Compare commits
22
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e4afe412a5 | ||
|
|
45f5b5060c | ||
|
|
a6af4cbbd9 | ||
|
|
e76a59f14a | ||
|
|
ea2673541c | ||
|
|
0193d342e0 | ||
|
|
0a1881592a | ||
|
|
fcfb5d0cbb | ||
|
|
a8fc80dd50 | ||
|
|
8805899f39 | ||
|
|
5dc6d47dd0 | ||
|
|
4450bd5c5d | ||
|
|
45faec8290 | ||
|
|
a19a70813c | ||
|
|
34582ffe50 | ||
|
|
0d4c1ed81e | ||
|
|
e1d739be1b | ||
|
|
2c72efd3ea | ||
|
|
270f160dd2 | ||
|
|
b026f494d8 | ||
|
|
8a690e2423 | ||
|
|
08678e4252 |
No files matched your search
@@ -39,11 +39,11 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v2
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v3
|
||||
uses: github/codeql-action/init@v1
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
@@ -54,7 +54,7 @@ jobs:
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v3
|
||||
uses: github/codeql-action/autobuild@v1
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
@@ -68,4 +68,4 @@ jobs:
|
||||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v3
|
||||
uses: github/codeql-action/analyze@v1
|
||||
@@ -19,9 +19,9 @@ jobs:
|
||||
packages: write
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@v4
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
java-version: '17'
|
||||
distribution: 'temurin'
|
||||
@@ -29,10 +29,10 @@ jobs:
|
||||
settings-path: ${{ github.workspace }} # location for the settings.xml file
|
||||
|
||||
- name: Build with Gradle
|
||||
uses: gradle/actions/setup-gradle@v3
|
||||
uses: gradle/gradle-build-action@67421db6bd0bf253fb4bd25b31ebb98943c375e1
|
||||
with:
|
||||
arguments: build
|
||||
- name: Upload a Build Artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v3.1.0
|
||||
with:
|
||||
path: /home/runner/work/Grim/Grim/build/libs/**.jar
|
||||
@@ -7,7 +7,7 @@ GrimAC is an open source Minecraft anticheat designed for 1.21 and supports 1.8-
|
||||
### Compiling through terminal/command prompt
|
||||
1. git clone https://github.com/GrimAnticheat/Grim.git (or click the green code button, download ZIP, then unzip it.)
|
||||
2. cd Grim
|
||||
3. ./gradlew build
|
||||
3. gradlew build
|
||||
4. The final jar is located in build/libs
|
||||
|
||||
### API Information
|
||||
|
||||
+9
-66
@@ -6,35 +6,17 @@ plugins {
|
||||
id("com.github.johnrengelman.shadow") version "8.1.1"
|
||||
id("io.freefair.lombok") version "8.6"
|
||||
id("net.minecrell.plugin-yml.bukkit") version "0.6.0"
|
||||
id("com.diffplug.spotless") version "6.25.0"
|
||||
}
|
||||
|
||||
spotless {
|
||||
java {
|
||||
endWithNewline()
|
||||
indentWithSpaces(4)
|
||||
removeUnusedImports()
|
||||
trimTrailingWhitespace()
|
||||
targetExclude("build/generated/**/*")
|
||||
}
|
||||
|
||||
kotlinGradle {
|
||||
endWithNewline()
|
||||
indentWithSpaces(4)
|
||||
trimTrailingWhitespace()
|
||||
}
|
||||
}
|
||||
|
||||
group = "ac.grim.grimac"
|
||||
version = "2.3.69"
|
||||
version = "2.3.68"
|
||||
description = "Libre simulation anticheat designed for 1.21 with 1.8-1.21 support, powered by PacketEvents 2.0."
|
||||
java.sourceCompatibility = JavaVersion.VERSION_17
|
||||
java.targetCompatibility = JavaVersion.VERSION_17
|
||||
|
||||
// Set to false for debug builds
|
||||
// You cannot live reload classes if the jar relocates dependencies
|
||||
// Checks Project properties -> environment variable -> defaults true
|
||||
val relocate: Boolean = project.findProperty("relocate")?.toString()?.toBoolean()
|
||||
?: System.getenv("RELOCATE_JAR")?.toBoolean()
|
||||
?: true
|
||||
var relocate = true;
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
@@ -56,10 +38,10 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation("com.github.retrooper:packetevents-spigot:2.6.1-SNAPSHOT")
|
||||
implementation("com.github.retrooper:packetevents-spigot:2.5.1-SNAPSHOT")
|
||||
implementation("co.aikar:acf-paper:0.5.1-SNAPSHOT")
|
||||
implementation("club.minnced:discord-webhooks:0.8.0") // Newer versions include kotlin-stdlib, which leads to incompatibility with plugins that use Kotlin
|
||||
implementation("it.unimi.dsi:fastutil:8.5.15")
|
||||
implementation("it.unimi.dsi:fastutil:8.5.13")
|
||||
implementation("github.scarsz:configuralize:1.4.0")
|
||||
|
||||
//implementation("com.github.grimanticheat:grimapi:1193c4fa41")
|
||||
@@ -67,9 +49,9 @@ dependencies {
|
||||
implementation("com.github.grimanticheat:grimapi:fc5634e444")
|
||||
|
||||
implementation("org.jetbrains:annotations:24.1.0")
|
||||
compileOnly("org.geysermc.floodgate:api:2.2.3-SNAPSHOT")
|
||||
compileOnly("org.geysermc.floodgate:api:2.0-SNAPSHOT")
|
||||
compileOnly("org.spigotmc:spigot-api:1.18.2-R0.1-SNAPSHOT")
|
||||
compileOnly("com.viaversion:viaversion-api:5.1.1-SNAPSHOT")
|
||||
compileOnly("com.viaversion:viaversion-api:4.9.4-SNAPSHOT")
|
||||
//
|
||||
compileOnly("io.netty:netty-all:4.1.85.Final")
|
||||
}
|
||||
@@ -78,7 +60,6 @@ bukkit {
|
||||
name = "GrimAC"
|
||||
author = "GrimAC"
|
||||
main = "ac.grim.grimac.GrimAC"
|
||||
website = "https://grim.ac/"
|
||||
apiVersion = "1.13"
|
||||
foliaSupported = true
|
||||
|
||||
@@ -144,7 +125,6 @@ bukkit {
|
||||
|
||||
tasks.build {
|
||||
dependsOn(tasks.shadowJar)
|
||||
dependsOn(tasks.spotlessApply)
|
||||
}
|
||||
|
||||
tasks.withType<JavaCompile> {
|
||||
@@ -155,43 +135,6 @@ publishing.publications.create<MavenPublication>("maven") {
|
||||
artifact(tasks["shadowJar"])
|
||||
}
|
||||
|
||||
java {
|
||||
sourceSets {
|
||||
create("java18") {
|
||||
java {
|
||||
srcDirs("src/main/java18")
|
||||
}
|
||||
compileClasspath += main.get().output
|
||||
runtimeClasspath += main.get().output
|
||||
}
|
||||
}
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
|
||||
toolchain {
|
||||
languageVersion.set(JavaLanguageVersion.of(21))
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType<JavaCompile> {
|
||||
if (name == "compileJava18Java") {
|
||||
options.compilerArgs.addAll(listOf("--add-modules", "jdk.incubator.vector", "-Xlint:unchecked"))
|
||||
sourceCompatibility = "18"
|
||||
targetCompatibility = "18"
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType<Jar> {
|
||||
manifest {
|
||||
attributes("Multi-Release" to "true")
|
||||
}
|
||||
duplicatesStrategy = DuplicatesStrategy.INCLUDE // Important for multi-release JARs
|
||||
from(sourceSets.main.get().output)
|
||||
from(sourceSets.getByName("java18").output) {
|
||||
into("META-INF/versions/18")
|
||||
}
|
||||
}
|
||||
|
||||
tasks.shadowJar {
|
||||
minimize()
|
||||
archiveFileName.set("${project.name}-${project.version}.jar")
|
||||
@@ -214,4 +157,4 @@ tasks.shadowJar {
|
||||
relocate("org.intellij", "ac.grim.grimac.shaded.intellij")
|
||||
relocate("org.jetbrains", "ac.grim.grimac.shaded.jetbrains")
|
||||
}
|
||||
}
|
||||
}
|
||||
Vendored
BIN
Binary file not shown.
+1
-1
@@ -1,6 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
@@ -1,149 +0,0 @@
|
||||
package ac.grim.grimac.utils.vector;
|
||||
|
||||
import jdk.incubator.vector.*;
|
||||
|
||||
public final class SIMDVector3D implements Vector3D {
|
||||
|
||||
private static final VectorSpecies<Double> SPECIES = DoubleVector.SPECIES_PREFERRED;
|
||||
private static final VectorMask<Double> LENGTH_3_ARRAY_MASK = SPECIES.indexInRange(0, 3);
|
||||
private static final VectorShuffle<Double> CROSS_PRODUCT_SHUFFLE1 = VectorShuffle.fromArray(SPECIES, new int[]{1, 2, 0, 3}, 0);
|
||||
private static final VectorShuffle<Double> CROSS_PRODUCT_SHUFFLE2 = VectorShuffle.fromArray(SPECIES, new int[]{2, 0, 1, 3}, 0);
|
||||
private static final DoubleVector FOURTH_COMPONENT_ZERO = DoubleVector.zero(SPECIES).withLane(3, 1.0);
|
||||
|
||||
private DoubleVector vector;
|
||||
|
||||
public SIMDVector3D(double x, double y, double z) {
|
||||
this.vector = DoubleVector.fromArray(SPECIES, new double[]{x, y, z, 0}, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getX() {
|
||||
return this.vector.lane(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getY() {
|
||||
return this.vector.lane(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getZ() {
|
||||
return this.vector.lane(2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3D setX(double x) {
|
||||
this.vector = this.vector.withLane(0, x);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3D setY(double y) {
|
||||
this.vector = this.vector.withLane(1, y);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3D setZ(double z) {
|
||||
this.vector = this.vector.withLane(2, z);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double length() {
|
||||
return Math.sqrt(lengthSquared());
|
||||
}
|
||||
|
||||
@Override
|
||||
public double lengthSquared() {
|
||||
return this.vector.mul(this.vector).reduceLanes(VectorOperators.ADD);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3D multiply(double m) {
|
||||
this.vector = this.vector.mul(m);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3D normalize() {
|
||||
// DoubleVector squared = this.vector.mul(this.vector);
|
||||
// double sum = squared.reduceLanes(VectorOperators.ADD);
|
||||
// double length = Math.sqrt(sum);
|
||||
// this.vector = this.vector.div(length);
|
||||
// return this;
|
||||
double length = length();
|
||||
this.vector = this.vector.div(length).blend(FOURTH_COMPONENT_ZERO, LENGTH_3_ARRAY_MASK.not());
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3D crossProduct(Vector3D other) {
|
||||
SIMDVector3D o = (SIMDVector3D) other;
|
||||
|
||||
DoubleVector tmp0 = this.vector.rearrange(CROSS_PRODUCT_SHUFFLE1);
|
||||
DoubleVector tmp1 = o.vector.rearrange(CROSS_PRODUCT_SHUFFLE2);
|
||||
|
||||
DoubleVector tmp2 = tmp0.mul(o.vector);
|
||||
DoubleVector tmp3 = tmp0.mul(tmp1);
|
||||
|
||||
DoubleVector tmp4 = tmp2.rearrange(CROSS_PRODUCT_SHUFFLE1);
|
||||
|
||||
this.vector = tmp3.sub(tmp4).blend(FOURTH_COMPONENT_ZERO, LENGTH_3_ARRAY_MASK.not());
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3D add(Vector3D o) {
|
||||
this.vector = this.vector.add(((SIMDVector3D) o).vector);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3D subtract(Vector3D o) {
|
||||
this.vector = this.vector.sub(((SIMDVector3D) o).vector);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3D multiply(Vector3D o) {
|
||||
this.vector = this.vector.mul(((SIMDVector3D) o).vector);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double distance(Vector3D o) {
|
||||
return Math.sqrt(distanceSquared(o));
|
||||
}
|
||||
|
||||
@Override
|
||||
public double distanceSquared(Vector3D o) {
|
||||
DoubleVector diff = this.vector.sub(((SIMDVector3D) o).vector);
|
||||
return diff.mul(diff).reduceLanes(VectorOperators.ADD);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double dot(Vector3D o) {
|
||||
return this.vector.mul(((SIMDVector3D) o).vector).reduceLanes(VectorOperators.ADD);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Vector3D clone() {
|
||||
// I think this makes a shallow clone if I do it like this?
|
||||
// try {
|
||||
// return (Vector3D) super.clone();
|
||||
// } catch (CloneNotSupportedException e) {
|
||||
// throw new Error(e);
|
||||
// }
|
||||
try {
|
||||
SIMDVector3D cloned = (SIMDVector3D) super.clone();
|
||||
// Create a new DoubleVector with the same values
|
||||
cloned.vector = DoubleVector.fromArray(SPECIES,
|
||||
new double[]{this.getX(), this.getY(), this.getZ(), 0}, 0);
|
||||
return cloned;
|
||||
} catch (CloneNotSupportedException e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package ac.grim.grimac.utils.vector;
|
||||
|
||||
import jdk.incubator.vector.VectorMask;
|
||||
import jdk.incubator.vector.VectorSpecies;
|
||||
import jdk.incubator.vector.DoubleVector;
|
||||
|
||||
public class VectorOperationsJava18 implements VectorOperations {
|
||||
|
||||
@Override
|
||||
public Vector3D newVector(double x, double y, double z) {
|
||||
return new SIMDVector3D(x, y, z);
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,17 @@
|
||||
package ac.grim.grimac;
|
||||
|
||||
import ac.grim.grimac.api.GrimAbstractAPI;
|
||||
import ac.grim.grimac.manager.*;
|
||||
import ac.grim.grimac.manager.config.BaseConfigManager;
|
||||
import ac.grim.grimac.utils.anticheat.PlayerDataManager;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.ServicePriority;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
@Getter
|
||||
public enum GrimAPI {
|
||||
INSTANCE;
|
||||
|
||||
private final BaseConfigManager configManager = new BaseConfigManager();
|
||||
private final AlertManagerImpl alertManager = new AlertManagerImpl();
|
||||
private final SpectateManager spectateManager = new SpectateManager();
|
||||
private final DiscordManager discordManager = new DiscordManager();
|
||||
@@ -18,10 +19,12 @@ public enum GrimAPI {
|
||||
private final TickManager tickManager = new TickManager();
|
||||
private final GrimExternalAPI externalAPI = new GrimExternalAPI(this);
|
||||
private InitManager initManager;
|
||||
private ConfigManagerImpl configManager;
|
||||
private JavaPlugin plugin;
|
||||
|
||||
public void load(final JavaPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
this.configManager = new ConfigManagerImpl();
|
||||
initManager = new InitManager();
|
||||
initManager.load();
|
||||
}
|
||||
@@ -29,6 +32,7 @@ public enum GrimAPI {
|
||||
public void start(final JavaPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
initManager.start();
|
||||
Bukkit.getServicesManager().register(GrimAbstractAPI.class, externalAPI, plugin, ServicePriority.Normal);
|
||||
}
|
||||
|
||||
public void stop(final JavaPlugin plugin) {
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
package ac.grim.grimac;
|
||||
|
||||
import ac.grim.grimac.api.AbstractCheck;
|
||||
import ac.grim.grimac.api.GrimAbstractAPI;
|
||||
import ac.grim.grimac.api.GrimUser;
|
||||
import ac.grim.grimac.api.alerts.AlertManager;
|
||||
import ac.grim.grimac.api.config.ConfigManager;
|
||||
import ac.grim.grimac.api.events.GrimReloadEvent;
|
||||
import ac.grim.grimac.manager.config.ConfigManagerFileImpl;
|
||||
import ac.grim.grimac.manager.init.Initable;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.anticheat.LogUtil;
|
||||
import ac.grim.grimac.utils.common.ConfigReloadObserver;
|
||||
import com.github.retrooper.packetevents.netty.channel.ChannelHelper;
|
||||
import io.github.retrooper.packetevents.util.SpigotReflectionUtil;
|
||||
@@ -18,7 +17,6 @@ import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.PluginDescriptionFile;
|
||||
import org.bukkit.plugin.ServicePriority;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Map;
|
||||
@@ -115,29 +113,25 @@ public class GrimExternalAPI implements GrimAbstractAPI, ConfigReloadObserver, I
|
||||
}
|
||||
|
||||
private ConfigManager configManager = null;
|
||||
private final ConfigManagerFileImpl configManagerFile = new ConfigManagerFileImpl();
|
||||
private boolean started = false;
|
||||
|
||||
// on load, load the config & register the service
|
||||
public void load() {
|
||||
reload(configManagerFile);
|
||||
Bukkit.getServicesManager().register(GrimAbstractAPI.class, this, GrimAPI.INSTANCE.getPlugin(), ServicePriority.Normal);
|
||||
}
|
||||
|
||||
// handles any config loading that's needed to be done after load
|
||||
@Override
|
||||
public void start() {
|
||||
started = true;
|
||||
try {
|
||||
GrimAPI.INSTANCE.getConfigManager().start();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (configManager == null) configManager = GrimAPI.INSTANCE.getConfigManager();
|
||||
variableReplacements.put("%player%", GrimUser::getName);
|
||||
variableReplacements.put("%uuid%", user -> user.getUniqueId().toString());
|
||||
variableReplacements.put("%ping%", user -> user.getTransactionPing() + "");
|
||||
variableReplacements.put("%brand%", GrimUser::getBrand);
|
||||
variableReplacements.put("%h_sensitivity%", user -> ((int) Math.round(user.getHorizontalSensitivity() * 200)) + "");
|
||||
variableReplacements.put("%v_sensitivity%", user -> ((int) Math.round(user.getVerticalSensitivity() * 200)) + "");
|
||||
variableReplacements.put("%fast_math%", user -> !user.isVanillaMath() + "");
|
||||
variableReplacements.put("%tps%", user -> String.format("%.2f", SpigotReflectionUtil.getTPS()));
|
||||
variableReplacements.put("%version%", GrimUser::getVersionName);
|
||||
variableReplacements.put("%prefix%", user -> ChatColor.translateAlternateColorCodes('&', GrimAPI.INSTANCE.getConfigManager().getConfig().getStringElse("prefix", "&bGrim &8»")));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload(ConfigManager config) {
|
||||
if (config.isLoadedAsync() && started) {
|
||||
if (config.isLoadedAsync()) {
|
||||
FoliaScheduler.getAsyncScheduler().runNow(GrimAPI.INSTANCE.getPlugin(),
|
||||
o -> successfulReload(config));
|
||||
} else {
|
||||
@@ -147,7 +141,7 @@ public class GrimExternalAPI implements GrimAbstractAPI, ConfigReloadObserver, I
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> reloadAsync(ConfigManager config) {
|
||||
if (config.isLoadedAsync() && started) {
|
||||
if (config.isLoadedAsync()) {
|
||||
CompletableFuture<Boolean> future = new CompletableFuture<>();
|
||||
FoliaScheduler.getAsyncScheduler().runNow(GrimAPI.INSTANCE.getPlugin(),
|
||||
o -> future.complete(successfulReload(config)));
|
||||
@@ -159,57 +153,36 @@ public class GrimExternalAPI implements GrimAbstractAPI, ConfigReloadObserver, I
|
||||
private boolean successfulReload(ConfigManager config) {
|
||||
try {
|
||||
config.reload();
|
||||
GrimAPI.INSTANCE.getConfigManager().load(config);
|
||||
if (started) GrimAPI.INSTANCE.getConfigManager().start();
|
||||
onReload(config);
|
||||
if (started) FoliaScheduler.getAsyncScheduler().runNow(GrimAPI.INSTANCE.getPlugin(),
|
||||
FoliaScheduler.getAsyncScheduler().runNow(GrimAPI.INSTANCE.getPlugin(),
|
||||
o -> Bukkit.getPluginManager().callEvent(new GrimReloadEvent(true)));
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (started) FoliaScheduler.getAsyncScheduler().runNow(GrimAPI.INSTANCE.getPlugin(),
|
||||
FoliaScheduler.getAsyncScheduler().runNow(GrimAPI.INSTANCE.getPlugin(),
|
||||
o -> Bukkit.getPluginManager().callEvent(new GrimReloadEvent(false)));
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReload(ConfigManager newConfig) {
|
||||
if (newConfig == null) {
|
||||
LogUtil.warn("ConfigManager not set. Using default config file manager.");
|
||||
configManager = configManagerFile;
|
||||
} else {
|
||||
configManager = newConfig;
|
||||
}
|
||||
// Update variables
|
||||
updateVariables();
|
||||
// Restart
|
||||
GrimAPI.INSTANCE.getDiscordManager().start();
|
||||
GrimAPI.INSTANCE.getSpectateManager().start();
|
||||
// Don't reload players if the plugin hasn't started yet
|
||||
if (!started) return;
|
||||
// Reload checks for all players
|
||||
configManager = newConfig != null ? newConfig : configManager;
|
||||
//Reload checks for all players
|
||||
for (GrimPlayer grimPlayer : GrimAPI.INSTANCE.getPlayerDataManager().getEntries()) {
|
||||
ChannelHelper.runInEventLoop(grimPlayer.user.getChannel(), () -> {
|
||||
grimPlayer.updatePermissions();
|
||||
grimPlayer.reload(configManager);
|
||||
grimPlayer.updatePermissions();
|
||||
grimPlayer.punishmentManager.reload(configManager);
|
||||
for (AbstractCheck value : grimPlayer.checkManager.allChecks.values()) {
|
||||
value.reload(configManager);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void updateVariables() {
|
||||
variableReplacements.putIfAbsent("%player%", GrimUser::getName);
|
||||
variableReplacements.putIfAbsent("%uuid%", user -> user.getUniqueId().toString());
|
||||
variableReplacements.putIfAbsent("%ping%", user -> user.getTransactionPing() + "");
|
||||
variableReplacements.putIfAbsent("%brand%", GrimUser::getBrand);
|
||||
variableReplacements.putIfAbsent("%h_sensitivity%", user -> ((int) Math.round(user.getHorizontalSensitivity() * 200)) + "");
|
||||
variableReplacements.putIfAbsent("%v_sensitivity%", user -> ((int) Math.round(user.getVerticalSensitivity() * 200)) + "");
|
||||
variableReplacements.putIfAbsent("%fast_math%", user -> !user.isVanillaMath() + "");
|
||||
variableReplacements.putIfAbsent("%tps%", user -> String.format("%.2f", SpigotReflectionUtil.getTPS()));
|
||||
variableReplacements.putIfAbsent("%version%", GrimUser::getVersionName);
|
||||
// static variables
|
||||
staticReplacements.putIfAbsent("%prefix%", ChatColor.translateAlternateColorCodes('&', GrimAPI.INSTANCE.getConfigManager().getPrefix()));
|
||||
staticReplacements.putIfAbsent("%grim_version%", getGrimVersion());
|
||||
//Restart
|
||||
GrimAPI.INSTANCE.getDiscordManager().start();
|
||||
GrimAPI.INSTANCE.getSpectateManager().start();
|
||||
GrimAPI.INSTANCE.getExternalAPI().start();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -25,7 +25,6 @@ public class Check implements AbstractCheck, ConfigReloadObserver {
|
||||
private String checkName;
|
||||
private String configName;
|
||||
private String alternativeName;
|
||||
private String displayName;
|
||||
private String description;
|
||||
|
||||
private boolean experimental;
|
||||
@@ -54,10 +53,9 @@ public class Check implements AbstractCheck, ConfigReloadObserver {
|
||||
this.alternativeName = checkData.alternativeName();
|
||||
this.experimental = checkData.experimental();
|
||||
this.description = checkData.description();
|
||||
this.displayName = this.checkName;
|
||||
}
|
||||
//
|
||||
reload();
|
||||
reload(GrimAPI.INSTANCE.getConfigManager().getConfig());
|
||||
}
|
||||
|
||||
public boolean shouldModifyPackets() {
|
||||
@@ -84,7 +82,7 @@ public class Check implements AbstractCheck, ConfigReloadObserver {
|
||||
}
|
||||
|
||||
public final boolean flag() {
|
||||
if (player.disableGrim || (experimental && !player.isExperimentalChecks()) || exempted)
|
||||
if (player.disableGrim || (experimental && !GrimAPI.INSTANCE.getConfigManager().isExperimentalChecks()) || exempted)
|
||||
return false; // Avoid calling event if disabled
|
||||
|
||||
FlagEvent event = new FlagEvent(player, this);
|
||||
@@ -114,8 +112,6 @@ public class Check implements AbstractCheck, ConfigReloadObserver {
|
||||
public void reload(ConfigManager configuration) {
|
||||
decay = configuration.getDoubleElse(configName + ".decay", decay);
|
||||
setbackVL = configuration.getDoubleElse(configName + ".setbackvl", setbackVL);
|
||||
displayName = configuration.getStringElse(configName + ".displayname", checkName);
|
||||
|
||||
if (setbackVL == -1) setbackVL = Double.MAX_VALUE;
|
||||
updateExempted();
|
||||
onReload(configuration);
|
||||
@@ -156,3 +152,4 @@ public class Check implements AbstractCheck, ConfigReloadObserver {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -11,8 +11,7 @@ import ac.grim.grimac.utils.anticheat.update.RotationUpdate;
|
||||
// It works on clients who % 360 their rotation.
|
||||
@CheckData(name = "AimModulo360", decay = 0.005)
|
||||
public class AimModulo360 extends Check implements RotationCheck {
|
||||
|
||||
private float lastDeltaYaw;
|
||||
float lastDeltaYaw;
|
||||
|
||||
public AimModulo360(GrimPlayer playerData) {
|
||||
super(playerData);
|
||||
@@ -20,17 +19,12 @@ public class AimModulo360 extends Check implements RotationCheck {
|
||||
|
||||
@Override
|
||||
public void process(final RotationUpdate rotationUpdate) {
|
||||
if (player.packetStateData.lastPacketWasTeleport) {
|
||||
lastDeltaYaw = rotationUpdate.getDeltaXRot();
|
||||
return;
|
||||
}
|
||||
|
||||
lastDeltaYaw = rotationUpdate.getDeltaXRot();
|
||||
if (player.packetStateData.lastPacketWasTeleport) return;
|
||||
if (player.xRot < 360 && player.xRot > -360 && Math.abs(rotationUpdate.getDeltaXRot()) > 320 && Math.abs(lastDeltaYaw) < 30) {
|
||||
flagAndAlert();
|
||||
} else {
|
||||
reward();
|
||||
}
|
||||
|
||||
lastDeltaYaw = rotationUpdate.getDeltaXRot();
|
||||
}
|
||||
}
|
||||
@@ -81,4 +81,4 @@ public class AimProcessor extends Check implements RotationCheck {
|
||||
double var9 = Math.cbrt(var11);
|
||||
return (var9 - 0.2f) / 0.6f;
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
-4
@@ -1,4 +1,4 @@
|
||||
package ac.grim.grimac.checks.impl.packetorder;
|
||||
package ac.grim.grimac.checks.impl.badpackets;
|
||||
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
@@ -10,16 +10,17 @@ import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientInteractEntity;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerFlying;
|
||||
|
||||
@CheckData(name = "PacketOrderB")
|
||||
public class PacketOrderB extends Check implements PacketCheck {
|
||||
@CheckData(name = "BadPacketsH")
|
||||
public class BadPacketsH extends Check implements PacketCheck {
|
||||
|
||||
// 1.9 packet order: INTERACT -> ANIMATION
|
||||
// 1.8 packet order: ANIMATION -> INTERACT
|
||||
// I personally think 1.8 made much more sense. You swing and THEN you hit!
|
||||
private boolean sentAnimation = player.getClientVersion().isNewerThan(ClientVersion.V_1_8);
|
||||
|
||||
public PacketOrderB(final GrimPlayer player) {
|
||||
public BadPacketsH(final GrimPlayer player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
+10
-40
@@ -1,4 +1,4 @@
|
||||
package ac.grim.grimac.checks.impl.packetorder;
|
||||
package ac.grim.grimac.checks.impl.badpackets;
|
||||
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
@@ -9,33 +9,25 @@ import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.protocol.player.InteractionHand;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientInteractEntity;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerFlying;
|
||||
|
||||
@CheckData(name = "PacketOrderC", experimental = true)
|
||||
public class PacketOrderC extends Check implements PacketCheck {
|
||||
public PacketOrderC(final GrimPlayer player) {
|
||||
@CheckData(name = "BadPacketsM", experimental = true)
|
||||
public class BadPacketsM extends Check implements PacketCheck {
|
||||
public BadPacketsM(final GrimPlayer player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
// 1.7 players do not send INTERACT_AT, so we cannot check them
|
||||
private final boolean exempt = player.getClientVersion().isOlderThanOrEquals(ClientVersion.V_1_7_10);
|
||||
private boolean sentInteractAt = false;
|
||||
private int requiredEntity;
|
||||
private InteractionHand requiredHand;
|
||||
private boolean requiredSneaking;
|
||||
|
||||
@Override
|
||||
public void onPacketReceive(PacketReceiveEvent event) {
|
||||
if (exempt) {
|
||||
return;
|
||||
}
|
||||
if (event.getPacketType() == PacketType.Play.Client.INTERACT_ENTITY && !exempt) {
|
||||
|
||||
if (event.getPacketType() == PacketType.Play.Client.INTERACT_ENTITY) {
|
||||
final WrapperPlayClientInteractEntity packet = new WrapperPlayClientInteractEntity(event);
|
||||
final WrapperPlayClientInteractEntity wrapper = new WrapperPlayClientInteractEntity(event);
|
||||
|
||||
final PacketEntity entity = player.compensatedEntities.entityMap.get(packet.getEntityId());
|
||||
final PacketEntity entity = player.compensatedEntities.entityMap.get(wrapper.getEntityId());
|
||||
|
||||
// For armor stands, vanilla clients send:
|
||||
// - when renaming the armor stand or in spectator mode: INTERACT_AT + INTERACT
|
||||
@@ -43,49 +35,27 @@ public class PacketOrderC extends Check implements PacketCheck {
|
||||
// Just exempt armor stands to be safe
|
||||
if (entity != null && entity.getType() == EntityTypes.ARMOR_STAND) return;
|
||||
|
||||
final boolean sneaking = packet.isSneaking().orElse(false);
|
||||
|
||||
switch (packet.getAction()) {
|
||||
switch (wrapper.getAction()) {
|
||||
// INTERACT_AT then INTERACT
|
||||
case INTERACT:
|
||||
if (!sentInteractAt) {
|
||||
if (flagAndAlert("Skipped Interact-At") && shouldModifyPackets()) {
|
||||
event.setCancelled(true);
|
||||
player.onPacketCancel();
|
||||
}
|
||||
} else if (packet.getEntityId() != requiredEntity || packet.getHand() != requiredHand || sneaking != requiredSneaking) {
|
||||
String verbose = "requiredEntity=" + requiredEntity + ", entity=" + packet.getEntityId()
|
||||
+ ", requiredHand=" + requiredHand + ", hand=" + packet.getHand()
|
||||
+ ", requiredSneaking=" + requiredSneaking + ", sneaking=" + sneaking;
|
||||
if (flagAndAlert(verbose) && shouldModifyPackets()) {
|
||||
if (flagAndAlert("Missed Interact-At") && shouldModifyPackets()) {
|
||||
event.setCancelled(true);
|
||||
player.onPacketCancel();
|
||||
}
|
||||
}
|
||||
|
||||
sentInteractAt = false;
|
||||
break;
|
||||
case INTERACT_AT:
|
||||
if (sentInteractAt) {
|
||||
if (flagAndAlert("Skipped Interact") && shouldModifyPackets()) {
|
||||
if (flagAndAlert("Missed Interact") && shouldModifyPackets()) {
|
||||
event.setCancelled(true);
|
||||
player.onPacketCancel();
|
||||
}
|
||||
}
|
||||
|
||||
requiredHand = packet.getHand();
|
||||
requiredEntity = packet.getEntityId();
|
||||
requiredSneaking = sneaking;
|
||||
sentInteractAt = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (WrapperPlayClientPlayerFlying.isFlying(event.getPacketType())) {
|
||||
if (sentInteractAt) {
|
||||
sentInteractAt = false;
|
||||
flagAndAlert("Skipped Interact (Tick)");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import ac.grim.grimac.checks.type.PacketCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.protocol.item.ItemStack;
|
||||
import com.github.retrooper.packetevents.protocol.item.type.ItemType;
|
||||
import com.github.retrooper.packetevents.protocol.item.type.ItemTypes;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
|
||||
@@ -4,6 +4,7 @@ import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.PacketCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.nmsutil.BlockBreakSpeed;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.protocol.item.type.ItemTypes;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
package ac.grim.grimac.checks.impl.combat;
|
||||
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.PostPredictionCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.anticheat.update.PredictionComplete;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientInteractEntity;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerFlying;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@CheckData(name = "MultiInteractA", experimental = true)
|
||||
public class MultiInteractA extends Check implements PostPredictionCheck {
|
||||
public MultiInteractA(final GrimPlayer player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
private final ArrayList<String> flags = new ArrayList<>();
|
||||
private int lastEntity;
|
||||
private boolean lastSneaking;
|
||||
private boolean hasInteracted = false;
|
||||
|
||||
@Override
|
||||
public void onPacketReceive(PacketReceiveEvent event) {
|
||||
if (event.getPacketType() == PacketType.Play.Client.INTERACT_ENTITY) {
|
||||
WrapperPlayClientInteractEntity packet = new WrapperPlayClientInteractEntity(event);
|
||||
int entity = packet.getEntityId();
|
||||
boolean sneaking = packet.isSneaking().orElse(false);
|
||||
|
||||
if (hasInteracted && entity != lastEntity) {
|
||||
String verbose = "lastEntity=" + lastEntity + ", entity=" + entity
|
||||
+ ", lastSneaking=" + lastSneaking + ", sneaking=" + sneaking;
|
||||
if (player.getClientVersion().isOlderThanOrEquals(ClientVersion.V_1_8)) {
|
||||
if (flagAndAlert(verbose) && shouldModifyPackets()) {
|
||||
event.setCancelled(true);
|
||||
player.onPacketCancel();
|
||||
}
|
||||
} else {
|
||||
flags.add(verbose);
|
||||
}
|
||||
}
|
||||
|
||||
lastEntity = entity;
|
||||
lastSneaking = sneaking;
|
||||
hasInteracted = true;
|
||||
}
|
||||
|
||||
if (WrapperPlayClientPlayerFlying.isFlying(event.getPacketType()) && player.getClientVersion().isOlderThanOrEquals(ClientVersion.V_1_8) && !player.packetStateData.lastPacketWasTeleport) {
|
||||
hasInteracted = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPredictionComplete(PredictionComplete predictionComplete) {
|
||||
// we don't need to check pre-1.9 players here (no tick skipping)
|
||||
if (player.getClientVersion().isOlderThanOrEquals(ClientVersion.V_1_8)) return;
|
||||
|
||||
if (player.isTickingReliablyFor(3)) {
|
||||
for (String verbose : flags) {
|
||||
flagAndAlert(verbose);
|
||||
}
|
||||
}
|
||||
|
||||
flags.clear();
|
||||
hasInteracted = false;
|
||||
}
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
package ac.grim.grimac.checks.impl.combat;
|
||||
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.PostPredictionCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.anticheat.MessageUtil;
|
||||
import ac.grim.grimac.utils.anticheat.update.PredictionComplete;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.util.Vector3f;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientInteractEntity;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerFlying;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@CheckData(name = "MultiInteractB", experimental = true)
|
||||
public class MultiInteractB extends Check implements PostPredictionCheck {
|
||||
public MultiInteractB(final GrimPlayer player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
private final ArrayList<String> flags = new ArrayList<>();
|
||||
private Vector3f lastPos;
|
||||
private boolean hasInteracted = false;
|
||||
|
||||
@Override
|
||||
public void onPacketReceive(PacketReceiveEvent event) {
|
||||
if (event.getPacketType() == PacketType.Play.Client.INTERACT_ENTITY) {
|
||||
Vector3f pos = new WrapperPlayClientInteractEntity(event).getTarget().orElse(null);
|
||||
|
||||
if (pos == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (hasInteracted && !pos.equals(lastPos)) {
|
||||
String verbose = "pos=" + MessageUtil.toUnlabledString(pos) + ", lastPos=" + MessageUtil.toUnlabledString(lastPos);
|
||||
if (player.getClientVersion().isOlderThanOrEquals(ClientVersion.V_1_8)) {
|
||||
if (flagAndAlert(verbose) && shouldModifyPackets()) {
|
||||
event.setCancelled(true);
|
||||
player.onPacketCancel();
|
||||
}
|
||||
} else {
|
||||
flags.add(verbose);
|
||||
}
|
||||
}
|
||||
|
||||
lastPos = pos;
|
||||
hasInteracted = true;
|
||||
}
|
||||
|
||||
if (WrapperPlayClientPlayerFlying.isFlying(event.getPacketType()) && player.getClientVersion().isOlderThanOrEquals(ClientVersion.V_1_8) && !player.packetStateData.lastPacketWasTeleport) {
|
||||
hasInteracted = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPredictionComplete(PredictionComplete predictionComplete) {
|
||||
// we don't need to check pre-1.9 players here (no tick skipping)
|
||||
if (player.getClientVersion().isOlderThanOrEquals(ClientVersion.V_1_8)) return;
|
||||
|
||||
if (player.isTickingReliablyFor(3)) {
|
||||
for (String verbose : flags) {
|
||||
flagAndAlert(verbose);
|
||||
}
|
||||
}
|
||||
|
||||
flags.clear();
|
||||
hasInteracted = false;
|
||||
}
|
||||
}
|
||||
@@ -21,13 +21,9 @@ import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.PacketCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.collisions.datatypes.SimpleCollisionBox;
|
||||
import ac.grim.grimac.utils.data.HitData;
|
||||
import ac.grim.grimac.utils.data.Pair;
|
||||
import ac.grim.grimac.utils.data.packetentity.PacketEntity;
|
||||
import ac.grim.grimac.utils.nmsutil.BlockRayTrace;
|
||||
import ac.grim.grimac.utils.data.packetentity.dragon.PacketEntityEnderDragonPart;
|
||||
import ac.grim.grimac.utils.nmsutil.ReachUtils;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.protocol.attribute.Attributes;
|
||||
import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
|
||||
@@ -35,40 +31,24 @@ import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.protocol.player.GameMode;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.WrappedBlockState;
|
||||
import com.github.retrooper.packetevents.util.Vector3d;
|
||||
import com.github.retrooper.packetevents.util.Vector3i;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientInteractEntity;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerFlying;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static ac.grim.grimac.utils.vector.VectorFactory.newVector3D;
|
||||
import java.util.*;
|
||||
|
||||
// You may not copy the check unless you are licensed under GPL
|
||||
@CheckData(name = "Reach", configName = "Reach", setback = 10)
|
||||
public class Reach extends Check implements PacketCheck {
|
||||
// Only one flag per reach attack, per entity, per tick.
|
||||
// We store position because lastX isn't reliable on teleports.
|
||||
private final Int2ObjectMap<Vector3d> playerAttackQueue = new Int2ObjectOpenHashMap<>();
|
||||
// Used to prevent falses in the wall hit check
|
||||
private final Set<Vector3i> blocksChangedThisTick = new HashSet<>();
|
||||
|
||||
private final Map<Integer, Vector3d> playerAttackQueue = new HashMap<>();
|
||||
private static final List<EntityType> blacklisted = Arrays.asList(
|
||||
EntityTypes.BOAT,
|
||||
EntityTypes.CHEST_BOAT,
|
||||
EntityTypes.SHULKER);
|
||||
|
||||
private boolean ignoreNonPlayerTargets;
|
||||
private boolean cancelImpossibleHits;
|
||||
private double threshold;
|
||||
private double cancelBuffer; // For the next 4 hits after using reach, we aggressively cancel reach
|
||||
@@ -101,11 +81,7 @@ public class Reach extends Check implements PacketCheck {
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (ignoreNonPlayerTargets && !entity.getType().equals(EntityTypes.PLAYER)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Dead entities cause false flags (https://github.com/GrimAnticheat/Grim/issues/546)
|
||||
if (entity.isDead) return;
|
||||
|
||||
@@ -130,11 +106,10 @@ public class Reach extends Check implements PacketCheck {
|
||||
}
|
||||
|
||||
// If the player set their look, or we know they have a new tick
|
||||
final boolean isFlying = WrapperPlayClientPlayerFlying.isFlying(event.getPacketType());
|
||||
if (isFlying ||
|
||||
if (WrapperPlayClientPlayerFlying.isFlying(event.getPacketType()) ||
|
||||
event.getPacketType() == PacketType.Play.Client.PONG ||
|
||||
event.getPacketType() == PacketType.Play.Client.WINDOW_CONFIRMATION) {
|
||||
tickBetterReachCheckWithAngle(isFlying);
|
||||
tickBetterReachCheckWithAngle();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,9 +141,9 @@ public class Reach extends Check implements PacketCheck {
|
||||
}
|
||||
}
|
||||
|
||||
private void tickBetterReachCheckWithAngle(boolean isFlying) {
|
||||
for (Int2ObjectMap.Entry<Vector3d> attack : playerAttackQueue.int2ObjectEntrySet()) {
|
||||
PacketEntity reachEntity = player.compensatedEntities.entityMap.get(attack.getIntKey());
|
||||
private void tickBetterReachCheckWithAngle() {
|
||||
for (Map.Entry<Integer, Vector3d> attack : playerAttackQueue.entrySet()) {
|
||||
PacketEntity reachEntity = player.compensatedEntities.entityMap.get(attack.getKey().intValue());
|
||||
if (reachEntity != null) {
|
||||
String result = checkReach(reachEntity, attack.getValue(), false);
|
||||
if (result != null) {
|
||||
@@ -181,9 +156,6 @@ public class Reach extends Check implements PacketCheck {
|
||||
}
|
||||
}
|
||||
playerAttackQueue.clear();
|
||||
// We can't use transactions for this because of this problem:
|
||||
// transaction -> block changed applied -> 2nd transaction -> list cleared -> attack packet -> flying -> reach block hit checked, falses
|
||||
if (isFlying) blocksChangedThisTick.clear();
|
||||
}
|
||||
|
||||
private String checkReach(PacketEntity reachEntity, Vector3d from, boolean isPrediction) {
|
||||
@@ -211,7 +183,7 @@ public class Reach extends Check implements PacketCheck {
|
||||
double minDistance = Double.MAX_VALUE;
|
||||
|
||||
// https://bugs.mojang.com/browse/MC-67665
|
||||
List<Vector3D> possibleLookDirs = new ArrayList<>(Collections.singletonList(ReachUtils.getLook(player, player.xRot, player.yRot)));
|
||||
List<Vector> possibleLookDirs = new ArrayList<>(Collections.singletonList(ReachUtils.getLook(player, player.xRot, player.yRot)));
|
||||
|
||||
// If we are a tick behind, we don't know their next look so don't bother doing this
|
||||
if (!isPrediction) {
|
||||
@@ -231,12 +203,12 @@ public class Reach extends Check implements PacketCheck {
|
||||
// +3 would be 3 + 3 = 6, which is the pre-1.20.5 behaviour, preventing "Missed Hitbox"
|
||||
final double distance = player.compensatedEntities.getSelf().getAttributeValue(Attributes.PLAYER_ENTITY_INTERACTION_RANGE) + 3;
|
||||
final double[] possibleEyeHeights = player.getPossibleEyeHeights();
|
||||
for (Vector3D lookVec : possibleLookDirs) {
|
||||
for (Vector lookVec : possibleLookDirs) {
|
||||
for (double eye : possibleEyeHeights) {
|
||||
ac.grim.grimac.utils.vector.Vector3D eyePos = newVector3D(from.getX(), from.getY() + eye, from.getZ());
|
||||
ac.grim.grimac.utils.vector.Vector3D endReachPos = eyePos.clone().add(newVector3D(lookVec.getX() * distance, lookVec.getY() * distance, lookVec.getZ() * distance));
|
||||
Vector eyePos = new Vector(from.getX(), from.getY() + eye, from.getZ());
|
||||
Vector endReachPos = eyePos.clone().add(new Vector(lookVec.getX() * distance, lookVec.getY() * distance, lookVec.getZ() * distance));
|
||||
|
||||
Vector3D intercept = ReachUtils.calculateIntercept(targetBox, eyePos, endReachPos).getFirst();
|
||||
Vector intercept = ReachUtils.calculateIntercept(targetBox, eyePos, endReachPos).getFirst();
|
||||
|
||||
if (ReachUtils.isVecInside(targetBox, eyePos)) {
|
||||
minDistance = 0;
|
||||
@@ -249,25 +221,9 @@ public class Reach extends Check implements PacketCheck {
|
||||
}
|
||||
}
|
||||
|
||||
HitData foundHitData = null;
|
||||
// If the entity is within range of the player (we'll flag anyway if not, so no point checking blocks in this case)
|
||||
// Ignore when could be hitting through a moving shulker, piston blocks. They are just too glitchy/uncertain to check.
|
||||
if (minDistance <= 3 && !player.compensatedWorld.isNearHardEntity(player.boundingBox.copy().expand(4))) {
|
||||
final @Nullable Pair<Double, HitData> targetBlock = getTargetBlock(player, possibleLookDirs, from, minDistance);
|
||||
// And if the target block is closer to the player than the entity box, they should hit the block instead
|
||||
// So, this hit is invalid.
|
||||
if (targetBlock != null && targetBlock.getFirst() < (minDistance * minDistance)) { // targetBlock is squared
|
||||
minDistance = Double.MIN_VALUE;
|
||||
foundHitData = targetBlock.getSecond();
|
||||
}
|
||||
}
|
||||
|
||||
// if the entity is not exempt and the entity is alive
|
||||
if ((!blacklisted.contains(reachEntity.getType()) && reachEntity.isLivingEntity()) || reachEntity.getType() == EntityTypes.END_CRYSTAL) {
|
||||
if (minDistance == Double.MIN_VALUE && foundHitData != null) {
|
||||
cancelBuffer = 1;
|
||||
return "Hit block block=" + foundHitData.getState().getType().getName();
|
||||
} else if (minDistance == Double.MAX_VALUE) {
|
||||
if (minDistance == Double.MAX_VALUE) {
|
||||
cancelBuffer = 1;
|
||||
return "Missed hitbox";
|
||||
} else if (minDistance > player.compensatedEntities.getSelf().getAttributeValue(Attributes.PLAYER_ENTITY_INTERACTION_RANGE)) {
|
||||
@@ -281,48 +237,8 @@ public class Reach extends Check implements PacketCheck {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void handleBlockChange(Vector3i vector3i, WrappedBlockState state) {
|
||||
if (blocksChangedThisTick.size() >= 40) return; // Don't let players freeze movement packets to grow this
|
||||
// Only do this for nearby blocks
|
||||
if (newVector3D(vector3i.x, vector3i.y, vector3i.z).distanceSquared(newVector3D(player.x, player.y, player.z)) > 6) return;
|
||||
// Only do this if the state really had any world impact
|
||||
if (state.equals(player.compensatedWorld.getWrappedBlockStateAt(vector3i))) return;
|
||||
blocksChangedThisTick.add(vector3i);
|
||||
}
|
||||
|
||||
// Returns a pair so we can check the block type in the flag
|
||||
@Nullable
|
||||
private Pair<Double, HitData> getTargetBlock(GrimPlayer player, List<Vector3D> possibleLookDirs, Vector3d from, double minDistance) {
|
||||
// Check every possible look direction and every possible eye height
|
||||
// IF *NONE* of them allow the player to hit the entity, this is an invalid hit
|
||||
HitData bestHitData = null;
|
||||
double min = Double.MAX_VALUE;
|
||||
for (Vector3D lookVec : possibleLookDirs) {
|
||||
for (double eye : player.getPossibleEyeHeights()) {
|
||||
Vector3D eyes = newVector3D(from.getX(), from.getY() + eye, from.getZ());
|
||||
final double reach = player.compensatedEntities.getSelf().getAttributeValue(Attributes.PLAYER_BLOCK_INTERACTION_RANGE);
|
||||
final HitData hitResult = BlockRayTrace.getNearestReachHitResult(player, eyes, lookVec, minDistance, reach);
|
||||
if (hitResult == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final double distance = eyes.distanceSquared(hitResult.getBlockHitLocation());
|
||||
// Block changes are uncertain, can't check this tick
|
||||
if (distance < (minDistance * minDistance) && blocksChangedThisTick.contains(hitResult.getPosition())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
bestHitData = hitResult;
|
||||
min = Math.min(min, distance);
|
||||
}
|
||||
}
|
||||
|
||||
return bestHitData == null ? null : Pair.of(min, bestHitData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReload(ConfigManager config) {
|
||||
this.ignoreNonPlayerTargets = config.getBooleanElse("Reach.ignore-non-player-targets", false);
|
||||
this.cancelImpossibleHits = config.getBooleanElse("Reach.block-impossible-hits", true);
|
||||
this.threshold = config.getDoubleElse("Reach.threshold", 0.0005);
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ public class CrashB extends Check implements PacketCheck {
|
||||
public void onPacketReceive(PacketReceiveEvent event) {
|
||||
if (event.getPacketType() == PacketType.Play.Client.CREATIVE_INVENTORY_ACTION) {
|
||||
if (player.gamemode != GameMode.CREATIVE) {
|
||||
player.getSetbackTeleportUtil().executeViolationSetback();
|
||||
event.setCancelled(true);
|
||||
player.onPacketCancel();
|
||||
flagAndAlert(); // Could be transaction split, no need to setback though
|
||||
|
||||
@@ -43,10 +43,7 @@ public class NoFallA extends Check implements PacketCheck {
|
||||
if (!isNearGround(wrapper.isOnGround())) { // If player isn't near ground
|
||||
// 1.8 boats have a mind on their own... only flag if they're not near a boat or are on 1.9+
|
||||
if (!GhostBlockDetector.isGhostBlock(player) && flagWithSetback()) alert("");
|
||||
if (shouldModifyPackets()) {
|
||||
wrapper.setOnGround(false);
|
||||
event.markForReEncode(true);
|
||||
}
|
||||
if (shouldModifyPackets()) wrapper.setOnGround(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -62,16 +59,10 @@ public class NoFallA extends Check implements PacketCheck {
|
||||
// Also flip teleports because I don't trust vanilla's handling of teleports and ground
|
||||
if (flipPlayerGroundStatus) {
|
||||
flipPlayerGroundStatus = false;
|
||||
if (shouldModifyPackets()) {
|
||||
wrapper.setOnGround(!wrapper.isOnGround());
|
||||
event.markForReEncode(true);
|
||||
}
|
||||
if (shouldModifyPackets()) wrapper.setOnGround(!wrapper.isOnGround());
|
||||
}
|
||||
if (player.packetStateData.lastPacketWasTeleport) {
|
||||
if (shouldModifyPackets()) {
|
||||
wrapper.setOnGround(false);
|
||||
event.markForReEncode(true);
|
||||
}
|
||||
if (shouldModifyPackets()) wrapper.setOnGround(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
package ac.grim.grimac.checks.impl.inventory;
|
||||
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.InventoryCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientInteractEntity;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientInteractEntity.InteractAction;
|
||||
|
||||
@CheckData(name = "InventoryA", setback = 3, description = "Attacked an entity while inventory is open")
|
||||
public class InventoryA extends InventoryCheck {
|
||||
public InventoryA(GrimPlayer player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPacketReceive(PacketReceiveEvent event) {
|
||||
super.onPacketReceive(event);
|
||||
|
||||
if (event.getPacketType() == PacketType.Play.Client.INTERACT_ENTITY) {
|
||||
WrapperPlayClientInteractEntity wrapper = new WrapperPlayClientInteractEntity(event);
|
||||
|
||||
if (wrapper.getAction() != InteractAction.ATTACK) return;
|
||||
|
||||
// Is not possible to attack while the inventory is open.
|
||||
if (player.hasInventoryOpen) {
|
||||
if (flagAndAlert()) {
|
||||
// Cancel the packet
|
||||
if (shouldModifyPackets()) {
|
||||
event.setCancelled(true);
|
||||
player.onPacketCancel();
|
||||
}
|
||||
closeInventory();
|
||||
}
|
||||
} else {
|
||||
reward();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package ac.grim.grimac.checks.impl.inventory;
|
||||
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.InventoryCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.protocol.player.DiggingAction;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerDigging;
|
||||
|
||||
@CheckData(name = "InventoryB", setback = 3, description = "Started digging blocks while inventory is open")
|
||||
public class InventoryB extends InventoryCheck {
|
||||
public InventoryB(GrimPlayer player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
public void handle(PacketReceiveEvent event, WrapperPlayClientPlayerDigging wrapper) {
|
||||
if (wrapper.getAction() != DiggingAction.START_DIGGING) return;
|
||||
|
||||
// Is not possible to start digging a block while the inventory is open.
|
||||
if (player.hasInventoryOpen) {
|
||||
if (flagAndAlert()) {
|
||||
// Cancel the packet
|
||||
if (shouldModifyPackets()) {
|
||||
event.setCancelled(true);
|
||||
player.onPacketCancel();
|
||||
}
|
||||
closeInventory();
|
||||
}
|
||||
} else {
|
||||
reward();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
package ac.grim.grimac.checks.impl.inventory;
|
||||
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.InventoryCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.anticheat.update.BlockPlace;
|
||||
|
||||
@CheckData(name = "InventoryC", setback = 3, description = "Placed a block while inventory is open")
|
||||
public class InventoryC extends InventoryCheck {
|
||||
|
||||
public InventoryC(GrimPlayer player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
public void onBlockPlace(final BlockPlace place) {
|
||||
// It is not possible to place a block while the inventory is open
|
||||
if (player.hasInventoryOpen) {
|
||||
if (flagAndAlert()) {
|
||||
if (shouldModifyPackets()) {
|
||||
place.resync();
|
||||
}
|
||||
closeInventory();
|
||||
}
|
||||
} else {
|
||||
reward();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
package ac.grim.grimac.checks.impl.inventory;
|
||||
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.InventoryCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.anticheat.update.PredictionComplete;
|
||||
import ac.grim.grimac.utils.data.VectorData;
|
||||
import ac.grim.grimac.utils.data.VectorData.MoveVectorData;
|
||||
import ac.grim.grimac.utils.data.VehicleData;
|
||||
|
||||
import java.util.StringJoiner;
|
||||
|
||||
@CheckData(name = "InventoryD", setback = 1, decay = 0.25)
|
||||
public class InventoryD extends InventoryCheck {
|
||||
private int horseJumpVerbose;
|
||||
|
||||
public InventoryD(GrimPlayer player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPredictionComplete(final PredictionComplete predictionComplete) {
|
||||
if (!predictionComplete.isChecked() ||
|
||||
predictionComplete.getData().isTeleport() ||
|
||||
player.getSetbackTeleportUtil().blockOffsets ||
|
||||
player.packetStateData.lastPacketWasTeleport ||
|
||||
player.packetStateData.isSlowedByUsingItem() ||
|
||||
System.currentTimeMillis() - player.lastBlockPlaceUseItem < 50L) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (player.hasInventoryOpen) {
|
||||
boolean inVehicle = player.compensatedEntities.getSelf().inVehicle();
|
||||
boolean isJumping, isMoving;
|
||||
|
||||
if (inVehicle) {
|
||||
VehicleData vehicle = player.vehicleData;
|
||||
|
||||
// Will flag once if player open anything with pressed space bar
|
||||
isJumping = vehicle.nextHorseJump > 0 && horseJumpVerbose++ >= 1;
|
||||
isMoving = vehicle.nextVehicleForward != 0 || vehicle.nextVehicleHorizontal != 0;
|
||||
} else {
|
||||
MoveVectorData move = findMovement(player.predictedVelocity);
|
||||
|
||||
isJumping = player.predictedVelocity.isJump();
|
||||
isMoving = move != null && (move.x != 0 || move.z != 0);
|
||||
}
|
||||
|
||||
if (!isMoving && !isJumping) {
|
||||
reward();
|
||||
return;
|
||||
}
|
||||
|
||||
if (flag()) {
|
||||
closeInventory();
|
||||
|
||||
StringJoiner joiner = new StringJoiner(" ");
|
||||
|
||||
if (isMoving) joiner.add("moving");
|
||||
if (isJumping) joiner.add("jumping");
|
||||
if (inVehicle) joiner.add("inVehicle");
|
||||
|
||||
alert(joiner.toString());
|
||||
}
|
||||
} else {
|
||||
horseJumpVerbose = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private MoveVectorData findMovement(VectorData vectorData) {
|
||||
if (vectorData instanceof MoveVectorData) {
|
||||
return (MoveVectorData) vectorData;
|
||||
}
|
||||
|
||||
while (vectorData != null) {
|
||||
vectorData = vectorData.lastVector;
|
||||
if (vectorData instanceof MoveVectorData) {
|
||||
return (MoveVectorData) vectorData;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
package ac.grim.grimac.checks.impl.inventory;
|
||||
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.InventoryCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.event.PacketSendEvent;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
|
||||
@CheckData(name = "InventoryE", setback = 3, description = "Sent a held item change packet while inventory is open")
|
||||
public class InventoryE extends InventoryCheck {
|
||||
private long lastTransaction = Long.MAX_VALUE; // Impossible transaction ID
|
||||
|
||||
public InventoryE(GrimPlayer player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPacketReceive(PacketReceiveEvent event) {
|
||||
super.onPacketReceive(event);
|
||||
|
||||
if (event.getPacketType() == PacketType.Play.Client.HELD_ITEM_CHANGE) {
|
||||
// It is not possible to change hotbar slots with held item change while the inventory is open
|
||||
// A container click packet would be sent instead
|
||||
if (player.hasInventoryOpen) {
|
||||
if (this.lastTransaction < player.lastTransactionReceived.get()
|
||||
&& flagAndAlert()) {
|
||||
// Cancel the packet
|
||||
if (shouldModifyPackets()) {
|
||||
event.setCancelled(true);
|
||||
player.onPacketCancel();
|
||||
player.getInventory().needResend = true;
|
||||
}
|
||||
closeInventory();
|
||||
}
|
||||
} else {
|
||||
reward();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPacketSend(PacketSendEvent event) {
|
||||
if (event.getPacketType() == PacketType.Play.Server.HELD_ITEM_CHANGE) {
|
||||
this.lastTransaction = player.lastTransactionSent.get();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
package ac.grim.grimac.checks.impl.inventory;
|
||||
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.InventoryCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.inventory.InventoryDesyncStatus;
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
|
||||
@CheckData(name = "InventoryF", setback = 3, description = "Sent a click window packet without a open inventory", experimental = true)
|
||||
public class InventoryF extends InventoryCheck {
|
||||
|
||||
public InventoryF(GrimPlayer player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPacketReceive(PacketReceiveEvent event) {
|
||||
// Exempt on 1.9+ server version due to the Via hack done in PacketPlayerWindow, the exemption can be deleted
|
||||
// once we are ahead of ViaVersion
|
||||
if (PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_9)
|
||||
|| player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_9)) return;
|
||||
|
||||
super.onPacketReceive(event);
|
||||
|
||||
if (event.getPacketType() == PacketType.Play.Client.CLICK_WINDOW) {
|
||||
if (!player.hasInventoryOpen && player.inventoryDesyncStatus == InventoryDesyncStatus.NOT_DESYNCED) {
|
||||
if (flagAndAlert()) {
|
||||
// Cancel the packet
|
||||
if (shouldModifyPackets()) {
|
||||
event.setCancelled(true);
|
||||
player.onPacketCancel();
|
||||
}
|
||||
closeInventory();
|
||||
}
|
||||
} else {
|
||||
reward();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
package ac.grim.grimac.checks.impl.inventory;
|
||||
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.InventoryCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientEntityAction;
|
||||
|
||||
@CheckData(name = "InventoryG", setback = 3, description = "Sent a entity action packet while inventory is open", experimental = true)
|
||||
public class InventoryG extends InventoryCheck {
|
||||
|
||||
public InventoryG(GrimPlayer player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPacketReceive(PacketReceiveEvent event) {
|
||||
if (player.packetStateData.lastPacketWasTeleport) return;
|
||||
super.onPacketReceive(event);
|
||||
|
||||
if (event.getPacketType() == PacketType.Play.Client.ENTITY_ACTION) {
|
||||
WrapperPlayClientEntityAction wrapper = new WrapperPlayClientEntityAction(event);
|
||||
WrapperPlayClientEntityAction.Action action = wrapper.getAction();
|
||||
|
||||
if (action == WrapperPlayClientEntityAction.Action.STOP_SNEAKING
|
||||
|| action == WrapperPlayClientEntityAction.Action.STOP_SPRINTING) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (player.hasInventoryOpen) {
|
||||
if (flagAndAlert()) {
|
||||
closeInventory();
|
||||
}
|
||||
} else {
|
||||
reward();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,6 @@ import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPluginMessage;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class ClientBrand extends Check implements PacketCheck {
|
||||
@@ -39,7 +38,6 @@ public class ClientBrand extends Check implements PacketCheck {
|
||||
System.arraycopy(data, 1, minusLength, 0, minusLength.length);
|
||||
|
||||
brand = new String(minusLength).replace(" (Velocity)", ""); //removes velocity's brand suffix
|
||||
brand = ChatColor.stripColor(brand); //strip color codes from client brand
|
||||
if (player.checkManager.getPrePredictionCheck(ExploitA.class).checkString(brand)) brand = "sent log4j";
|
||||
if (!GrimAPI.INSTANCE.getConfigManager().isIgnoredClient(brand)) {
|
||||
String message = GrimAPI.INSTANCE.getConfigManager().getConfig().getStringElse("client-brand-format", "%prefix% &f%player% joined using %brand%");
|
||||
|
||||
@@ -63,15 +63,15 @@ public class FastBreak extends Check implements PacketCheck {
|
||||
|
||||
if (digging.getAction() == DiggingAction.START_DIGGING) {
|
||||
WrappedBlockState block = player.compensatedWorld.getWrappedBlockStateAt(blockPosition);
|
||||
|
||||
|
||||
// Exempt all blocks that do not exist in the player version
|
||||
if (WrappedBlockState.getDefaultState(player.getClientVersion(), block.getType()).getType() == StateTypes.AIR) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
startBreak = System.currentTimeMillis() - (targetBlock == null ? 50 : 0); // ???
|
||||
targetBlock = blockPosition;
|
||||
|
||||
|
||||
maximumBlockDamage = BlockBreakSpeed.getBlockDamage(player, targetBlock);
|
||||
|
||||
double breakDelay = System.currentTimeMillis() - lastFinishBreak;
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package ac.grim.grimac.checks.impl.misc;
|
||||
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.PacketCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@CheckData(name = "TransactionOrder", experimental = false)
|
||||
public class TransactionOrder extends Check implements PacketCheck {
|
||||
|
||||
public TransactionOrder(GrimPlayer player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -7,7 +7,7 @@ import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.anticheat.update.PredictionComplete;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
|
||||
@CheckData(name = "NegativeTimer", configName = "NegativeTimer", setback = -1, experimental = true)
|
||||
@CheckData(name = "NegativeTimer", configName = "NegativeTimer", setback = 10, experimental = true)
|
||||
public class NegativeTimerCheck extends TimerCheck implements PostPredictionCheck {
|
||||
|
||||
public NegativeTimerCheck(GrimPlayer player) {
|
||||
@@ -24,7 +24,7 @@ public class NegativeTimerCheck extends TimerCheck implements PostPredictionChec
|
||||
|
||||
if (timerBalanceRealTime < lastMovementPlayerClock - clockDrift) {
|
||||
int lostMS = (int) ((System.nanoTime() - timerBalanceRealTime) / 1e6);
|
||||
if (flagAndAlert("-" + lostMS)) setbackIfAboveSetbackVL();
|
||||
flagAndAlert("-" + lostMS);
|
||||
timerBalanceRealTime += 50e6;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,8 @@ public class NoSlowA extends Check implements PostPredictionCheck {
|
||||
}
|
||||
|
||||
if (bestOffset > offsetToFlag) {
|
||||
if (flaggedLastTick && flagWithSetback()) {
|
||||
if (flaggedLastTick) {
|
||||
flagWithSetback();
|
||||
alert("");
|
||||
}
|
||||
flaggedLastTick = true;
|
||||
|
||||
@@ -35,4 +35,4 @@ public class NoSlowB extends Check implements PacketCheck {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,17 +2,32 @@ package ac.grim.grimac.checks.impl.movement;
|
||||
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.PacketCheck;
|
||||
import ac.grim.grimac.checks.type.PostPredictionCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.anticheat.update.PredictionComplete;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientEntityAction;
|
||||
|
||||
@CheckData(name = "NoSlowC", setback = 5, experimental = true)
|
||||
public class NoSlowC extends Check implements PostPredictionCheck {
|
||||
public class NoSlowC extends Check implements PostPredictionCheck, PacketCheck {
|
||||
public NoSlowC(GrimPlayer player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
public boolean startedSprintingBeforeSlowMovement = false;
|
||||
|
||||
@Override
|
||||
public void onPacketReceive(PacketReceiveEvent event) {
|
||||
if (event.getPacketType() == PacketType.Play.Client.ENTITY_ACTION) {
|
||||
if (new WrapperPlayClientEntityAction(event).getAction() == WrapperPlayClientEntityAction.Action.START_SPRINTING) {
|
||||
startedSprintingBeforeSlowMovement = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPredictionComplete(final PredictionComplete predictionComplete) {
|
||||
if (!predictionComplete.isChecked()) return;
|
||||
@@ -21,7 +36,8 @@ public class NoSlowC extends Check implements PostPredictionCheck {
|
||||
ClientVersion client = player.getClientVersion();
|
||||
|
||||
// https://bugs.mojang.com/browse/MC-152728
|
||||
if (client.isNewerThanOrEquals(ClientVersion.V_1_14_2)) {
|
||||
if (startedSprintingBeforeSlowMovement && client.isNewerThanOrEquals(ClientVersion.V_1_14_2)) {
|
||||
reward();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,26 +2,42 @@ package ac.grim.grimac.checks.impl.movement;
|
||||
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.PacketCheck;
|
||||
import ac.grim.grimac.checks.type.PostPredictionCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.anticheat.update.PredictionComplete;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientEntityAction;
|
||||
|
||||
@CheckData(name = "NoSlowD", setback = 5, experimental = true)
|
||||
public class NoSlowD extends Check implements PostPredictionCheck {
|
||||
public class NoSlowD extends Check implements PostPredictionCheck, PacketCheck {
|
||||
public NoSlowD(GrimPlayer player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
public boolean startedSprintingBeforeUse = false;
|
||||
private boolean flaggedLastTick = false;
|
||||
|
||||
@Override
|
||||
public void onPacketReceive(PacketReceiveEvent event) {
|
||||
if (event.getPacketType() == PacketType.Play.Client.ENTITY_ACTION) {
|
||||
if (new WrapperPlayClientEntityAction(event).getAction() == WrapperPlayClientEntityAction.Action.START_SPRINTING) {
|
||||
startedSprintingBeforeUse = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPredictionComplete(final PredictionComplete predictionComplete) {
|
||||
if (!predictionComplete.isChecked()) return;
|
||||
|
||||
if (player.packetStateData.isSlowedByUsingItem()) {
|
||||
// https://bugs.mojang.com/browse/MC-152728
|
||||
if (player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_14_2)) {
|
||||
if (startedSprintingBeforeUse && player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_14_2)) {
|
||||
reward();
|
||||
flaggedLastTick = false;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package ac.grim.grimac.checks.impl.movement;
|
||||
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.PacketCheck;
|
||||
import ac.grim.grimac.checks.type.PostPredictionCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.anticheat.update.PredictionComplete;
|
||||
@@ -12,7 +13,7 @@ import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientEn
|
||||
import static com.github.retrooper.packetevents.protocol.potion.PotionTypes.BLINDNESS;
|
||||
|
||||
@CheckData(name = "NoSlowE", setback = 5, experimental = true)
|
||||
public class NoSlowE extends Check implements PostPredictionCheck {
|
||||
public class NoSlowE extends Check implements PostPredictionCheck, PacketCheck {
|
||||
public NoSlowE(GrimPlayer player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import ac.grim.grimac.player.GrimPlayer;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.util.Vector3d;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientInteractEntity;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerFlying;
|
||||
|
||||
public class SetbackBlocker extends Check implements PacketCheck {
|
||||
|
||||
@@ -20,9 +20,9 @@ public class TimerCheck extends Check implements PacketCheck {
|
||||
|
||||
// How long should the player be able to fall back behind their ping?
|
||||
// Default: 120 milliseconds
|
||||
long clockDrift;
|
||||
long clockDrift = (long) 120e6;
|
||||
|
||||
long limitAbuseOverPing;
|
||||
long limitAbuseOverPing = 1000;
|
||||
|
||||
boolean hasGottenMovementAfterTransaction = false;
|
||||
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
package ac.grim.grimac.checks.impl.packetorder;
|
||||
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.PostPredictionCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.anticheat.update.PredictionComplete;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientClickWindow;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientClickWindow.WindowClickType;
|
||||
|
||||
@CheckData(name = "PacketOrderA", experimental = true)
|
||||
public class PacketOrderA extends Check implements PostPredictionCheck {
|
||||
public PacketOrderA(final GrimPlayer player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
private int invalid;
|
||||
|
||||
@Override
|
||||
public void onPacketReceive(PacketReceiveEvent event) {
|
||||
if (event.getPacketType() == PacketType.Play.Client.CLICK_WINDOW) {
|
||||
final WindowClickType clickType = new WrapperPlayClientClickWindow(event).getWindowClickType();
|
||||
|
||||
if ((clickType == WindowClickType.PICKUP || clickType == WindowClickType.PICKUP_ALL) && player.packetOrderProcessor.isQuickMoveClicking()
|
||||
|| clickType == WindowClickType.QUICK_MOVE && player.packetOrderProcessor.isPickUpClicking()) {
|
||||
if (player.getClientVersion().isOlderThanOrEquals(ClientVersion.V_1_8)) {
|
||||
if (flagAndAlert() && shouldModifyPackets()) {
|
||||
event.setCancelled(true);
|
||||
player.onPacketCancel();
|
||||
}
|
||||
} else {
|
||||
invalid++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPredictionComplete(PredictionComplete predictionComplete) {
|
||||
// we don't need to check pre-1.9 players here (no tick skipping)
|
||||
if (player.getClientVersion().isOlderThanOrEquals(ClientVersion.V_1_8)) return;
|
||||
|
||||
if (player.isTickingReliablyFor(3)) {
|
||||
for (; invalid >= 1; invalid--) {
|
||||
flagAndAlert();
|
||||
}
|
||||
}
|
||||
|
||||
invalid = 0;
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package ac.grim.grimac.checks.impl.packetorder;
|
||||
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.PacketCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
|
||||
@CheckData(name = "PacketOrderD")
|
||||
public class PacketOrderD extends Check implements PacketCheck {
|
||||
public PacketOrderD(GrimPlayer player) {
|
||||
super(player);
|
||||
}
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
package ac.grim.grimac.checks.impl.packetorder;
|
||||
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.PostPredictionCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.anticheat.update.PredictionComplete;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
|
||||
@CheckData(name = "PacketOrderE", experimental = true)
|
||||
public class PacketOrderE extends Check implements PostPredictionCheck {
|
||||
public PacketOrderE(final GrimPlayer player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
private int invalid;
|
||||
private boolean setback;
|
||||
|
||||
@Override
|
||||
public void onPacketReceive(PacketReceiveEvent event) {
|
||||
if (event.getPacketType() == PacketType.Play.Client.HELD_ITEM_CHANGE) {
|
||||
if (player.packetOrderProcessor.isAttacking()
|
||||
|| player.packetOrderProcessor.isRightClicking()
|
||||
|| player.packetOrderProcessor.isOpeningInventory()
|
||||
|| player.packetOrderProcessor.isReleasing()
|
||||
|| player.packetOrderProcessor.isSneaking()
|
||||
|| player.packetOrderProcessor.isSprinting()
|
||||
|| player.packetOrderProcessor.isLeavingBed()
|
||||
|| player.packetOrderProcessor.isStartingToGlide()
|
||||
|| player.packetOrderProcessor.isJumpingWithMount()
|
||||
) {
|
||||
if (player.getClientVersion().isNewerThan(ClientVersion.V_1_8) || flagAndAlert()) {
|
||||
invalid++;
|
||||
|
||||
if (player.packetOrderProcessor.isUsing()) {
|
||||
setback = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPredictionComplete(PredictionComplete predictionComplete) {
|
||||
if (player.getClientVersion().isOlderThanOrEquals(ClientVersion.V_1_8)) {
|
||||
if (setback) {
|
||||
setback = false;
|
||||
setbackIfAboveSetbackVL();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (player.isTickingReliablyFor(3)) {
|
||||
for (; invalid >= 1; invalid--) {
|
||||
if (flagAndAlert() && setback) {
|
||||
setback = false;
|
||||
setbackIfAboveSetbackVL();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
invalid = 0;
|
||||
}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
package ac.grim.grimac.checks.impl.packetorder;
|
||||
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.PostPredictionCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.anticheat.update.PredictionComplete;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.protocol.player.DiggingAction;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientClientStatus;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerDigging;
|
||||
|
||||
@CheckData(name = "PacketOrderF", experimental = true)
|
||||
public class PacketOrderF extends Check implements PostPredictionCheck {
|
||||
public PacketOrderF(GrimPlayer player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
private int invalid;
|
||||
|
||||
@Override
|
||||
public void onPacketReceive(PacketReceiveEvent event) {
|
||||
if (event.getPacketType() == PacketType.Play.Client.INTERACT_ENTITY
|
||||
|| event.getPacketType() == PacketType.Play.Client.PLAYER_BLOCK_PLACEMENT
|
||||
|| event.getPacketType() == PacketType.Play.Client.USE_ITEM
|
||||
|| event.getPacketType() == PacketType.Play.Client.PICK_ITEM
|
||||
|| event.getPacketType() == PacketType.Play.Client.PLAYER_DIGGING
|
||||
|| (event.getPacketType() == PacketType.Play.Client.CLIENT_STATUS
|
||||
&& new WrapperPlayClientClientStatus(event).getAction() == WrapperPlayClientClientStatus.Action.OPEN_INVENTORY_ACHIEVEMENT)
|
||||
) if (player.packetOrderProcessor.isSprinting() || player.packetOrderProcessor.isSneaking()) {
|
||||
if (player.getClientVersion().isOlderThanOrEquals(ClientVersion.V_1_8)) {
|
||||
if (flagAndAlert() && shouldModifyPackets()) {
|
||||
if (event.getPacketType() == PacketType.Play.Client.PLAYER_DIGGING
|
||||
&& new WrapperPlayClientPlayerDigging(event).getAction() == DiggingAction.RELEASE_USE_ITEM
|
||||
) return; // don't cause a noslow
|
||||
|
||||
event.setCancelled(true);
|
||||
player.onPacketCancel();
|
||||
}
|
||||
} else {
|
||||
invalid++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPredictionComplete(PredictionComplete predictionComplete) {
|
||||
// we don't need to check pre-1.9 players here (no tick skipping)
|
||||
if (player.getClientVersion().isOlderThanOrEquals(ClientVersion.V_1_8)) return;
|
||||
|
||||
if (player.isTickingReliablyFor(3)) {
|
||||
for (; invalid >= 1; invalid--) {
|
||||
flagAndAlert();
|
||||
}
|
||||
}
|
||||
|
||||
invalid = 0;
|
||||
}
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
package ac.grim.grimac.checks.impl.packetorder;
|
||||
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.PostPredictionCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.anticheat.update.PredictionComplete;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.protocol.player.DiggingAction;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientClientStatus;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerDigging;
|
||||
|
||||
@CheckData(name = "PacketOrderG", experimental = true)
|
||||
public class PacketOrderG extends Check implements PostPredictionCheck {
|
||||
public PacketOrderG(GrimPlayer player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
private int invalid;
|
||||
|
||||
@Override
|
||||
public void onPacketReceive(PacketReceiveEvent event) {
|
||||
if (event.getPacketType() == PacketType.Play.Client.PLAYER_DIGGING
|
||||
|| (event.getPacketType() == PacketType.Play.Client.CLIENT_STATUS
|
||||
&& new WrapperPlayClientClientStatus(event).getAction() == WrapperPlayClientClientStatus.Action.OPEN_INVENTORY_ACHIEVEMENT)
|
||||
) {
|
||||
if (event.getPacketType() == PacketType.Play.Client.PLAYER_DIGGING) {
|
||||
final DiggingAction action = new WrapperPlayClientPlayerDigging(event).getAction();
|
||||
if (action == DiggingAction.RELEASE_USE_ITEM
|
||||
|| action == DiggingAction.START_DIGGING
|
||||
|| action == DiggingAction.CANCELLED_DIGGING
|
||||
|| action == DiggingAction.FINISHED_DIGGING
|
||||
) return;
|
||||
}
|
||||
|
||||
if (player.packetOrderProcessor.isAttacking()
|
||||
|| player.packetOrderProcessor.isReleasing()
|
||||
|| player.packetOrderProcessor.isRightClicking()
|
||||
|| player.packetOrderProcessor.isPicking()
|
||||
|| player.packetOrderProcessor.isDigging()
|
||||
) {
|
||||
if (player.getClientVersion().isOlderThanOrEquals(ClientVersion.V_1_8)) {
|
||||
if (flagAndAlert() && shouldModifyPackets()) {
|
||||
event.setCancelled(true);
|
||||
player.onPacketCancel();
|
||||
}
|
||||
} else {
|
||||
invalid++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPredictionComplete(PredictionComplete predictionComplete) {
|
||||
// we don't need to check pre-1.9 players here (no tick skipping)
|
||||
if (player.getClientVersion().isOlderThanOrEquals(ClientVersion.V_1_8)) return;
|
||||
|
||||
if (player.isTickingReliablyFor(3)) {
|
||||
for (; invalid >= 1; invalid--) {
|
||||
flagAndAlert();
|
||||
}
|
||||
}
|
||||
|
||||
invalid = 0;
|
||||
}
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
package ac.grim.grimac.checks.impl.packetorder;
|
||||
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.PostPredictionCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.anticheat.update.PredictionComplete;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientEntityAction;
|
||||
|
||||
@CheckData(name = "PacketOrderH", experimental = true)
|
||||
public class PacketOrderH extends Check implements PostPredictionCheck {
|
||||
public PacketOrderH(final GrimPlayer player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
private int invalid;
|
||||
|
||||
@Override
|
||||
public void onPacketReceive(PacketReceiveEvent event) {
|
||||
if (event.getPacketType() == PacketType.Play.Client.ENTITY_ACTION) {
|
||||
switch (new WrapperPlayClientEntityAction(event).getAction()) {
|
||||
case START_SPRINTING:
|
||||
case STOP_SPRINTING:
|
||||
if (player.packetOrderProcessor.isSneaking()) {
|
||||
if (player.getClientVersion().isOlderThanOrEquals(ClientVersion.V_1_8)) {
|
||||
flagAndAlert();
|
||||
} else {
|
||||
invalid++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPredictionComplete(PredictionComplete predictionComplete) {
|
||||
// we don't need to check pre-1.9 players here (no tick skipping)
|
||||
if (player.getClientVersion().isOlderThanOrEquals(ClientVersion.V_1_8)) return;
|
||||
|
||||
if (player.isTickingReliablyFor(3)) {
|
||||
for (; invalid >= 1; invalid--) {
|
||||
flagAndAlert();
|
||||
}
|
||||
}
|
||||
|
||||
invalid = 0;
|
||||
}
|
||||
}
|
||||
@@ -1,130 +0,0 @@
|
||||
package ac.grim.grimac.checks.impl.packetorder;
|
||||
|
||||
import ac.grim.grimac.api.config.ConfigManager;
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.PostPredictionCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.anticheat.update.PredictionComplete;
|
||||
import ac.grim.grimac.utils.nmsutil.BlockBreakSpeed;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.protocol.player.GameMode;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientInteractEntity;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerDigging;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerFlying;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
|
||||
@CheckData(name = "PacketOrderI", experimental = true)
|
||||
public class PacketOrderI extends Check implements PostPredictionCheck {
|
||||
public PacketOrderI(final GrimPlayer player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
private boolean exemptPlacingWhileDigging;
|
||||
|
||||
private boolean setback;
|
||||
private boolean digging; // for placing
|
||||
private final ArrayDeque<String> flags = new ArrayDeque<>();
|
||||
|
||||
@Override
|
||||
public void onPacketReceive(PacketReceiveEvent event) {
|
||||
if (event.getPacketType() == PacketType.Play.Client.INTERACT_ENTITY) {
|
||||
if (new WrapperPlayClientInteractEntity(event).getAction() == WrapperPlayClientInteractEntity.InteractAction.ATTACK) {
|
||||
if (player.packetOrderProcessor.isRightClicking() || player.packetOrderProcessor.isPicking() || player.packetOrderProcessor.isReleasing() || player.packetOrderProcessor.isDigging()) {
|
||||
if (player.getClientVersion().isOlderThanOrEquals(ClientVersion.V_1_8)) {
|
||||
if (flagAndAlert("attack") && shouldModifyPackets()) {
|
||||
event.setCancelled(true);
|
||||
player.onPacketCancel();
|
||||
}
|
||||
} else {
|
||||
flags.add("attack");
|
||||
}
|
||||
}
|
||||
} else if (player.packetOrderProcessor.isReleasing() || player.packetOrderProcessor.isDigging()) {
|
||||
if (player.getClientVersion().isOlderThanOrEquals(ClientVersion.V_1_8)) {
|
||||
if (flagAndAlert("interact") && shouldModifyPackets()) {
|
||||
event.setCancelled(true);
|
||||
player.onPacketCancel();
|
||||
}
|
||||
} else {
|
||||
flags.add("interact");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (event.getPacketType() == PacketType.Play.Client.PLAYER_BLOCK_PLACEMENT || event.getPacketType() == PacketType.Play.Client.USE_ITEM) {
|
||||
if (player.packetOrderProcessor.isReleasing() || digging) {
|
||||
if (player.getClientVersion().isOlderThanOrEquals(ClientVersion.V_1_8)) {
|
||||
if (flagAndAlert("place/use") && shouldModifyPackets()) {
|
||||
event.setCancelled(true);
|
||||
player.onPacketCancel();
|
||||
}
|
||||
} else {
|
||||
flags.add("place");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (event.getPacketType() == PacketType.Play.Client.PLAYER_DIGGING) {
|
||||
WrapperPlayClientPlayerDigging packet = new WrapperPlayClientPlayerDigging(event);
|
||||
|
||||
switch (packet.getAction()) {
|
||||
case RELEASE_USE_ITEM:
|
||||
if (player.packetOrderProcessor.isAttacking() || player.packetOrderProcessor.isRightClicking() || player.packetOrderProcessor.isPicking() || player.packetOrderProcessor.isDigging()) {
|
||||
if (player.getClientVersion().isOlderThanOrEquals(ClientVersion.V_1_8)) {
|
||||
if (flagAndAlert("release")) {
|
||||
setback = true;
|
||||
}
|
||||
} else {
|
||||
flags.add("release");
|
||||
setback = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case START_DIGGING:
|
||||
double damage = BlockBreakSpeed.getBlockDamage(player, packet.getBlockPosition());
|
||||
if (damage >= 1 || damage <= 0 && player.gamemode == GameMode.CREATIVE) {
|
||||
return;
|
||||
}
|
||||
case CANCELLED_DIGGING:
|
||||
case FINISHED_DIGGING:
|
||||
if (exemptPlacingWhileDigging || player.getClientVersion().isOlderThanOrEquals(ClientVersion.V_1_7_10)) {
|
||||
return;
|
||||
}
|
||||
digging = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (WrapperPlayClientPlayerFlying.isFlying(event.getPacketType()) && player.getClientVersion().isOlderThanOrEquals(ClientVersion.V_1_8) && !player.packetStateData.lastPacketWasTeleport) {
|
||||
digging = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPredictionComplete(PredictionComplete predictionComplete) {
|
||||
if (player.getClientVersion().isOlderThanOrEquals(ClientVersion.V_1_8)) {
|
||||
if (setback) {
|
||||
setbackIfAboveSetbackVL();
|
||||
setback = false;
|
||||
}
|
||||
} else if (player.isTickingReliablyFor(3)) {
|
||||
for (String verbose : flags) {
|
||||
if (flagAndAlert(verbose) && setback) {
|
||||
setbackIfAboveSetbackVL();
|
||||
setback = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
flags.clear();
|
||||
setback = digging = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReload(ConfigManager config) {
|
||||
exemptPlacingWhileDigging = config.getBooleanElse(getConfigName() + ".exempt-placing-while-digging", false);
|
||||
}
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
package ac.grim.grimac.checks.impl.packetorder;
|
||||
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.PostPredictionCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.anticheat.update.PredictionComplete;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
|
||||
@CheckData(name = "PacketOrderJ", experimental = true)
|
||||
public class PacketOrderJ extends Check implements PostPredictionCheck {
|
||||
public PacketOrderJ(final GrimPlayer player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
private int invalid;
|
||||
|
||||
@Override
|
||||
public void onPacketReceive(PacketReceiveEvent event) {
|
||||
if (event.getPacketType() == PacketType.Play.Client.PLAYER_BLOCK_PLACEMENT || event.getPacketType() == PacketType.Play.Client.USE_ITEM) {
|
||||
if (player.packetOrderProcessor.isAttacking() && !player.packetOrderProcessor.isInteracting()) {
|
||||
if (player.getClientVersion().isOlderThanOrEquals(ClientVersion.V_1_8)) {
|
||||
if (flagAndAlert() && shouldModifyPackets()) {
|
||||
event.setCancelled(true);
|
||||
player.onPacketCancel();
|
||||
}
|
||||
} else {
|
||||
invalid++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPredictionComplete(PredictionComplete predictionComplete) {
|
||||
// we don't need to check pre-1.9 players here (no tick skipping)
|
||||
if (player.getClientVersion().isOlderThanOrEquals(ClientVersion.V_1_8)) return;
|
||||
|
||||
if (player.isTickingReliablyFor(3)) {
|
||||
for (; invalid >= 1; invalid--) {
|
||||
flagAndAlert();
|
||||
}
|
||||
}
|
||||
|
||||
invalid = 0;
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
package ac.grim.grimac.checks.impl.packetorder;
|
||||
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.PostPredictionCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.anticheat.update.PredictionComplete;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientClientStatus;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
|
||||
@CheckData(name = "PacketOrderK", experimental = true)
|
||||
public class PacketOrderK extends Check implements PostPredictionCheck {
|
||||
public PacketOrderK(final GrimPlayer player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
private final ArrayDeque<String> flags = new ArrayDeque<>();
|
||||
|
||||
@Override
|
||||
public void onPacketReceive(PacketReceiveEvent event) {
|
||||
if (event.getPacketType() == PacketType.Play.Client.CLIENT_STATUS) {
|
||||
if (new WrapperPlayClientClientStatus(event).getAction() == WrapperPlayClientClientStatus.Action.OPEN_INVENTORY_ACHIEVEMENT) {
|
||||
if (player.packetOrderProcessor.isClickingInInventory() || player.packetOrderProcessor.isClosingInventory()) {
|
||||
if (player.getClientVersion().isOlderThanOrEquals(ClientVersion.V_1_8)) {
|
||||
flagAndAlert("open");
|
||||
} else {
|
||||
flags.add("open");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (event.getPacketType() == PacketType.Play.Client.CLICK_WINDOW || event.getPacketType() == PacketType.Play.Client.CLOSE_WINDOW) {
|
||||
if (player.packetOrderProcessor.isOpeningInventory()) {
|
||||
if (player.getClientVersion().isOlderThanOrEquals(ClientVersion.V_1_8)) {
|
||||
if (flagAndAlert(event.getPacketType() == PacketType.Play.Client.CLICK_WINDOW ? "click" : "close") && shouldModifyPackets()) {
|
||||
event.setCancelled(true);
|
||||
player.onPacketCancel();
|
||||
}
|
||||
} else {
|
||||
flags.add(event.getPacketType() == PacketType.Play.Client.CLICK_WINDOW ? "click" : "close");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPredictionComplete(PredictionComplete predictionComplete) {
|
||||
// we don't need to check pre-1.9 players here (no tick skipping)
|
||||
if (player.getClientVersion().isOlderThanOrEquals(ClientVersion.V_1_8)) return;
|
||||
|
||||
if (player.isTickingReliablyFor(3)) {
|
||||
for (String verbose : flags) {
|
||||
flagAndAlert(verbose);
|
||||
}
|
||||
}
|
||||
|
||||
flags.clear();
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
package ac.grim.grimac.checks.impl.packetorder;
|
||||
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.PostPredictionCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.anticheat.update.PredictionComplete;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.protocol.player.DiggingAction;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientClientStatus;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerDigging;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
|
||||
@CheckData(name = "PacketOrderL", experimental = true)
|
||||
public class PacketOrderL extends Check implements PostPredictionCheck {
|
||||
public PacketOrderL(final GrimPlayer player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
private final ArrayDeque<String> flags = new ArrayDeque<>();
|
||||
|
||||
@Override
|
||||
public void onPacketReceive(PacketReceiveEvent event) {
|
||||
if (event.getPacketType() == PacketType.Play.Client.CLIENT_STATUS) {
|
||||
if (new WrapperPlayClientClientStatus(event).getAction() == WrapperPlayClientClientStatus.Action.OPEN_INVENTORY_ACHIEVEMENT) {
|
||||
if (player.packetOrderProcessor.isDropping()) {
|
||||
if (player.getClientVersion().isOlderThanOrEquals(ClientVersion.V_1_8)) {
|
||||
if (flagAndAlert("inventory") && shouldModifyPackets()) {
|
||||
event.setCancelled(true);
|
||||
player.onPacketCancel();
|
||||
}
|
||||
} else {
|
||||
flags.add("inventory");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (event.getPacketType() == PacketType.Play.Client.PLAYER_DIGGING) {
|
||||
if (new WrapperPlayClientPlayerDigging(event).getAction() == DiggingAction.SWAP_ITEM_WITH_OFFHAND) {
|
||||
if (player.packetOrderProcessor.isDropping()) {
|
||||
flags.add("swap");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPredictionComplete(PredictionComplete predictionComplete) {
|
||||
// we don't need to check pre-1.9 players here (no tick skipping)
|
||||
if (player.getClientVersion().isOlderThanOrEquals(ClientVersion.V_1_8)) return;
|
||||
|
||||
if (player.isTickingReliablyFor(3)) {
|
||||
for (String verbose : flags) {
|
||||
flagAndAlert(verbose);
|
||||
}
|
||||
}
|
||||
|
||||
flags.clear();
|
||||
}
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
package ac.grim.grimac.checks.impl.packetorder;
|
||||
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.PostPredictionCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.anticheat.update.PredictionComplete;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.protocol.world.BlockFace;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientInteractEntity;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerBlockPlacement;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerFlying;
|
||||
|
||||
@CheckData(name = "PacketOrderM", experimental = true)
|
||||
public class PacketOrderM extends Check implements PostPredictionCheck {
|
||||
public PacketOrderM(final GrimPlayer player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
private int invalid;
|
||||
private boolean usingWithoutInteract, interacting;
|
||||
|
||||
@Override
|
||||
public void onPacketReceive(PacketReceiveEvent event) {
|
||||
if (event.getPacketType() == PacketType.Play.Client.INTERACT_ENTITY) {
|
||||
if (new WrapperPlayClientInteractEntity(event).getAction() != WrapperPlayClientInteractEntity.InteractAction.ATTACK) {
|
||||
interacting = true;
|
||||
if (usingWithoutInteract) {
|
||||
if (player.getClientVersion().isOlderThanOrEquals(ClientVersion.V_1_8)) {
|
||||
if (flagAndAlert() && shouldModifyPackets()) {
|
||||
event.setCancelled(true);
|
||||
player.onPacketCancel();
|
||||
}
|
||||
} else {
|
||||
invalid++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (event.getPacketType() == PacketType.Play.Client.USE_ITEM
|
||||
|| event.getPacketType() == PacketType.Play.Client.PLAYER_BLOCK_PLACEMENT
|
||||
&& new WrapperPlayClientPlayerBlockPlacement(event).getFace() == BlockFace.OTHER) {
|
||||
if (!interacting) {
|
||||
usingWithoutInteract = true;
|
||||
}
|
||||
|
||||
interacting = false;
|
||||
}
|
||||
|
||||
if (WrapperPlayClientPlayerFlying.isFlying(event.getPacketType()) && player.getClientVersion().isOlderThanOrEquals(ClientVersion.V_1_8) && !player.packetStateData.lastPacketWasTeleport) {
|
||||
usingWithoutInteract = interacting = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPredictionComplete(PredictionComplete predictionComplete) {
|
||||
// we don't need to check pre-1.9 players here (no tick skipping)
|
||||
if (player.getClientVersion().isOlderThanOrEquals(ClientVersion.V_1_8)) return;
|
||||
|
||||
if (player.isTickingReliablyFor(3)) {
|
||||
for (; invalid >= 1; invalid--) {
|
||||
flagAndAlert();
|
||||
}
|
||||
}
|
||||
|
||||
invalid = 0;
|
||||
usingWithoutInteract = interacting = false;
|
||||
}
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
package ac.grim.grimac.checks.impl.packetorder;
|
||||
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.BlockPlaceCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.anticheat.update.BlockPlace;
|
||||
import ac.grim.grimac.utils.anticheat.update.PredictionComplete;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.protocol.world.BlockFace;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerBlockPlacement;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerFlying;
|
||||
|
||||
@CheckData(name = "PacketOrderN", experimental = true)
|
||||
public class PacketOrderN extends BlockPlaceCheck {
|
||||
public PacketOrderN(final GrimPlayer player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
private int invalid;
|
||||
private boolean usingWithoutPlacing, placing;
|
||||
|
||||
@Override
|
||||
public void onBlockPlace(BlockPlace place) {
|
||||
placing = true;
|
||||
if (usingWithoutPlacing) {
|
||||
if (player.getClientVersion().isOlderThanOrEquals(ClientVersion.V_1_8)) {
|
||||
if (flagAndAlert() && shouldModifyPackets() && shouldCancel()) {
|
||||
place.resync();
|
||||
}
|
||||
} else {
|
||||
invalid++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPacketReceive(PacketReceiveEvent event) {
|
||||
if (event.getPacketType() == PacketType.Play.Client.USE_ITEM
|
||||
|| event.getPacketType() == PacketType.Play.Client.PLAYER_BLOCK_PLACEMENT
|
||||
&& new WrapperPlayClientPlayerBlockPlacement(event).getFace() == BlockFace.OTHER) {
|
||||
if (!placing) {
|
||||
usingWithoutPlacing = true;
|
||||
}
|
||||
|
||||
placing = false;
|
||||
}
|
||||
|
||||
if (WrapperPlayClientPlayerFlying.isFlying(event.getPacketType()) && player.getClientVersion().isOlderThanOrEquals(ClientVersion.V_1_8) && !player.packetStateData.lastPacketWasTeleport) {
|
||||
usingWithoutPlacing = placing = false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPredictionComplete(PredictionComplete predictionComplete) {
|
||||
// we don't need to check pre-1.9 players here (no tick skipping)
|
||||
if (player.getClientVersion().isOlderThanOrEquals(ClientVersion.V_1_8)) return;
|
||||
|
||||
if (player.isTickingReliablyFor(3)) {
|
||||
for (; invalid >= 1; invalid--) {
|
||||
flagAndAlert();
|
||||
}
|
||||
}
|
||||
|
||||
invalid = 0;
|
||||
usingWithoutPlacing = placing = false;
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
package ac.grim.grimac.checks.impl.packetorder;
|
||||
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.BlockPlaceCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.anticheat.update.BlockPlace;
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.protocol.player.InteractionHand;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerFlying;
|
||||
|
||||
@CheckData(name = "PacketOrderO", experimental = true)
|
||||
public class PacketOrderO extends BlockPlaceCheck {
|
||||
public PacketOrderO(final GrimPlayer player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
private boolean sentMainhand;
|
||||
|
||||
@Override
|
||||
public void onBlockPlace(BlockPlace place) {
|
||||
if (!isSupported()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (place.getHand() == InteractionHand.OFF_HAND) {
|
||||
if (!sentMainhand) {
|
||||
if (flagAndAlert("Skipped Mainhand") && shouldModifyPackets() && shouldCancel()) {
|
||||
place.resync();
|
||||
}
|
||||
}
|
||||
|
||||
sentMainhand = false;
|
||||
} else {
|
||||
if (sentMainhand) {
|
||||
if (flagAndAlert("Skipped Offhand") && shouldModifyPackets() && shouldCancel()) {
|
||||
place.resync();
|
||||
}
|
||||
}
|
||||
|
||||
sentMainhand = !place.isBlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPacketReceive(PacketReceiveEvent event) {
|
||||
if (WrapperPlayClientPlayerFlying.isFlying(event.getPacketType()) && !player.packetStateData.lastPacketWasTeleport && !player.packetStateData.lastPacketWasOnePointSeventeenDuplicate) {
|
||||
if (sentMainhand) {
|
||||
sentMainhand = false;
|
||||
flagAndAlert("Skipped Offhand (Tick)");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isSupported() {
|
||||
return player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_13) && PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_9);
|
||||
}
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
package ac.grim.grimac.checks.impl.packetorder;
|
||||
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.PacketCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.protocol.player.InteractionHand;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientInteractEntity;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientInteractEntity.InteractAction;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerFlying;
|
||||
|
||||
@CheckData(name = "PacketOrderP", experimental = true)
|
||||
public class PacketOrderP extends Check implements PacketCheck {
|
||||
public PacketOrderP(final GrimPlayer player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
private boolean sentMainhand;
|
||||
private int requiredEntity;
|
||||
private boolean requiredSneaking;
|
||||
|
||||
@Override
|
||||
public void onPacketReceive(PacketReceiveEvent event) {
|
||||
if (event.getPacketType() == PacketType.Play.Client.INTERACT_ENTITY && player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_9)) {
|
||||
final WrapperPlayClientInteractEntity packet = new WrapperPlayClientInteractEntity(event);
|
||||
InteractAction action = packet.getAction();
|
||||
if (action != InteractAction.ATTACK) {
|
||||
final boolean sneaking = packet.isSneaking().orElse(false);
|
||||
final int entity = packet.getEntityId();
|
||||
|
||||
if (packet.getHand() == InteractionHand.OFF_HAND) {
|
||||
if (action == InteractAction.INTERACT) {
|
||||
if (!sentMainhand) {
|
||||
if (flagAndAlert("Skipped Mainhand") && shouldModifyPackets()) {
|
||||
event.setCancelled(true);
|
||||
player.onPacketCancel();
|
||||
}
|
||||
}
|
||||
sentMainhand = false;
|
||||
} else if (sneaking != requiredSneaking || entity != requiredEntity) {
|
||||
String verbose = "requiredEntity=" + requiredEntity + ", entity=" + entity
|
||||
+ ", requiredSneaking=" + requiredSneaking + ", sneaking=" + sneaking;
|
||||
if (flagAndAlert(verbose) && shouldModifyPackets()) {
|
||||
event.setCancelled(true);
|
||||
player.onPacketCancel();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
requiredEntity = entity;
|
||||
requiredSneaking = sneaking;
|
||||
sentMainhand = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (WrapperPlayClientPlayerFlying.isFlying(event.getPacketType()) && !player.packetStateData.lastPacketWasTeleport && !player.packetStateData.lastPacketWasOnePointSeventeenDuplicate) {
|
||||
sentMainhand = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,178 +0,0 @@
|
||||
package ac.grim.grimac.checks.impl.packetorder;
|
||||
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.checks.type.PostPredictionCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.anticheat.update.PredictionComplete;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketTypeCommon;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.protocol.world.BlockFace;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.*;
|
||||
import lombok.Getter;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
|
||||
@Getter
|
||||
public final class PacketOrderProcessor extends Check implements PostPredictionCheck {
|
||||
public PacketOrderProcessor(final GrimPlayer player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
private boolean openingInventory; // only pre 1.9 clients on pre 1.9 servers
|
||||
private boolean swapping;
|
||||
private boolean dropping;
|
||||
private boolean interacting;
|
||||
private boolean attacking;
|
||||
private boolean releasing;
|
||||
private boolean digging;
|
||||
private boolean sprinting;
|
||||
private boolean sneaking;
|
||||
private boolean placing;
|
||||
private boolean using;
|
||||
private boolean picking;
|
||||
private boolean clickingInInventory;
|
||||
private boolean closingInventory;
|
||||
private boolean quickMoveClicking;
|
||||
private boolean pickUpClicking;
|
||||
private boolean leavingBed;
|
||||
private boolean startingToGlide;
|
||||
private boolean jumpingWithMount;
|
||||
|
||||
@Override
|
||||
public void onPacketReceive(PacketReceiveEvent event) {
|
||||
final PacketTypeCommon packetType = event.getPacketType();
|
||||
|
||||
if (packetType == PacketType.Play.Client.CLIENT_STATUS) {
|
||||
if (new WrapperPlayClientClientStatus(event).getAction() == WrapperPlayClientClientStatus.Action.OPEN_INVENTORY_ACHIEVEMENT) {
|
||||
openingInventory = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (packetType == PacketType.Play.Client.INTERACT_ENTITY) {
|
||||
if (new WrapperPlayClientInteractEntity(event).getAction() == WrapperPlayClientInteractEntity.InteractAction.ATTACK) {
|
||||
attacking = true;
|
||||
} else {
|
||||
interacting = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (packetType == PacketType.Play.Client.PLAYER_DIGGING) {
|
||||
switch (new WrapperPlayClientPlayerDigging(event).getAction()) {
|
||||
case SWAP_ITEM_WITH_OFFHAND:
|
||||
swapping = true;
|
||||
break;
|
||||
case DROP_ITEM:
|
||||
case DROP_ITEM_STACK:
|
||||
dropping = true;
|
||||
break;
|
||||
case RELEASE_USE_ITEM:
|
||||
releasing = true;
|
||||
break;
|
||||
case FINISHED_DIGGING:
|
||||
case CANCELLED_DIGGING:
|
||||
case START_DIGGING:
|
||||
digging = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (packetType == PacketType.Play.Client.ENTITY_ACTION) {
|
||||
switch (new WrapperPlayClientEntityAction(event).getAction()) {
|
||||
case START_SPRINTING:
|
||||
case STOP_SPRINTING:
|
||||
sprinting = true;
|
||||
break;
|
||||
case STOP_SNEAKING:
|
||||
case START_SNEAKING:
|
||||
sneaking = true;
|
||||
break;
|
||||
case LEAVE_BED:
|
||||
leavingBed = true;
|
||||
break;
|
||||
case START_FLYING_WITH_ELYTRA:
|
||||
startingToGlide = true;
|
||||
break;
|
||||
case OPEN_HORSE_INVENTORY:
|
||||
openingInventory = true;
|
||||
break;
|
||||
case START_JUMPING_WITH_HORSE:
|
||||
case STOP_JUMPING_WITH_HORSE:
|
||||
jumpingWithMount = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (packetType == PacketType.Play.Client.USE_ITEM) {
|
||||
using = true;
|
||||
}
|
||||
|
||||
if (packetType == PacketType.Play.Client.PLAYER_BLOCK_PLACEMENT) {
|
||||
if (new WrapperPlayClientPlayerBlockPlacement(event).getFace() == BlockFace.OTHER) {
|
||||
using = true;
|
||||
} else {
|
||||
placing = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (packetType == PacketType.Play.Client.PICK_ITEM) {
|
||||
picking = true;
|
||||
}
|
||||
|
||||
if (packetType == PacketType.Play.Client.CLICK_WINDOW) {
|
||||
clickingInInventory = true;
|
||||
|
||||
switch (new WrapperPlayClientClickWindow(event).getWindowClickType()) {
|
||||
case QUICK_MOVE:
|
||||
quickMoveClicking = true;
|
||||
break;
|
||||
case PICKUP:
|
||||
case PICKUP_ALL:
|
||||
pickUpClicking = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (packetType == PacketType.Play.Client.CLOSE_WINDOW) {
|
||||
closingInventory = true;
|
||||
}
|
||||
|
||||
if (WrapperPlayClientPlayerFlying.isFlying(event.getPacketType()) && player.getClientVersion().isOlderThanOrEquals(ClientVersion.V_1_8) && !player.packetStateData.lastPacketWasTeleport) {
|
||||
onTick();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPredictionComplete(PredictionComplete predictionComplete) {
|
||||
if (player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_9)) {
|
||||
onTick();
|
||||
}
|
||||
}
|
||||
|
||||
private void onTick() {
|
||||
openingInventory = false;
|
||||
swapping = false;
|
||||
dropping = false;
|
||||
attacking = false;
|
||||
interacting = false;
|
||||
releasing = false;
|
||||
digging = false;
|
||||
placing = false;
|
||||
using = false;
|
||||
picking = false;
|
||||
sprinting = false;
|
||||
sneaking = false;
|
||||
clickingInInventory = false;
|
||||
closingInventory = false;
|
||||
quickMoveClicking = false;
|
||||
pickUpClicking = false;
|
||||
leavingBed = false;
|
||||
startingToGlide = false;
|
||||
jumpingWithMount = false;
|
||||
}
|
||||
|
||||
@Contract(pure = true)
|
||||
public boolean isRightClicking() {
|
||||
return placing || using || interacting;
|
||||
}
|
||||
}
|
||||
+3
-2
@@ -2,6 +2,7 @@ package ac.grim.grimac.checks.impl.post;
|
||||
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.PacketCheck;
|
||||
import ac.grim.grimac.checks.type.PostPredictionCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.anticheat.update.PredictionComplete;
|
||||
@@ -24,7 +25,7 @@ import java.util.Locale;
|
||||
import static com.github.retrooper.packetevents.protocol.packettype.PacketType.Play.Client.*;
|
||||
|
||||
@CheckData(name = "Post")
|
||||
public class Post extends Check implements PostPredictionCheck {
|
||||
public class PostCheck extends Check implements PacketCheck, PostPredictionCheck {
|
||||
private final ArrayDeque<PacketTypeCommon> post = new ArrayDeque<>();
|
||||
// Due to 1.9+ missing the idle packet, we must queue flags
|
||||
// 1.8 clients will have the same logic for simplicity, although it's not needed
|
||||
@@ -32,7 +33,7 @@ public class Post extends Check implements PostPredictionCheck {
|
||||
private boolean sentFlying = false;
|
||||
private int isExemptFromSwingingCheck = Integer.MIN_VALUE;
|
||||
|
||||
public Post(GrimPlayer playerData) {
|
||||
public PostCheck(GrimPlayer playerData) {
|
||||
super(playerData);
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import ac.grim.grimac.utils.anticheat.update.PredictionComplete;
|
||||
import ac.grim.grimac.utils.lists.EvictingQueue;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.entity.Player;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
@@ -45,8 +45,8 @@ public class DebugHandler extends Check implements PostPredictionCheck {
|
||||
|
||||
ChatColor color = pickColor(offset, offset);
|
||||
|
||||
Vector3D predicted = player.predictedVelocity.vector;
|
||||
Vector3D actually = player.actualMovement;
|
||||
Vector predicted = player.predictedVelocity.vector;
|
||||
Vector actually = player.actualMovement;
|
||||
|
||||
ChatColor xColor = pickColor(Math.abs(predicted.getX() - actually.getX()), offset);
|
||||
ChatColor yColor = pickColor(Math.abs(predicted.getY() - actually.getY()), offset);
|
||||
|
||||
@@ -7,11 +7,11 @@ import ac.grim.grimac.utils.anticheat.update.BlockPlace;
|
||||
import ac.grim.grimac.utils.collisions.datatypes.SimpleCollisionBox;
|
||||
import ac.grim.grimac.utils.math.VectorUtils;
|
||||
import com.github.retrooper.packetevents.protocol.attribute.Attributes;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.protocol.player.GameMode;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.type.StateTypes;
|
||||
import com.github.retrooper.packetevents.util.Vector3i;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
|
||||
import static ac.grim.grimac.utils.vector.VectorFactory.newVector3D;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
@CheckData(name = "FarPlace")
|
||||
public class FarPlace extends BlockPlaceCheck {
|
||||
@@ -29,8 +29,8 @@ public class FarPlace extends BlockPlaceCheck {
|
||||
final double[] possibleEyeHeights = player.getPossibleEyeHeights();
|
||||
for (double d : possibleEyeHeights) {
|
||||
SimpleCollisionBox box = new SimpleCollisionBox(blockPos);
|
||||
Vector3D eyes = newVector3D(player.x, player.y + d, player.z);
|
||||
Vector3D best = VectorUtils.cutBoxToVector(eyes, box);
|
||||
Vector eyes = new Vector(player.x, player.y + d, player.z);
|
||||
Vector best = VectorUtils.cutBoxToVector(eyes, box);
|
||||
min = Math.min(min, eyes.distanceSquared(best));
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@ import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.BlockPlaceCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.anticheat.update.BlockPlace;
|
||||
import ac.grim.grimac.utils.collisions.HitboxData;
|
||||
import ac.grim.grimac.utils.collisions.RaycastData;
|
||||
import ac.grim.grimac.utils.collisions.datatypes.SimpleCollisionBox;
|
||||
import ac.grim.grimac.utils.data.HitData;
|
||||
import ac.grim.grimac.utils.nmsutil.BlockRayTrace;
|
||||
@@ -12,15 +14,13 @@ import com.github.retrooper.packetevents.protocol.attribute.Attributes;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.protocol.player.GameMode;
|
||||
import com.github.retrooper.packetevents.protocol.world.BlockFace;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.WrappedBlockState;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.type.StateType;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.type.StateTypes;
|
||||
import com.github.retrooper.packetevents.util.Vector3d;
|
||||
import com.github.retrooper.packetevents.util.Vector3i;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@CheckData(name = "LineOfSightPlace")
|
||||
public class LineOfSightPlace extends BlockPlaceCheck {
|
||||
@@ -30,13 +30,6 @@ public class LineOfSightPlace extends BlockPlaceCheck {
|
||||
private boolean useBlockWhitelist;
|
||||
private HashSet<StateType> blockWhitelist;
|
||||
|
||||
// 15 is the maximum set of Collision boxes that will be used in the ray trace check
|
||||
// it corresponds to the size of the collision boxes from the modern Cauldron
|
||||
// Since this is used per-player we can avoid calling new[] by allocating it per-player in the check
|
||||
private final SimpleCollisionBox[] collisionBoxBuffer = new SimpleCollisionBox[15];
|
||||
|
||||
public final ConcurrentHashMap<Vector3i, WrappedBlockState> blocksChangedList = new ConcurrentHashMap<>();
|
||||
|
||||
public LineOfSightPlace(GrimPlayer player) {
|
||||
super(player);
|
||||
}
|
||||
@@ -45,17 +38,9 @@ public class LineOfSightPlace extends BlockPlaceCheck {
|
||||
public void onBlockPlace(final BlockPlace place) {
|
||||
if (checkIfShouldSkip(place)) return;
|
||||
|
||||
// if (flagBuffer > 0 && !didRayTraceHit(place)) {
|
||||
// ignorePost = true;
|
||||
// // If the player hit and has flagged this check recently
|
||||
// if (flagAndAlert("pre-flying: " + player.compensatedWorld.getWrappedBlockStateAt(place.getPlacedAgainstBlockLocation()).getType()) && shouldModifyPackets() && shouldCancel()) {
|
||||
// place.resync(); // Deny the block placement.
|
||||
// }
|
||||
// }
|
||||
// Only flag (which will only happen in post) if we miss pre
|
||||
if (didRayTraceHit(place)) {
|
||||
if (flagBuffer > 0 && !didRayTraceHit(place)) {
|
||||
ignorePost = true;
|
||||
} else if (flagBuffer > 0) {
|
||||
// If the player hit and has flagged this check recently
|
||||
if (flagAndAlert("pre-flying: " + player.compensatedWorld.getWrappedBlockStateAt(place.getPlacedAgainstBlockLocation()).getType()) && shouldModifyPackets() && shouldCancel()) {
|
||||
place.resync(); // Deny the block placement.
|
||||
}
|
||||
@@ -72,15 +57,14 @@ public class LineOfSightPlace extends BlockPlaceCheck {
|
||||
ignorePost = false;
|
||||
return;
|
||||
}
|
||||
blocksChangedList.clear();
|
||||
|
||||
// Ray trace to try and hit the target block.
|
||||
boolean hit = didRayTraceHit(place);
|
||||
// This can false with rapidly moving yaw in 1.8+ clients
|
||||
if (!hit) {
|
||||
flagBuffer = 1;
|
||||
flagAndAlert("post-flying: " + player.compensatedWorld.getWrappedBlockStateAt(place.getPlacedAgainstBlockLocation()).getType());
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
flagBuffer = Math.max(0, flagBuffer - 0.1);
|
||||
}
|
||||
}
|
||||
@@ -97,16 +81,6 @@ public class LineOfSightPlace extends BlockPlaceCheck {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void handleBlockChange(Vector3i vector3i, WrappedBlockState state) {
|
||||
if (blocksChangedList.size() >= 60) return; // Don't let players freeze movement packets to grow this
|
||||
// Only do this for nearby blocks
|
||||
if (new Vector3d(vector3i.x, vector3i.y, vector3i.z).distanceSquared(new Vector3d(player.x, player.y, player.z)) > 36) return;
|
||||
// Only do this if the state really had any world impact
|
||||
// this line always just returns the current world state in compensatedWorld
|
||||
// if (state.equals(player.compensatedWorld.getWrappedBlockStateAt(vector3i))) return;
|
||||
blocksChangedList.put(vector3i, state);
|
||||
}
|
||||
|
||||
private boolean didRayTraceHit(BlockPlace place) {
|
||||
double[] possibleEyeHeights = player.getPossibleEyeHeights();
|
||||
|
||||
@@ -178,7 +152,7 @@ public class LineOfSightPlace extends BlockPlaceCheck {
|
||||
|
||||
calculateDirection(eyeLookDir, lookDir[0], lookDir[1]);
|
||||
|
||||
if (didRayTraceHitTargetBlock(eyePosition, eyeLookDir, maxDistance, interactBlockVec, expectedBlockFace)) {
|
||||
if (getTargetBlock(eyePosition, eyeLookDir, maxDistance, interactBlockVec, expectedBlockFace)) {
|
||||
return true; // If any possible face matches the client-side placement, assume it's legitimate
|
||||
}
|
||||
}
|
||||
@@ -198,14 +172,12 @@ public class LineOfSightPlace extends BlockPlaceCheck {
|
||||
result[2] = xz * player.trigHandler.cos(rotX);
|
||||
}
|
||||
|
||||
private boolean didRayTraceHitTargetBlock(double[] eyePos, double[] eyeDir, double maxDistance, int[] targetBlockVec, BlockFace expectedBlockFace) {
|
||||
HitData hitData = BlockRayTrace.getNearestReachHitResult(player, eyePos, eyeDir, maxDistance, maxDistance, targetBlockVec, expectedBlockFace, collisionBoxBuffer, null, false);
|
||||
if (hitData == null || !hitData.success)
|
||||
hitData = BlockRayTrace.getNearestReachHitResult(player, eyePos, eyeDir, maxDistance, maxDistance, targetBlockVec,
|
||||
expectedBlockFace, collisionBoxBuffer, player.checkManager.getBlockPlaceCheck(LineOfSightPlace.class).blocksChangedList, false);
|
||||
private boolean getTargetBlock(double[] eyePos, double[] eyeDir, double maxDistance, int[] targetBlockVec, BlockFace expectedBlockFace) {
|
||||
HitData hitData = BlockRayTrace.getNearestReachHitResult(player, eyePos, eyeDir, maxDistance, maxDistance, targetBlockVec, false);
|
||||
|
||||
|
||||
// we check for hitdata != null because of being in expanded hitbox, or there was no result, do we still need this?
|
||||
return hitData != null && hitData.success;
|
||||
return hitData != null && new Vector3i(targetBlockVec[0], targetBlockVec[1], targetBlockVec[2]).equals(hitData.getPosition()) && hitData.getClosestDirection() == expectedBlockFace;
|
||||
}
|
||||
|
||||
private boolean isBlockTypeWhitelisted(StateType type) {
|
||||
|
||||
@@ -63,7 +63,7 @@ public class MultiPlace extends BlockPlaceCheck {
|
||||
|
||||
@Override
|
||||
public void onPredictionComplete(PredictionComplete predictionComplete) {
|
||||
if (player.getClientVersion().isNewerThan(ClientVersion.V_1_8) && player.isTickingReliablyFor(3)) {
|
||||
if (player.getClientVersion().isNewerThan(ClientVersion.V_1_8) && !player.skippedTickInActualMovement && predictionComplete.isChecked()) {
|
||||
for (String verbose : flags) {
|
||||
flagAndAlert(verbose);
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import ac.grim.grimac.utils.collisions.datatypes.SimpleCollisionBox;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.type.StateTypes;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
@CheckData(name = "PositionPlace")
|
||||
public class PositionPlace extends BlockPlaceCheck {
|
||||
|
||||
@@ -19,14 +19,12 @@ import com.github.retrooper.packetevents.util.Vector3f;
|
||||
import com.github.retrooper.packetevents.util.Vector3i;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerExplosion;
|
||||
import lombok.Getter;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Deque;
|
||||
import java.util.LinkedList;
|
||||
|
||||
import static ac.grim.grimac.utils.vector.VectorFactory.newVector3D;
|
||||
|
||||
@CheckData(name = "AntiExplosion", configName = "Explosion", setback = 10)
|
||||
public class ExplosionHandler extends Check implements PostPredictionCheck {
|
||||
Deque<VelocityData> firstBreadMap = new LinkedList<>();
|
||||
@@ -123,7 +121,7 @@ public class ExplosionHandler extends Check implements PostPredictionCheck {
|
||||
}
|
||||
|
||||
public void addPlayerExplosion(int breadOne, Vector3f explosion) {
|
||||
firstBreadMap.add(new VelocityData(-1, breadOne, player.getSetbackTeleportUtil().isSendingSetback, newVector3D(explosion.getX(), explosion.getY(), explosion.getZ())));
|
||||
firstBreadMap.add(new VelocityData(-1, breadOne, player.getSetbackTeleportUtil().isSendingSetback, new Vector(explosion.getX(), explosion.getY(), explosion.getZ())));
|
||||
}
|
||||
|
||||
public void setPointThree(boolean isPointThree) {
|
||||
|
||||
@@ -15,14 +15,12 @@ import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.util.Vector3d;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityVelocity;
|
||||
import lombok.Getter;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Deque;
|
||||
import java.util.LinkedList;
|
||||
|
||||
import static ac.grim.grimac.utils.vector.VectorFactory.newVector3D;
|
||||
|
||||
// We are making a velocity sandwich between two pieces of transaction packets (bread)
|
||||
@CheckData(name = "AntiKB", alternativeName = "AntiKnockback", configName = "Knockback", setback = 10, decay = 0.025)
|
||||
public class KnockbackHandler extends Check implements PostPredictionCheck {
|
||||
@@ -72,12 +70,12 @@ public class KnockbackHandler extends Check implements PostPredictionCheck {
|
||||
|
||||
// Wrap velocity between two transactions
|
||||
player.sendTransaction();
|
||||
addPlayerKnockback(entityId, player.lastTransactionSent.get(), newVector3D(playerVelocity.getX(), playerVelocity.getY(), playerVelocity.getZ()));
|
||||
addPlayerKnockback(entityId, player.lastTransactionSent.get(), new Vector(playerVelocity.getX(), playerVelocity.getY(), playerVelocity.getZ()));
|
||||
event.getTasksAfterSend().add(player::sendTransaction);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull public Pair<VelocityData, Vector3D> getFutureKnockback() {
|
||||
@NotNull public Pair<VelocityData, Vector> getFutureKnockback() {
|
||||
// Chronologically in the future
|
||||
if (firstBreadMap.size() > 0) {
|
||||
VelocityData data = firstBreadMap.peek();
|
||||
@@ -99,7 +97,7 @@ public class KnockbackHandler extends Check implements PostPredictionCheck {
|
||||
return new Pair<>(null, null);
|
||||
}
|
||||
|
||||
private void addPlayerKnockback(int entityID, int breadOne, Vector3D knockback) {
|
||||
private void addPlayerKnockback(int entityID, int breadOne, Vector knockback) {
|
||||
firstBreadMap.add(new VelocityData(entityID, breadOne, player.getSetbackTeleportUtil().isSendingSetback, knockback));
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@ import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.anticheat.update.BlockPlace;
|
||||
import ac.grim.grimac.utils.collisions.HitboxData;
|
||||
import ac.grim.grimac.utils.collisions.datatypes.CollisionBox;
|
||||
import ac.grim.grimac.utils.collisions.datatypes.ComplexCollisionBox;
|
||||
import ac.grim.grimac.utils.collisions.datatypes.SimpleCollisionBox;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.defaulttags.BlockTags;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.type.StateType;
|
||||
@@ -19,7 +18,6 @@ import java.util.List;
|
||||
public class BlockPlaceCheck extends Check implements RotationCheck, PostPredictionCheck {
|
||||
private static final List<StateType> weirdBoxes = new ArrayList<>();
|
||||
private static final List<StateType> buggyBoxes = new ArrayList<>();
|
||||
private final SimpleCollisionBox[] boxes = new SimpleCollisionBox[ComplexCollisionBox.DEFAULT_MAX_COLLISION_BOX_SIZE];
|
||||
|
||||
protected int cancelVL;
|
||||
|
||||
@@ -71,11 +69,11 @@ public class BlockPlaceCheck extends Check implements RotationCheck, PostPredict
|
||||
Vector3i clicked = place.getPlacedAgainstBlockLocation();
|
||||
CollisionBox placedOn = HitboxData.getBlockHitbox(player, place.getMaterial(), player.getClientVersion(), player.compensatedWorld.getWrappedBlockStateAt(clicked), clicked.getX(), clicked.getY(), clicked.getZ());
|
||||
|
||||
int size = placedOn.downCast(boxes);
|
||||
List<SimpleCollisionBox> boxes = new ArrayList<>();
|
||||
placedOn.downCast(boxes);
|
||||
|
||||
SimpleCollisionBox combined = new SimpleCollisionBox(clicked.getX(), clicked.getY(), clicked.getZ());
|
||||
for (int i = 0; i < size; i++) {
|
||||
SimpleCollisionBox box = boxes[i];
|
||||
for (SimpleCollisionBox box : boxes) {
|
||||
double minX = Math.max(box.minX, combined.minX);
|
||||
double minY = Math.max(box.minY, combined.minY);
|
||||
double minZ = Math.max(box.minZ, combined.minZ);
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
package ac.grim.grimac.checks.type;
|
||||
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientCloseWindow;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerCloseWindow;
|
||||
import org.jetbrains.annotations.MustBeInvokedByOverriders;
|
||||
|
||||
public class InventoryCheck extends BlockPlaceCheck implements PacketCheck {
|
||||
// Impossible transaction ID
|
||||
protected static final long NONE = Long.MAX_VALUE;
|
||||
|
||||
protected long closeTransaction = NONE;
|
||||
protected int closePacketsToSkip;
|
||||
|
||||
public InventoryCheck(GrimPlayer player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
@MustBeInvokedByOverriders
|
||||
public void onPacketReceive(final PacketReceiveEvent event) {
|
||||
if (event.getPacketType() == PacketType.Play.Client.CLICK_WINDOW) {
|
||||
// Disallow any clicks if inventory is closing
|
||||
if (closeTransaction != NONE && shouldModifyPackets()) {
|
||||
event.setCancelled(true);
|
||||
player.onPacketCancel();
|
||||
player.getInventory().needResend = true;
|
||||
}
|
||||
} else if (event.getPacketType() == PacketType.Play.Client.CLOSE_WINDOW) {
|
||||
// Players with high ping can close inventory faster than send transaction back
|
||||
if (closeTransaction != NONE && closePacketsToSkip-- <= 0) {
|
||||
closeTransaction = NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void closeInventory() {
|
||||
if (closeTransaction != NONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
int windowId = player.getInventory().openWindowID;
|
||||
|
||||
player.user.writePacket(new WrapperPlayServerCloseWindow(windowId));
|
||||
|
||||
// Force close inventory on server side
|
||||
closePacketsToSkip = 1; // Sending close packet to itself, so skip it
|
||||
PacketEvents.getAPI().getProtocolManager().receivePacket(
|
||||
player.user.getChannel(), new WrapperPlayClientCloseWindow(windowId)
|
||||
);
|
||||
|
||||
player.sendTransaction();
|
||||
|
||||
int transaction = player.lastTransactionSent.get();
|
||||
closeTransaction = transaction;
|
||||
player.latencyUtils.addRealTimeTask(transaction, () -> {
|
||||
if (closeTransaction == transaction) {
|
||||
closeTransaction = NONE;
|
||||
}
|
||||
});
|
||||
|
||||
player.user.flushPackets();
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
package ac.grim.grimac.checks.type;
|
||||
|
||||
import ac.grim.grimac.api.AbstractCheck;
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.anticheat.update.RotationUpdate;
|
||||
|
||||
public interface RotationCheck extends AbstractCheck {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package ac.grim.grimac.checks.type;
|
||||
|
||||
import ac.grim.grimac.api.AbstractCheck;
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.anticheat.update.VehiclePositionUpdate;
|
||||
|
||||
public interface VehicleCheck extends AbstractCheck {
|
||||
|
||||
@@ -70,4 +70,4 @@ public class GrimDebug extends BaseCommand {
|
||||
|
||||
sender.sendMessage("Console output for " + (grimPlayer.bukkitPlayer == null ? grimPlayer.user.getProfile().getName() : grimPlayer.bukkitPlayer.getName()) + " is now " + isOutput);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,12 @@
|
||||
package ac.grim.grimac.commands;
|
||||
|
||||
import ac.grim.grimac.GrimAPI;
|
||||
import ac.grim.grimac.checks.impl.aim.processor.AimProcessor;
|
||||
import ac.grim.grimac.checks.impl.misc.ClientBrand;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.anticheat.MessageUtil;
|
||||
import ac.grim.grimac.utils.anticheat.MultiLibUtil;
|
||||
import ac.grim.grimac.utils.math.GrimMath;
|
||||
import co.aikar.commands.BaseCommand;
|
||||
import co.aikar.commands.annotation.CommandAlias;
|
||||
import co.aikar.commands.annotation.CommandCompletion;
|
||||
|
||||
@@ -20,7 +20,7 @@ public class GrimSendAlert extends BaseCommand {
|
||||
bukkitPlayer.sendMessage(string);
|
||||
}
|
||||
|
||||
if (GrimAPI.INSTANCE.getConfigManager().isPrintAlertsToConsole()) {
|
||||
if (GrimAPI.INSTANCE.getConfigManager().getConfig().getBooleanElse("alerts.print-to-console", true)) {
|
||||
LogUtil.console(string); // Print alert to console
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,3 +28,4 @@ public class GrimStopSpectating extends BaseCommand {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package ac.grim.grimac.events.packets;
|
||||
import ac.grim.grimac.GrimAPI;
|
||||
import ac.grim.grimac.checks.impl.badpackets.BadPacketsX;
|
||||
import ac.grim.grimac.checks.impl.badpackets.BadPacketsZ;
|
||||
import ac.grim.grimac.checks.impl.inventory.InventoryB;
|
||||
import ac.grim.grimac.events.packets.patch.ResyncWorldUtil;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.anticheat.update.*;
|
||||
@@ -32,6 +31,7 @@ import com.github.retrooper.packetevents.protocol.player.InteractionHand;
|
||||
import com.github.retrooper.packetevents.protocol.world.BlockFace;
|
||||
import com.github.retrooper.packetevents.protocol.world.Location;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.WrappedBlockState;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.defaulttags.BlockTags;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.type.StateType;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.type.StateTypes;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.type.StateValue;
|
||||
@@ -44,8 +44,6 @@ import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerAc
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSetSlot;
|
||||
import io.github.retrooper.packetevents.util.SpigotConversionUtil;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
public class CheckManagerListener extends PacketListenerAbstract {
|
||||
|
||||
public CheckManagerListener() {
|
||||
@@ -146,7 +144,7 @@ public class CheckManagerListener extends PacketListenerAbstract {
|
||||
}
|
||||
}
|
||||
|
||||
private static void handleBlockPlaceOrUseItem(PacketWrapper<?> packet, GrimPlayer player) {
|
||||
private static void handleBlockPlaceOrUseItem(PacketWrapper packet, GrimPlayer player) {
|
||||
// Legacy "use item" packet
|
||||
if (packet instanceof WrapperPlayClientPlayerBlockPlacement &&
|
||||
PacketEvents.getAPI().getServerManager().getVersion().isOlderThan(ServerVersion.V_1_9)) {
|
||||
@@ -270,7 +268,7 @@ public class CheckManagerListener extends PacketListenerAbstract {
|
||||
// Additionally, only yaw/pitch matters: https://github.com/GrimAnticheat/Grim/issues/1275#issuecomment-1872444018
|
||||
// 1.9+ isn't impacted by this packet as much.
|
||||
if (PacketEvents.getAPI().getServerManager().getVersion().isOlderThanOrEquals(ServerVersion.V_1_9)) {
|
||||
if (player.isCancelDuplicatePacket()) {
|
||||
if (GrimAPI.INSTANCE.getConfigManager().getConfig().getBooleanElse("cancel-duplicate-packet", true)) {
|
||||
player.packetStateData.cancelDuplicatePacket = true;
|
||||
}
|
||||
} else {
|
||||
@@ -280,7 +278,7 @@ public class CheckManagerListener extends PacketListenerAbstract {
|
||||
|
||||
player.packetStateData.lastPacketWasOnePointSeventeenDuplicate = true;
|
||||
|
||||
if (!player.isIgnoreDuplicatePacketRotation()) {
|
||||
if (!GrimAPI.INSTANCE.getConfigManager().isIgnoreDuplicatePacketRotation()) {
|
||||
if (player.xRot != location.getYaw() || player.yRot != location.getPitch()) {
|
||||
player.lastXRot = player.xRot;
|
||||
player.lastYRot = player.yRot;
|
||||
@@ -297,11 +295,6 @@ public class CheckManagerListener extends PacketListenerAbstract {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Manual filter on FINISH_DIGGING to prevent clients setting non-breakable blocks to air
|
||||
private static final Function<StateType, Boolean> BREAKABLE = type -> {
|
||||
return !type.isAir() && type.getHardness() != -1.0f && type != StateTypes.WATER && type != StateTypes.LAVA;
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onPacketReceive(PacketReceiveEvent event) {
|
||||
if (event.getConnectionState() != ConnectionState.PLAY) return;
|
||||
@@ -355,7 +348,7 @@ public class CheckManagerListener extends PacketListenerAbstract {
|
||||
if (WrapperPlayClientPlayerFlying.isFlying(event.getPacketType())) {
|
||||
WrapperPlayClientPlayerFlying flying = new WrapperPlayClientPlayerFlying(event);
|
||||
Location pos = flying.getLocation();
|
||||
boolean ignoreRotation = player.packetStateData.lastPacketWasOnePointSeventeenDuplicate && player.isIgnoreDuplicatePacketRotation();
|
||||
boolean ignoreRotation = player.packetStateData.lastPacketWasOnePointSeventeenDuplicate && GrimAPI.INSTANCE.getConfigManager().isIgnoreDuplicatePacketRotation();
|
||||
handleFlying(player, pos.getX(), pos.getY(), pos.getZ(), ignoreRotation ? player.xRot : pos.getYaw(), ignoreRotation ? player.yRot : pos.getPitch(), flying.hasPositionChanged(), flying.hasRotationChanged(), flying.isOnGround(), teleportData, event);
|
||||
}
|
||||
|
||||
@@ -383,26 +376,22 @@ public class CheckManagerListener extends PacketListenerAbstract {
|
||||
|
||||
if (event.getPacketType() == PacketType.Play.Client.PLAYER_DIGGING) {
|
||||
WrapperPlayClientPlayerDigging dig = new WrapperPlayClientPlayerDigging(event);
|
||||
final Vector3i digPosition = dig.getBlockPosition();
|
||||
WrappedBlockState block = player.compensatedWorld.getWrappedBlockStateAt(digPosition);
|
||||
final StateType type = block.getType();
|
||||
WrappedBlockState block = player.compensatedWorld.getWrappedBlockStateAt(dig.getBlockPosition());
|
||||
|
||||
player.checkManager.getPacketCheck(InventoryB.class).handle(event, dig);
|
||||
|
||||
player.checkManager.getPacketCheck(BadPacketsX.class).handle(event, dig, type);
|
||||
player.checkManager.getPacketCheck(BadPacketsX.class).handle(event, dig, block.getType());
|
||||
player.checkManager.getPacketCheck(BadPacketsZ.class).handle(event, dig);
|
||||
|
||||
if (dig.getAction() == DiggingAction.FINISHED_DIGGING) {
|
||||
// Not unbreakable
|
||||
if (BREAKABLE.apply(type) && !event.isCancelled()) {
|
||||
if (!block.getType().isAir() && block.getType().getHardness() != -1.0f && !event.isCancelled()) {
|
||||
player.compensatedWorld.startPredicting();
|
||||
player.compensatedWorld.updateBlock(digPosition.getX(), digPosition.getY(), digPosition.getZ(), 0);
|
||||
player.compensatedWorld.updateBlock(dig.getBlockPosition().getX(), dig.getBlockPosition().getY(), dig.getBlockPosition().getZ(), 0);
|
||||
player.compensatedWorld.stopPredicting(dig);
|
||||
}
|
||||
}
|
||||
|
||||
if (dig.getAction() == DiggingAction.START_DIGGING && !event.isCancelled()) {
|
||||
double damage = BlockBreakSpeed.getBlockDamage(player, digPosition);
|
||||
double damage = BlockBreakSpeed.getBlockDamage(player, dig.getBlockPosition());
|
||||
|
||||
//Instant breaking, no damage means it is unbreakable by creative players (with swords)
|
||||
if (damage >= 1) {
|
||||
@@ -410,9 +399,9 @@ public class CheckManagerListener extends PacketListenerAbstract {
|
||||
if (player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_13) && Materials.isWaterSource(player.getClientVersion(), block)) {
|
||||
// Vanilla uses a method to grab water flowing, but as you can't break flowing water
|
||||
// We can simply treat all waterlogged blocks or source blocks as source blocks
|
||||
player.compensatedWorld.updateBlock(digPosition, StateTypes.WATER.createBlockState(CompensatedWorld.blockVersion));
|
||||
player.compensatedWorld.updateBlock(dig.getBlockPosition(), StateTypes.WATER.createBlockState(CompensatedWorld.blockVersion));
|
||||
} else {
|
||||
player.compensatedWorld.updateBlock(digPosition.getX(), digPosition.getY(), digPosition.getZ(), 0);
|
||||
player.compensatedWorld.updateBlock(dig.getBlockPosition().getX(), dig.getBlockPosition().getY(), dig.getBlockPosition().getZ(), 0);
|
||||
}
|
||||
player.compensatedWorld.stopPredicting(dig);
|
||||
}
|
||||
@@ -717,4 +706,8 @@ public class CheckManagerListener extends PacketListenerAbstract {
|
||||
|
||||
player.checkManager.onPacketSend(event);
|
||||
}
|
||||
|
||||
private static boolean isFence(StateType state) {
|
||||
return BlockTags.FENCES.contains(state);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,9 @@
|
||||
package ac.grim.grimac.events.packets;
|
||||
|
||||
import ac.grim.grimac.GrimAPI;
|
||||
import ac.grim.grimac.checks.impl.movement.NoSlowC;
|
||||
import ac.grim.grimac.checks.impl.movement.NoSlowD;
|
||||
import ac.grim.grimac.checks.impl.movement.NoSlowE;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import com.github.retrooper.packetevents.event.PacketListenerAbstract;
|
||||
import com.github.retrooper.packetevents.event.PacketListenerPriority;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package ac.grim.grimac.events.packets;
|
||||
|
||||
import ac.grim.grimac.api.config.ConfigManager;
|
||||
import ac.grim.grimac.GrimAPI;
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.checks.type.PacketCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
@@ -53,6 +53,7 @@ public class PacketEntityReplication extends Check implements PacketCheck {
|
||||
private final List<Integer> despawnedEntitiesThisTransaction = new ArrayList<>();
|
||||
|
||||
// Maximum ping when a firework boost is removed from the player.
|
||||
private final int maxFireworkBoostPing = GrimAPI.INSTANCE.getConfigManager().getConfig().getIntElse("max-ping-firework-boost", 1000);
|
||||
|
||||
public PacketEntityReplication(GrimPlayer player) {
|
||||
super(player);
|
||||
@@ -499,12 +500,4 @@ public class PacketEntityReplication extends Check implements PacketCheck {
|
||||
public void tickStartTick() {
|
||||
hasSentPreWavePacket = false;
|
||||
}
|
||||
|
||||
private int maxFireworkBoostPing = 1000;
|
||||
|
||||
@Override
|
||||
public void onReload(ConfigManager config) {
|
||||
maxFireworkBoostPing = config.getIntElse("max-ping-firework-boost", 1000);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package ac.grim.grimac.events.packets;
|
||||
|
||||
import ac.grim.grimac.api.config.ConfigManager;
|
||||
import ac.grim.grimac.GrimAPI;
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.checks.type.PacketCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
@@ -37,6 +37,7 @@ public class PacketPlayerAbilities extends Check implements PacketCheck {
|
||||
|
||||
if (lastSentPlayerCanFly && !abilities.isFlightAllowed()) {
|
||||
int noFlying = player.lastTransactionSent.get();
|
||||
int maxFlyingPing = GrimAPI.INSTANCE.getConfigManager().getConfig().getIntElse("max-ping-out-of-flying", 1000);
|
||||
if (maxFlyingPing != -1) {
|
||||
player.runNettyTaskInMs(() -> {
|
||||
if (player.lastTransactionReceived.get() < noFlying) {
|
||||
@@ -55,12 +56,4 @@ public class PacketPlayerAbilities extends Check implements PacketCheck {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
int maxFlyingPing = 1000;
|
||||
|
||||
@Override
|
||||
public void onReload(ConfigManager config) {
|
||||
maxFlyingPing = config.getIntElse("max-ping-out-of-flying", 1000);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,8 +8,6 @@ import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.event.PacketListenerAbstract;
|
||||
import com.github.retrooper.packetevents.event.PacketListenerPriority;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
||||
import com.github.retrooper.packetevents.protocol.attribute.Attributes;
|
||||
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
|
||||
import com.github.retrooper.packetevents.protocol.item.ItemStack;
|
||||
import com.github.retrooper.packetevents.protocol.item.enchantment.type.EnchantmentTypes;
|
||||
@@ -74,13 +72,6 @@ public class PacketPlayerAttack extends PacketListenerAbstract {
|
||||
player.maxPlayerAttackSlow = 1;
|
||||
}
|
||||
} else if (!isLegacyPlayer && player.isSprinting) {
|
||||
// 1.9+ players who have attack speed cannot slow themselves twice in one tick because their attack cooldown gets reset on swing.
|
||||
if (player.maxPlayerAttackSlow > 0
|
||||
&& PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_9)
|
||||
&& player.compensatedEntities.getSelf().getAttributeValue(Attributes.GENERIC_ATTACK_SPEED) < 16) { // 16 is a reasonable limit
|
||||
return;
|
||||
}
|
||||
|
||||
// 1.9+ player who might have been slowed, but we can't be sure
|
||||
player.maxPlayerAttackSlow += 1;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package ac.grim.grimac.events.packets;
|
||||
|
||||
import ac.grim.grimac.GrimAPI;
|
||||
import ac.grim.grimac.checks.impl.movement.NoSlowA;
|
||||
import ac.grim.grimac.checks.impl.movement.NoSlowD;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.event.PacketListenerAbstract;
|
||||
@@ -22,6 +23,7 @@ import com.github.retrooper.packetevents.protocol.player.GameMode;
|
||||
import com.github.retrooper.packetevents.protocol.player.InteractionHand;
|
||||
import com.github.retrooper.packetevents.protocol.world.BlockFace;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.*;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
public class PacketPlayerDigging extends PacketListenerAbstract {
|
||||
|
||||
@@ -170,12 +172,10 @@ public class PacketPlayerDigging extends PacketListenerAbstract {
|
||||
|
||||
if (WrapperPlayClientPlayerFlying.isFlying(event.getPacketType())) {
|
||||
final GrimPlayer player = GrimAPI.INSTANCE.getPlayerDataManager().getPlayer(event.getUser());
|
||||
if (player != null && player.packetStateData.isSlowedByUsingItem()
|
||||
&& !player.packetStateData.lastPacketWasTeleport
|
||||
&& !player.packetStateData.lastPacketWasOnePointSeventeenDuplicate) {
|
||||
if (player.packetStateData.eatingHand != InteractionHand.OFF_HAND
|
||||
&& player.packetStateData.getSlowedByUsingItemSlot() != player.packetStateData.lastSlotSelected
|
||||
|| player.getInventory().getItemInHand(player.packetStateData.eatingHand).isEmpty()) {
|
||||
if (player == null) return;
|
||||
|
||||
if (!player.packetStateData.lastPacketWasTeleport && !player.packetStateData.lastPacketWasOnePointSeventeenDuplicate) {
|
||||
if (player.packetStateData.isSlowedByUsingItem() && player.packetStateData.eatingHand != InteractionHand.OFF_HAND && player.packetStateData.getSlowedByUsingItemSlot() != player.packetStateData.lastSlotSelected) {
|
||||
player.packetStateData.setSlowedByUsingItem(false);
|
||||
player.checkManager.getPostPredictionCheck(NoSlowA.class).didSlotChangeLastTick = true;
|
||||
}
|
||||
@@ -220,7 +220,13 @@ public class PacketPlayerDigging extends PacketListenerAbstract {
|
||||
final ItemStack item = hand == InteractionHand.MAIN_HAND ?
|
||||
player.getInventory().getHeldItem() : player.getInventory().getOffHand();
|
||||
|
||||
final boolean wasSlow = player.packetStateData.isSlowedByUsingItem();
|
||||
|
||||
handleUseItem(player, item, hand);
|
||||
|
||||
if (!wasSlow) {
|
||||
player.checkManager.getPostPredictionCheck(NoSlowD.class).startedSprintingBeforeUse = player.packetStateData.isSlowedByUsingItem() && player.isSprinting;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,13 +19,11 @@ import com.github.retrooper.packetevents.util.Vector3d;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerJoinGame;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerRespawn;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerUpdateHealth;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import static ac.grim.grimac.utils.vector.VectorFactory.newVector3D;
|
||||
|
||||
/**
|
||||
* PlayerRespawnS2CPacket info (1.20.2+):
|
||||
* If the world is different (check via registry key), world is recreated (all entities etc destroyed).
|
||||
@@ -187,7 +185,7 @@ public class PacketPlayerRespawn extends PacketListenerAbstract {
|
||||
player.compensatedEntities.hasSprintingAttributeEnabled = false;
|
||||
}
|
||||
player.pose = Pose.STANDING;
|
||||
player.clientVelocity = newVector3D();
|
||||
player.clientVelocity = new Vector();
|
||||
player.gamemode = respawn.getGameMode();
|
||||
if (PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_17)) {
|
||||
player.compensatedWorld.setDimension(respawn.getDimensionType(), event.getUser());
|
||||
|
||||
@@ -10,6 +10,7 @@ import com.github.retrooper.packetevents.event.PacketListenerAbstract;
|
||||
import com.github.retrooper.packetevents.event.PacketListenerPriority;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
||||
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientSteerVehicle;
|
||||
|
||||
@@ -1,165 +0,0 @@
|
||||
package ac.grim.grimac.events.packets;
|
||||
|
||||
import ac.grim.grimac.GrimAPI;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.data.packetentity.PacketEntitySelf;
|
||||
import ac.grim.grimac.utils.inventory.InventoryDesyncStatus;
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.event.PacketListenerAbstract;
|
||||
import com.github.retrooper.packetevents.event.PacketListenerPriority;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.event.PacketSendEvent;
|
||||
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientClientStatus;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientClientStatus.Action;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerFlying;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerOpenWindow;
|
||||
|
||||
public class PacketPlayerWindow extends PacketListenerAbstract {
|
||||
|
||||
public PacketPlayerWindow() {
|
||||
super(PacketListenerPriority.LOWEST);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPacketReceive(PacketReceiveEvent event) {
|
||||
if (WrapperPlayClientPlayerFlying.isFlying(event.getPacketType()) && !event.isCancelled()) {
|
||||
GrimPlayer player = GrimAPI.INSTANCE.getPlayerDataManager().getPlayer(event.getUser());
|
||||
if (player == null) return;
|
||||
|
||||
if (player.hasInventoryOpen && isNearNetherPortal(player)) {
|
||||
handleInventoryClose(player, InventoryDesyncStatus.NETHER_PORTAL);
|
||||
}
|
||||
}
|
||||
|
||||
// Client Status is sent in 1.7-1.8
|
||||
if (event.getPacketType() == PacketType.Play.Client.CLIENT_STATUS) {
|
||||
WrapperPlayClientClientStatus wrapper = new WrapperPlayClientClientStatus(event);
|
||||
|
||||
if (wrapper.getAction() == Action.OPEN_INVENTORY_ACHIEVEMENT) {
|
||||
GrimPlayer player = GrimAPI.INSTANCE.getPlayerDataManager().getPlayer(event.getUser());
|
||||
if (player == null) return;
|
||||
|
||||
handleInventoryOpen(player);
|
||||
}
|
||||
}
|
||||
|
||||
// We need to do this due to 1.9 not sending anymore the inventory action in the Client Status
|
||||
if (event.getPacketType() == PacketType.Play.Client.CLICK_WINDOW) {
|
||||
GrimPlayer player = GrimAPI.INSTANCE.getPlayerDataManager().getPlayer(event.getUser());
|
||||
if (player == null) return;
|
||||
|
||||
// TODO: Remove this check after we finish the before ViaVersion injection
|
||||
// Explanation: On 1.7 and 1.8 we have OPEN_INVENTORY_ACHIEVEMENT on CLIENT_STATUS packet
|
||||
// but after Via translation this information gets lost
|
||||
// This is a workaround to atleast make our inventory checks work "decently" in 1.8 clients for 1.9+ servers
|
||||
if (PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_9)
|
||||
&& player.getClientVersion().isOlderThanOrEquals(ClientVersion.V_1_8)) {
|
||||
handleInventoryOpen(player);
|
||||
}
|
||||
|
||||
if (player.getClientVersion().isNewerThan(ClientVersion.V_1_8)) {
|
||||
handleInventoryOpen(player);
|
||||
}
|
||||
}
|
||||
|
||||
if (event.getPacketType() == PacketType.Play.Client.CLOSE_WINDOW) {
|
||||
GrimPlayer player = GrimAPI.INSTANCE.getPlayerDataManager().getPlayer(event.getUser());
|
||||
if (player == null) return;
|
||||
|
||||
handleInventoryClose(player, InventoryDesyncStatus.NOT_DESYNCED);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPacketSend(PacketSendEvent event) {
|
||||
if (event.getPacketType() == PacketType.Play.Server.RESPAWN) {
|
||||
GrimPlayer player = GrimAPI.INSTANCE.getPlayerDataManager().getPlayer(event.getUser());
|
||||
if (player == null) return;
|
||||
|
||||
player.sendTransaction();
|
||||
|
||||
player.latencyUtils.addRealTimeTask(player.lastTransactionSent.get(),
|
||||
() -> handleInventoryClose(player, InventoryDesyncStatus.NOT_DESYNCED));
|
||||
} else if (event.getPacketType() == PacketType.Play.Server.OPEN_WINDOW) {
|
||||
WrapperPlayServerOpenWindow wrapper = new WrapperPlayServerOpenWindow(event);
|
||||
|
||||
GrimPlayer player = GrimAPI.INSTANCE.getPlayerDataManager().getPlayer(event.getUser());
|
||||
if (player == null) return;
|
||||
|
||||
player.sendTransaction();
|
||||
|
||||
String legacyType = wrapper.getLegacyType();
|
||||
int modernType = wrapper.getType();
|
||||
InventoryDesyncStatus inventoryDesyncStatus = getContainerDesyncStatus(player, legacyType, modernType);
|
||||
|
||||
player.latencyUtils.addRealTimeTask(player.lastTransactionSent.get(),
|
||||
() -> {
|
||||
if (inventoryDesyncStatus == InventoryDesyncStatus.NOT_DESYNCED) {
|
||||
handleInventoryOpen(player);
|
||||
} else {
|
||||
handleInventoryClose(player, inventoryDesyncStatus);
|
||||
}
|
||||
});
|
||||
} else if (event.getPacketType() == PacketType.Play.Server.OPEN_HORSE_WINDOW) {
|
||||
GrimPlayer player = GrimAPI.INSTANCE.getPlayerDataManager().getPlayer(event.getUser());
|
||||
if (player == null) return;
|
||||
|
||||
player.sendTransaction();
|
||||
|
||||
player.latencyUtils.addRealTimeTask(player.lastTransactionSent.get(),
|
||||
() -> handleInventoryOpen(player));
|
||||
} else if (event.getPacketType() == PacketType.Play.Server.CLOSE_WINDOW) {
|
||||
GrimPlayer player = GrimAPI.INSTANCE.getPlayerDataManager().getPlayer(event.getUser());
|
||||
if (player == null) return;
|
||||
|
||||
player.sendTransaction();
|
||||
|
||||
player.latencyUtils.addRealTimeTask(player.lastTransactionSent.get(),
|
||||
() -> handleInventoryClose(player, InventoryDesyncStatus.NOT_DESYNCED));
|
||||
}
|
||||
}
|
||||
|
||||
private void handleInventoryOpen(GrimPlayer player) {
|
||||
if (!player.hasInventoryOpen) {
|
||||
player.lastInventoryOpen = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
player.hasInventoryOpen = true;
|
||||
}
|
||||
|
||||
private void handleInventoryClose(GrimPlayer player, InventoryDesyncStatus desyncStatus) {
|
||||
player.hasInventoryOpen = false;
|
||||
player.inventoryDesyncStatus = desyncStatus;
|
||||
}
|
||||
|
||||
public InventoryDesyncStatus getContainerDesyncStatus(GrimPlayer player, String legacyType, int modernType) {
|
||||
// Closing beacon with the cross button cause desync in 1.7-1.8
|
||||
if (player.getClientVersion().isOlderThanOrEquals(ClientVersion.V_1_8) &&
|
||||
("minecraft:beacon".equals(legacyType) || modernType == 8)) {
|
||||
return player.inventoryDesyncStatus = InventoryDesyncStatus.BEACON;
|
||||
}
|
||||
|
||||
if (isNearNetherPortal(player)) {
|
||||
return player.inventoryDesyncStatus = InventoryDesyncStatus.NETHER_PORTAL;
|
||||
}
|
||||
|
||||
return player.inventoryDesyncStatus = InventoryDesyncStatus.NOT_DESYNCED;
|
||||
}
|
||||
|
||||
public boolean isNearNetherPortal(GrimPlayer player) {
|
||||
// Going inside nether portal with opened inventory cause desync, fixed in 1.12.2
|
||||
if (player.getClientVersion().isOlderThanOrEquals(ClientVersion.V_1_12_1) &&
|
||||
player.pointThreeEstimator.isNearNetherPortal) {
|
||||
PacketEntitySelf playerEntity = player.compensatedEntities.getSelf();
|
||||
// Client ignore nether portal if player has passengers or riding an entity
|
||||
if (!playerEntity.inVehicle() && playerEntity.passengers.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package ac.grim.grimac.events.packets;
|
||||
|
||||
import ac.grim.grimac.GrimAPI;
|
||||
import ac.grim.grimac.checks.impl.movement.NoSlowD;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.nmsutil.WatchableIndexUtil;
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
@@ -23,7 +24,6 @@ import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public class PacketSelfMetadataListener extends PacketListenerAbstract {
|
||||
|
||||
public PacketSelfMetadataListener() {
|
||||
super(PacketListenerPriority.HIGH);
|
||||
}
|
||||
@@ -68,7 +68,6 @@ public class PacketSelfMetadataListener extends PacketListenerAbstract {
|
||||
// Remove the pose metadata from the list
|
||||
metadataStuff.removeIf(element -> element.getIndex() == 6);
|
||||
entityMetadata.setEntityMetadata(metadataStuff);
|
||||
event.markForReEncode(true);
|
||||
}
|
||||
|
||||
EntityData watchable = WatchableIndexUtil.getIndex(entityMetadata.getEntityMetadata(), 0);
|
||||
@@ -208,6 +207,8 @@ public class PacketSelfMetadataListener extends PacketListenerAbstract {
|
||||
// The above line is a hack to fake activate use item
|
||||
player.packetStateData.setSlowedByUsingItem(isActive);
|
||||
|
||||
player.checkManager.getPostPredictionCheck(NoSlowD.class).startedSprintingBeforeUse = player.packetStateData.isSlowedByUsingItem() && player.isSprinting;
|
||||
|
||||
if (isActive) {
|
||||
player.packetStateData.eatingHand = isOffhand ? InteractionHand.OFF_HAND : InteractionHand.MAIN_HAND;
|
||||
}
|
||||
|
||||
@@ -6,12 +6,14 @@ import ac.grim.grimac.utils.data.Pair;
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.event.PacketListenerAbstract;
|
||||
import com.github.retrooper.packetevents.event.PacketListenerPriority;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.event.PacketSendEvent;
|
||||
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.protocol.teleport.RelativeFlag;
|
||||
import com.github.retrooper.packetevents.util.Vector3d;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientTeleportConfirm;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPlayerPositionAndLook;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerVehicleMove;
|
||||
import org.bukkit.Location;
|
||||
|
||||
+34
-15
@@ -5,11 +5,14 @@ import ac.grim.grimac.player.GrimPlayer;
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.event.PacketListenerAbstract;
|
||||
import com.github.retrooper.packetevents.event.PacketListenerPriority;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.event.PacketSendEvent;
|
||||
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketTypeCommon;
|
||||
import com.github.retrooper.packetevents.protocol.player.GameMode;
|
||||
import com.github.retrooper.packetevents.protocol.player.UserProfile;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerFlying;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityMetadata;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPlayerInfo;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPlayerInfoUpdate;
|
||||
|
||||
@@ -17,15 +20,22 @@ import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
|
||||
public class PacketHidePlayerInfo extends PacketListenerAbstract {
|
||||
|
||||
public PacketHidePlayerInfo() {
|
||||
public class PacketSetWrapperNull extends PacketListenerAbstract {
|
||||
// It's faster (and less buggy) to simply not re-encode the wrapper unless we changed something
|
||||
// The two packets we change are clientbound entity metadata (to fix a netcode issue)
|
||||
// and the serverbound player flying packets (to patch NoFall)
|
||||
public PacketSetWrapperNull() {
|
||||
super(PacketListenerPriority.HIGHEST);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPacketSend(PacketSendEvent event) {
|
||||
if (event.getPacketType() == PacketType.Play.Server.PLAYER_INFO) {
|
||||
if (event.getPacketType() == PacketType.Play.Server.ENTITY_METADATA) {
|
||||
WrapperPlayServerEntityMetadata wrapper = new WrapperPlayServerEntityMetadata(event);
|
||||
if (wrapper.getEntityId() != event.getUser().getEntityId()) {
|
||||
event.setLastUsedWrapper(null);
|
||||
}
|
||||
} else if (event.getPacketType() == PacketType.Play.Server.PLAYER_INFO) {
|
||||
//iterate through players and fake their game mode if they are spectating via grim spectate
|
||||
if (PacketEvents.getAPI().getServerManager().getVersion().isOlderThanOrEquals(ServerVersion.V_1_12_2))
|
||||
return;
|
||||
@@ -52,8 +62,8 @@ public class PacketHidePlayerInfo extends PacketListenerAbstract {
|
||||
//if amount of hidden players is the amount of players updated & is an update game mode action just cancel it
|
||||
if (hideCount == nmsPlayerInfoDataList.size() && info.getAction() == WrapperPlayServerPlayerInfo.Action.UPDATE_GAME_MODE) {
|
||||
event.setCancelled(true);
|
||||
} else if (hideCount > 0) {
|
||||
event.markForReEncode(true);
|
||||
} else if (hideCount <= 0) {
|
||||
event.setLastUsedWrapper(null);
|
||||
}
|
||||
}
|
||||
} else if (event.getPacketType() == PacketType.Play.Server.PLAYER_INFO_UPDATE) {
|
||||
@@ -71,13 +81,12 @@ public class PacketHidePlayerInfo extends PacketListenerAbstract {
|
||||
for (WrapperPlayServerPlayerInfoUpdate.PlayerInfo entry : wrapper.getEntries()) {
|
||||
//check if the player should be hidden
|
||||
WrapperPlayServerPlayerInfoUpdate.PlayerInfo modifiedPacket = null;
|
||||
final UserProfile gameProfile = entry.getGameProfile();
|
||||
if (GrimAPI.INSTANCE.getSpectateManager().shouldHidePlayer(receiver, gameProfile.getUUID())) {
|
||||
if (GrimAPI.INSTANCE.getSpectateManager().shouldHidePlayer(receiver, entry.getProfileId())) {
|
||||
hideCount++;
|
||||
//modify & create a new packet from pre-existing one if they are a spectator
|
||||
if (entry.getGameMode() == GameMode.SPECTATOR) {
|
||||
modifiedPacket = new WrapperPlayServerPlayerInfoUpdate.PlayerInfo(
|
||||
gameProfile,
|
||||
entry.getGameProfile(),
|
||||
entry.isListed(),
|
||||
entry.getLatency(),
|
||||
GameMode.SURVIVAL,
|
||||
@@ -95,20 +104,30 @@ public class PacketHidePlayerInfo extends PacketListenerAbstract {
|
||||
} //if only the game mode was updated and the packet was modified, don't send anything
|
||||
|
||||
}
|
||||
|
||||
// if the amount of hidden players & modified entries are the same
|
||||
if (hideCount == modified.size()) {
|
||||
//if no hidden players, don't modify packet
|
||||
if (hideCount <= 0) {
|
||||
event.setLastUsedWrapper(null);
|
||||
} else if (hideCount == modified.size()) { //if the amount of hidden players & modified entries are the same
|
||||
if (onlyGameMode) { // if only the game mode changed, cancel
|
||||
event.setCancelled(true);
|
||||
} else { //if more than the game mode changed, remove the action
|
||||
wrapper.getActions().remove(WrapperPlayServerPlayerInfoUpdate.Action.UPDATE_GAME_MODE);
|
||||
event.markForReEncode(true);
|
||||
}
|
||||
} else { //modify entries
|
||||
wrapper.setEntries(modified);
|
||||
event.markForReEncode(true);
|
||||
}
|
||||
}
|
||||
|
||||
} else if (event.getPacketType() != PacketType.Play.Server.PLAYER_POSITION_AND_LOOK) {
|
||||
event.setLastUsedWrapper(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPacketReceive(PacketReceiveEvent event) {
|
||||
PacketTypeCommon packetType = event.getPacketType();
|
||||
if (!WrapperPlayClientPlayerFlying.isFlying(packetType) && packetType != PacketType.Play.Client.CLIENT_SETTINGS && !event.isCancelled()) {
|
||||
event.setLastUsedWrapper(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -99,4 +99,4 @@ public class ProxyAlertMessenger extends PacketListenerAbstract {
|
||||
if (!file.exists()) return false;
|
||||
return YamlConfiguration.loadConfiguration(file).getBoolean(pathToValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -37,8 +37,7 @@ public class ResyncWorldUtil {
|
||||
|
||||
// Takes 0.15ms or so to complete. Not bad IMO. Unsure how I could improve this other than sending packets async.
|
||||
// But that's on PacketEvents.
|
||||
FoliaScheduler.getRegionScheduler().execute(GrimAPI.INSTANCE.getPlugin(), player.bukkitPlayer.getWorld(),
|
||||
minBlockX >> 4, minBlockZ >> 4, () -> {
|
||||
FoliaScheduler.getEntityScheduler().execute(player.bukkitPlayer, GrimAPI.INSTANCE.getPlugin(), () -> {
|
||||
boolean flat = PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_13);
|
||||
|
||||
if (player.bukkitPlayer == null) return;
|
||||
@@ -112,6 +111,6 @@ public class ResyncWorldUtil {
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}, null, 0);
|
||||
}
|
||||
}
|
||||
@@ -174,4 +174,4 @@ public class BasePacketWorldReader extends PacketListenerAbstract {
|
||||
player.latencyUtils.addRealTimeTask(player.lastTransactionSent.get(), () -> player.compensatedWorld.updateBlock(blockChange.getX(), blockChange.getY(), blockChange.getZ(), blockChange.getBlockId()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,24 +1,22 @@
|
||||
package ac.grim.grimac.manager;
|
||||
|
||||
|
||||
import ac.grim.grimac.api.AbstractCheck;
|
||||
import ac.grim.grimac.checks.impl.aim.AimDuplicateLook;
|
||||
import ac.grim.grimac.checks.impl.aim.AimModulo360;
|
||||
import ac.grim.grimac.checks.impl.aim.processor.AimProcessor;
|
||||
import ac.grim.grimac.checks.impl.badpackets.*;
|
||||
import ac.grim.grimac.checks.impl.combat.MultiInteractA;
|
||||
import ac.grim.grimac.checks.impl.combat.MultiInteractB;
|
||||
import ac.grim.grimac.checks.impl.combat.Reach;
|
||||
import ac.grim.grimac.checks.impl.crash.*;
|
||||
import ac.grim.grimac.checks.impl.exploit.ExploitA;
|
||||
import ac.grim.grimac.checks.impl.exploit.ExploitB;
|
||||
import ac.grim.grimac.checks.impl.groundspoof.NoFallA;
|
||||
import ac.grim.grimac.checks.impl.inventory.*;
|
||||
import ac.grim.grimac.checks.impl.misc.ClientBrand;
|
||||
import ac.grim.grimac.checks.impl.misc.FastBreak;
|
||||
import ac.grim.grimac.checks.impl.misc.GhostBlockMitigation;
|
||||
import ac.grim.grimac.checks.impl.misc.TransactionOrder;
|
||||
import ac.grim.grimac.checks.impl.movement.*;
|
||||
import ac.grim.grimac.checks.impl.packetorder.*;
|
||||
import ac.grim.grimac.checks.impl.post.Post;
|
||||
import ac.grim.grimac.checks.impl.post.PostCheck;
|
||||
import ac.grim.grimac.checks.impl.prediction.DebugHandler;
|
||||
import ac.grim.grimac.checks.impl.prediction.NoFallB;
|
||||
import ac.grim.grimac.checks.impl.prediction.OffsetHandler;
|
||||
@@ -44,16 +42,8 @@ import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.event.PacketSendEvent;
|
||||
import com.google.common.collect.ClassToInstanceMap;
|
||||
import com.google.common.collect.ImmutableClassToInstanceMap;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.permissions.Permission;
|
||||
import org.bukkit.permissions.PermissionDefault;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
public class CheckManager {
|
||||
private static boolean inited;
|
||||
private static final AtomicBoolean initedAtomic = new AtomicBoolean(false);
|
||||
|
||||
ClassToInstanceMap<PacketCheck> packetChecks;
|
||||
ClassToInstanceMap<PositionCheck> positionCheck;
|
||||
ClassToInstanceMap<RotationCheck> rotationCheck;
|
||||
@@ -86,10 +76,12 @@ public class CheckManager {
|
||||
.put(BadPacketsE.class, new BadPacketsE(player))
|
||||
.put(BadPacketsF.class, new BadPacketsF(player))
|
||||
.put(BadPacketsG.class, new BadPacketsG(player))
|
||||
.put(BadPacketsH.class, new BadPacketsH(player))
|
||||
.put(BadPacketsI.class, new BadPacketsI(player))
|
||||
.put(BadPacketsJ.class, new BadPacketsJ(player))
|
||||
.put(BadPacketsK.class, new BadPacketsK(player))
|
||||
.put(BadPacketsL.class, new BadPacketsL(player))
|
||||
.put(BadPacketsM.class, new BadPacketsM(player))
|
||||
.put(BadPacketsN.class, new BadPacketsN(player))
|
||||
.put(BadPacketsP.class, new BadPacketsP(player))
|
||||
.put(BadPacketsQ.class, new BadPacketsQ(player))
|
||||
@@ -102,16 +94,8 @@ public class CheckManager {
|
||||
.put(BadPacketsX.class, new BadPacketsX(player))
|
||||
.put(BadPacketsY.class, new BadPacketsY(player))
|
||||
.put(BadPacketsZ.class, new BadPacketsZ(player))
|
||||
.put(InventoryA.class, new InventoryA(player))
|
||||
.put(InventoryB.class, new InventoryB(player))
|
||||
.put(InventoryE.class, new InventoryE(player))
|
||||
.put(InventoryF.class, new InventoryF(player))
|
||||
.put(InventoryG.class, new InventoryG(player))
|
||||
.put(FastBreak.class, new FastBreak(player))
|
||||
.put(PacketOrderB.class, new PacketOrderB(player))
|
||||
.put(PacketOrderC.class, new PacketOrderC(player))
|
||||
.put(PacketOrderD.class, new PacketOrderD(player))
|
||||
.put(PacketOrderP.class, new PacketOrderP(player))
|
||||
.put(TransactionOrder.class, new TransactionOrder(player))
|
||||
.put(NoSlowB.class, new NoSlowB(player))
|
||||
.put(SetbackBlocker.class, new SetbackBlocker(player)) // Must be last class otherwise we can't check while blocking packets
|
||||
.build();
|
||||
@@ -134,20 +118,8 @@ public class CheckManager {
|
||||
.put(ExplosionHandler.class, new ExplosionHandler(player))
|
||||
.put(KnockbackHandler.class, new KnockbackHandler(player))
|
||||
.put(GhostBlockDetector.class, new GhostBlockDetector(player))
|
||||
.put(InventoryD.class, new InventoryD(player))
|
||||
.put(Phase.class, new Phase(player))
|
||||
.put(PacketOrderProcessor.class, player.packetOrderProcessor)
|
||||
.put(Post.class, new Post(player))
|
||||
.put(PacketOrderA.class, new PacketOrderA(player))
|
||||
.put(PacketOrderE.class, new PacketOrderE(player))
|
||||
.put(PacketOrderF.class, new PacketOrderF(player))
|
||||
.put(PacketOrderG.class, new PacketOrderG(player))
|
||||
.put(PacketOrderH.class, new PacketOrderH(player))
|
||||
.put(PacketOrderI.class, new PacketOrderI(player))
|
||||
.put(PacketOrderJ.class, new PacketOrderJ(player))
|
||||
.put(PacketOrderK.class, new PacketOrderK(player))
|
||||
.put(PacketOrderL.class, new PacketOrderL(player))
|
||||
.put(PacketOrderM.class, new PacketOrderM(player))
|
||||
.put(PostCheck.class, new PostCheck(player))
|
||||
.put(NoFallB.class, new NoFallB(player))
|
||||
.put(OffsetHandler.class, new OffsetHandler(player))
|
||||
.put(SuperDebug.class, new SuperDebug(player))
|
||||
@@ -157,8 +129,6 @@ public class CheckManager {
|
||||
.put(NoSlowC.class, new NoSlowC(player))
|
||||
.put(NoSlowD.class, new NoSlowD(player))
|
||||
.put(NoSlowE.class, new NoSlowE(player))
|
||||
.put(MultiInteractA.class, new MultiInteractA(player))
|
||||
.put(MultiInteractB.class, new MultiInteractB(player))
|
||||
.put(SetbackTeleportUtil.class, new SetbackTeleportUtil(player)) // Avoid teleporting to new position, update safe pos last
|
||||
.put(CompensatedFireworks.class, player.compensatedFireworks)
|
||||
.put(SneakingEstimator.class, new SneakingEstimator(player))
|
||||
@@ -166,7 +136,6 @@ public class CheckManager {
|
||||
.build();
|
||||
|
||||
blockPlaceCheck = new ImmutableClassToInstanceMap.Builder<BlockPlaceCheck>()
|
||||
.put(InventoryC.class, new InventoryC(player))
|
||||
.put(InvalidPlaceA.class, new InvalidPlaceA(player))
|
||||
.put(InvalidPlaceB.class, new InvalidPlaceB(player))
|
||||
.put(AirLiquidPlace.class, new AirLiquidPlace(player))
|
||||
@@ -174,8 +143,6 @@ public class CheckManager {
|
||||
.put(FarPlace.class, new FarPlace(player))
|
||||
.put(FabricatedPlace.class, new FabricatedPlace(player))
|
||||
.put(PositionPlace.class, new PositionPlace(player))
|
||||
.put(PacketOrderN.class, new PacketOrderN(player))
|
||||
.put(PacketOrderO.class, new PacketOrderO(player))
|
||||
.put(DuplicateRotPlace.class, new DuplicateRotPlace(player))
|
||||
.put(LineOfSightPlace.class, new LineOfSightPlace(player))
|
||||
.put(GhostBlockMitigation.class, new GhostBlockMitigation(player))
|
||||
@@ -205,8 +172,6 @@ public class CheckManager {
|
||||
.putAll(blockPlaceCheck)
|
||||
.putAll(prePredictionChecks)
|
||||
.build();
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -308,17 +273,11 @@ public class CheckManager {
|
||||
return (T) packetChecks.get(check);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends BlockPlaceCheck> T getBlockPlaceCheck(Class<T> check) {
|
||||
return (T) blockPlaceCheck.get(check);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends PacketCheck> T getPrePredictionCheck(Class<T> check) {
|
||||
return (T) prePredictionChecks.get(check);
|
||||
}
|
||||
|
||||
|
||||
private PacketEntityReplication packetEntityReplication = null;
|
||||
|
||||
public PacketEntityReplication getEntityReplication() {
|
||||
@@ -365,25 +324,4 @@ public class CheckManager {
|
||||
public <T extends PostPredictionCheck> T getPostPredictionCheck(Class<T> check) {
|
||||
return (T) postPredictionCheck.get(check);
|
||||
}
|
||||
|
||||
private void init() {
|
||||
// Fast non-thread safe check
|
||||
if (inited) return;
|
||||
// Slow thread safe check
|
||||
if (!initedAtomic.compareAndSet(false, true)) return;
|
||||
inited = true;
|
||||
|
||||
for (AbstractCheck check : allChecks.values()) {
|
||||
if (check.getCheckName() != null) {
|
||||
String permissionName = "grim.exempt." + check.getCheckName().toLowerCase();
|
||||
Permission permission = Bukkit.getPluginManager().getPermission(permissionName);
|
||||
|
||||
if (permission == null) {
|
||||
Bukkit.getPluginManager().addPermission(new Permission(permissionName, PermissionDefault.FALSE));
|
||||
} else {
|
||||
permission.setDefault(PermissionDefault.FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+59
-44
@@ -1,4 +1,4 @@
|
||||
package ac.grim.grimac.manager.config;
|
||||
package ac.grim.grimac.manager;
|
||||
|
||||
import ac.grim.grimac.GrimAC;
|
||||
import ac.grim.grimac.GrimAPI;
|
||||
@@ -7,38 +7,55 @@ import ac.grim.grimac.api.config.ConfigManager;
|
||||
import ac.grim.grimac.utils.anticheat.LogUtil;
|
||||
import github.scarsz.configuralize.DynamicConfig;
|
||||
import github.scarsz.configuralize.Language;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.PatternSyntaxException;
|
||||
|
||||
public class ConfigManagerFileImpl implements ConfigManager, BasicReloadable {
|
||||
public class ConfigManagerImpl implements ConfigManager, BasicReloadable {
|
||||
|
||||
public ConfigManager getConfig() {
|
||||
if (GrimAPI.INSTANCE.getInitManager().isStarted()) return GrimAPI.INSTANCE.getExternalAPI().getConfigManager();
|
||||
return this;
|
||||
}
|
||||
|
||||
private final DynamicConfig config;
|
||||
@Getter
|
||||
private final File configFile = new File(GrimAPI.INSTANCE.getPlugin().getDataFolder(), "config.yml");
|
||||
@Getter
|
||||
private final File messagesFile = new File(GrimAPI.INSTANCE.getPlugin().getDataFolder(), "messages.yml");
|
||||
@Getter
|
||||
private final File discordFile = new File(GrimAPI.INSTANCE.getPlugin().getDataFolder(), "discord.yml");
|
||||
@Getter
|
||||
private final File punishFile = new File(GrimAPI.INSTANCE.getPlugin().getDataFolder(), "punishments.yml");
|
||||
@Getter
|
||||
private boolean ignoreDuplicatePacketRotation = false;
|
||||
|
||||
private File getConfigFile(String path) {
|
||||
return new File(GrimAPI.INSTANCE.getPlugin().getDataFolder(), path);
|
||||
}
|
||||
@Getter
|
||||
private boolean experimentalChecks = false;
|
||||
|
||||
public ConfigManagerFileImpl() {
|
||||
private final List<Pattern> ignoredClientPatterns = new ArrayList<>();
|
||||
|
||||
public ConfigManagerImpl() {
|
||||
upgrade();
|
||||
// load config
|
||||
GrimAPI.INSTANCE.getPlugin().getDataFolder().mkdirs();
|
||||
config = new DynamicConfig();
|
||||
}
|
||||
config.addSource(GrimAC.class, "config", getConfigFile());
|
||||
config.addSource(GrimAC.class, "messages", getMessagesFile());
|
||||
config.addSource(GrimAC.class, "discord", getDiscordFile());
|
||||
config.addSource(GrimAC.class, "punishments", getPunishFile());
|
||||
|
||||
private boolean initialized = false;
|
||||
reload();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
GrimAPI.INSTANCE.getPlugin().getDataFolder().mkdirs();
|
||||
if (!initialized) {
|
||||
initialized = true;
|
||||
upgrade();
|
||||
config.addSource(GrimAC.class, "config", getConfigFile("config.yml"));
|
||||
config.addSource(GrimAC.class, "messages", getConfigFile("messages.yml"));
|
||||
config.addSource(GrimAC.class, "discord", getConfigFile("discord.yml"));
|
||||
config.addSource(GrimAC.class, "punishments", getConfigFile("punishments.yml"));
|
||||
}
|
||||
//
|
||||
String languageCode = System.getProperty("user.language").toUpperCase();
|
||||
|
||||
try {
|
||||
@@ -65,6 +82,29 @@ public class ConfigManagerFileImpl implements ConfigManager, BasicReloadable {
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to load config", e);
|
||||
}
|
||||
|
||||
int configuredMaxTransactionTime = config.getIntElse("max-transaction-time", 60);
|
||||
if (configuredMaxTransactionTime > 180 || configuredMaxTransactionTime < 1) {
|
||||
LogUtil.warn("Detected invalid max-transaction-time! This setting is clamped between 1 and 180 to prevent issues. Attempting to disable or set this too high can result in memory usage issues.");
|
||||
}
|
||||
|
||||
ignoredClientPatterns.clear();
|
||||
for (String string : config.getStringList("client-brand.ignored-clients")) {
|
||||
try {
|
||||
ignoredClientPatterns.add(Pattern.compile(string));
|
||||
} catch (PatternSyntaxException e) {
|
||||
throw new RuntimeException("Failed to compile client pattern", e);
|
||||
}
|
||||
}
|
||||
experimentalChecks = config.getBooleanElse("experimental-checks", false);
|
||||
ignoreDuplicatePacketRotation = config.getBooleanElse("ignore-duplicate-packet-rotation", false);
|
||||
}
|
||||
|
||||
public boolean isIgnoredClient(String brand) {
|
||||
for (Pattern pattern : ignoredClientPatterns) {
|
||||
if (pattern.matcher(brand).find()) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void upgrade() {
|
||||
@@ -82,7 +122,7 @@ public class ConfigManagerFileImpl implements ConfigManager, BasicReloadable {
|
||||
|
||||
configVersion = Integer.parseInt(configStringVersion);
|
||||
// TODO: Do we have to hardcode this?
|
||||
configString = configString.replaceAll("config-version: " + configStringVersion, "config-version: 10");
|
||||
configString = configString.replaceAll("config-version: " + configStringVersion, "config-version: 9");
|
||||
Files.write(config.toPath(), configString.getBytes());
|
||||
|
||||
upgradeModernConfig(config, configString, configVersion);
|
||||
@@ -124,9 +164,6 @@ public class ConfigManagerFileImpl implements ConfigManager, BasicReloadable {
|
||||
if (configVersion < 9) {
|
||||
newOffsetHandlingAntiKB(config, configString);
|
||||
}
|
||||
if (configVersion < 10) {
|
||||
addInventoryPunishments();
|
||||
}
|
||||
}
|
||||
|
||||
private void removeLegacyTwoPointOne(File config) throws IOException {
|
||||
@@ -177,28 +214,6 @@ public class ConfigManagerFileImpl implements ConfigManager, BasicReloadable {
|
||||
}
|
||||
}
|
||||
|
||||
private void addInventoryPunishments() {
|
||||
File config = new File(GrimAPI.INSTANCE.getPlugin().getDataFolder(), "punishments.yml");
|
||||
String configString;
|
||||
if (config.exists()) {
|
||||
try {
|
||||
configString = new String(Files.readAllBytes(config.toPath()));
|
||||
|
||||
// If it works, it isn't stupid. Only replace it if it exactly matches the default config.
|
||||
String reachSection = " Reach:";
|
||||
String inventorySection = " Inventory:\n remove-violations-after: 300\n checks:\n - \"Inventory\"\n commands:\n - \"10:10 [alert]\"\n - \"20:20 [webhook]\"\n - \"20:20 [proxy]\"\n";
|
||||
|
||||
int index = configString.indexOf(reachSection);
|
||||
if (index != -1) {
|
||||
configString = configString.substring(0, index) + inventorySection + configString.substring(index);
|
||||
}
|
||||
|
||||
Files.write(config.toPath(), configString.getBytes());
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void fixBadPacketsAndAdjustPingConfig(File config, String configString) {
|
||||
try {
|
||||
configString = configString.replaceAll("max-ping: \\d+", "max-transaction-time: 60");
|
||||
@@ -1,72 +1,68 @@
|
||||
package ac.grim.grimac.manager;
|
||||
|
||||
import ac.grim.grimac.GrimAPI;
|
||||
import ac.grim.grimac.GrimExternalAPI;
|
||||
import ac.grim.grimac.manager.init.Initable;
|
||||
import ac.grim.grimac.manager.init.load.PacketEventsInit;
|
||||
import ac.grim.grimac.manager.init.start.*;
|
||||
import ac.grim.grimac.manager.init.stop.TerminatePacketEvents;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ClassToInstanceMap;
|
||||
import com.google.common.collect.ImmutableClassToInstanceMap;
|
||||
import lombok.Getter;
|
||||
|
||||
public class InitManager {
|
||||
|
||||
private final ImmutableList<Initable> initializersOnLoad;
|
||||
private final ImmutableList<Initable> initializersOnStart;
|
||||
private final ImmutableList<Initable> initializersOnStop;
|
||||
private final ClassToInstanceMap<Initable> initializersOnLoad;
|
||||
private final ClassToInstanceMap<Initable> initializersOnStart;
|
||||
private final ClassToInstanceMap<Initable> initializersOnStop;
|
||||
|
||||
@Getter private boolean loaded = false;
|
||||
@Getter private boolean started = false;
|
||||
@Getter private boolean stopped = false;
|
||||
|
||||
public InitManager() {
|
||||
initializersOnLoad = ImmutableList.<Initable>builder()
|
||||
.add(new PacketEventsInit())
|
||||
.add(() -> GrimAPI.INSTANCE.getExternalAPI().load())
|
||||
initializersOnLoad = new ImmutableClassToInstanceMap.Builder<Initable>()
|
||||
.put(PacketEventsInit.class, new PacketEventsInit())
|
||||
.build();
|
||||
|
||||
initializersOnStart = ImmutableList.<Initable>builder()
|
||||
.add(GrimAPI.INSTANCE.getExternalAPI())
|
||||
.add(new ExemptOnlinePlayers())
|
||||
.add(new EventManager())
|
||||
.add(new PacketManager())
|
||||
.add(new ViaBackwardsManager())
|
||||
.add(new TickRunner())
|
||||
.add(new TickEndEvent())
|
||||
.add(new CommandRegister())
|
||||
.add(new BStats())
|
||||
.add(new PacketLimiter())
|
||||
.add(GrimAPI.INSTANCE.getDiscordManager())
|
||||
.add(GrimAPI.INSTANCE.getSpectateManager())
|
||||
.add(new JavaVersion())
|
||||
.add(new ViaVersion())
|
||||
initializersOnStart = new ImmutableClassToInstanceMap.Builder<Initable>()
|
||||
.put(GrimExternalAPI.class, GrimAPI.INSTANCE.getExternalAPI())
|
||||
.put(ExemptOnlinePlayers.class, new ExemptOnlinePlayers())
|
||||
.put(EventManager.class, new EventManager())
|
||||
.put(PacketManager.class, new PacketManager())
|
||||
.put(ViaBackwardsManager.class, new ViaBackwardsManager())
|
||||
.put(TickRunner.class, new TickRunner())
|
||||
.put(TickEndEvent.class, new TickEndEvent())
|
||||
.put(CommandRegister.class, new CommandRegister())
|
||||
.put(BStats.class, new BStats())
|
||||
.put(PacketLimiter.class, new PacketLimiter())
|
||||
.put(DiscordManager.class, GrimAPI.INSTANCE.getDiscordManager())
|
||||
.put(SpectateManager.class, GrimAPI.INSTANCE.getSpectateManager())
|
||||
.put(JavaVersion.class, new JavaVersion())
|
||||
.build();
|
||||
|
||||
initializersOnStop = ImmutableList.<Initable>builder()
|
||||
.add(new TerminatePacketEvents())
|
||||
initializersOnStop = new ImmutableClassToInstanceMap.Builder<Initable>()
|
||||
.put(TerminatePacketEvents.class, new TerminatePacketEvents())
|
||||
.build();
|
||||
}
|
||||
|
||||
public void load() {
|
||||
for (Initable initable : initializersOnLoad) handle(initable);
|
||||
for (Initable initable : initializersOnLoad.values()) {
|
||||
initable.start();
|
||||
}
|
||||
loaded = true;
|
||||
}
|
||||
|
||||
public void start() {
|
||||
for (Initable initable : initializersOnStart) handle(initable);
|
||||
for (Initable initable : initializersOnStart.values()) {
|
||||
initable.start();
|
||||
}
|
||||
started = true;
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
for (Initable initable : initializersOnStop) handle(initable);
|
||||
for (Initable initable : initializersOnStop.values()) {
|
||||
initable.start();
|
||||
}
|
||||
stopped = true;
|
||||
}
|
||||
|
||||
private void handle(Initable initable) {
|
||||
try {
|
||||
initable.start();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,6 @@ import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.anticheat.LogUtil;
|
||||
import ac.grim.grimac.utils.anticheat.MessageUtil;
|
||||
import io.github.retrooper.packetevents.util.folia.FoliaScheduler;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.bukkit.Bukkit;
|
||||
@@ -23,23 +22,17 @@ public class PunishmentManager implements ConfigReloadable {
|
||||
GrimPlayer player;
|
||||
List<PunishGroup> groups = new ArrayList<>();
|
||||
String experimentalSymbol = "*";
|
||||
private String alertString;
|
||||
private boolean testMode;
|
||||
private boolean printToConsole;
|
||||
private String proxyAlertString = "";
|
||||
|
||||
public PunishmentManager(GrimPlayer player) {
|
||||
this.player = player;
|
||||
reload(GrimAPI.INSTANCE.getConfigManager().getConfig());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload(ConfigManager config) {
|
||||
List<String> punish = config.getStringListElse("Punishments", new ArrayList<>());
|
||||
experimentalSymbol = config.getStringElse("experimental-symbol", "*");
|
||||
alertString = config.getStringElse("alerts-format", "%prefix% &f%player% &bfailed &f%check_name% &f(x&c%vl%&f) &7%verbose%");
|
||||
testMode = config.getBooleanElse("test-mode", false);
|
||||
printToConsole = config.getBooleanElse("verbose.print-to-console", false);
|
||||
proxyAlertString = config.getStringElse("alerts-format-proxy", "%prefix% &f[&cproxy&f] &f%player% &bfailed &f%check_name% &f(x&c%vl%&f) &7%verbose%");
|
||||
|
||||
try {
|
||||
groups.clear();
|
||||
|
||||
@@ -106,7 +99,7 @@ public class PunishmentManager implements ConfigReloadable {
|
||||
original = MessageUtil.format(original
|
||||
.replace("[alert]", alertString)
|
||||
.replace("[proxy]", alertString)
|
||||
.replace("%check_name%", check.getDisplayName())
|
||||
.replace("%check_name%", check.getCheckName())
|
||||
.replace("%experimental%", check.isExperimental() ? experimentalSymbol : "")
|
||||
.replace("%vl%", vl)
|
||||
.replace("%verbose%", verbose)
|
||||
@@ -119,6 +112,8 @@ public class PunishmentManager implements ConfigReloadable {
|
||||
}
|
||||
|
||||
public boolean handleAlert(GrimPlayer player, String verbose, Check check) {
|
||||
String alertString = GrimAPI.INSTANCE.getConfigManager().getConfig().getStringElse("alerts-format", "%prefix% &f%player% &bfailed &f%check_name% &f(x&c%vl%&f) &7%verbose%");
|
||||
boolean testMode = GrimAPI.INSTANCE.getConfigManager().getConfig().getBooleanElse("test-mode", false);
|
||||
boolean sentDebug = false;
|
||||
|
||||
// Check commands
|
||||
@@ -134,7 +129,7 @@ public class PunishmentManager implements ConfigReloadable {
|
||||
for (Player bukkitPlayer : GrimAPI.INSTANCE.getAlertManager().getEnabledVerbose()) {
|
||||
bukkitPlayer.sendMessage(cmd);
|
||||
}
|
||||
if (printToConsole) {
|
||||
if (GrimAPI.INSTANCE.getConfigManager().getConfig().getBooleanElse("verbose.print-to-console", false)) {
|
||||
LogUtil.console(cmd); // Print verbose to console
|
||||
}
|
||||
}
|
||||
@@ -150,9 +145,11 @@ public class PunishmentManager implements ConfigReloadable {
|
||||
|
||||
if (command.command.equals("[webhook]")) {
|
||||
String vl = group.violations.values().stream().filter((e) -> e == check).count() + "";
|
||||
GrimAPI.INSTANCE.getDiscordManager().sendAlert(player, verbose, check.getDisplayName(), vl);
|
||||
GrimAPI.INSTANCE.getDiscordManager().sendAlert(player, verbose, check.getCheckName(), vl);
|
||||
} else if (command.command.equals("[proxy]")) {
|
||||
ProxyAlertMessenger.sendPluginMessage(replaceAlertPlaceholders(command.getCommand(), group, check, proxyAlertString, verbose));
|
||||
String proxyAlertString = GrimAPI.INSTANCE.getConfigManager().getConfig().getStringElse("alerts-format-proxy", "%prefix% &f[&cproxy&f] &f%player% &bfailed &f%check_name% &f(x&c%vl%&f) &7%verbose%");
|
||||
proxyAlertString = replaceAlertPlaceholders(command.getCommand(), group, check, proxyAlertString, verbose);
|
||||
ProxyAlertMessenger.sendPluginMessage(proxyAlertString);
|
||||
} else {
|
||||
if (command.command.equals("[alert]")) {
|
||||
sentDebug = true;
|
||||
@@ -164,8 +161,9 @@ public class PunishmentManager implements ConfigReloadable {
|
||||
}
|
||||
|
||||
String finalCmd = cmd;
|
||||
FoliaScheduler.getGlobalRegionScheduler().run(GrimAPI.INSTANCE.getPlugin(), (dummy) ->
|
||||
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), finalCmd));
|
||||
FoliaScheduler.getGlobalRegionScheduler().run(GrimAPI.INSTANCE.getPlugin(), (dummy) -> {
|
||||
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), finalCmd);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,7 +182,7 @@ public class PunishmentManager implements ConfigReloadable {
|
||||
|
||||
group.violations.put(currentTime, check);
|
||||
// Remove violations older than the defined time in the config
|
||||
group.violations.long2ObjectEntrySet().removeIf(time -> currentTime - time.getLongKey() > group.removeViolationsAfter);
|
||||
group.violations.entrySet().removeIf(time -> currentTime - time.getKey() > group.removeViolationsAfter);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -196,7 +194,7 @@ class PunishGroup {
|
||||
@Getter
|
||||
List<ParsedCommand> commands;
|
||||
@Getter
|
||||
Long2ObjectOpenHashMap<Check> violations = new Long2ObjectOpenHashMap<>();
|
||||
HashMap<Long, Check> violations = new HashMap<>();
|
||||
@Getter
|
||||
int removeViolationsAfter;
|
||||
|
||||
|
||||
@@ -19,7 +19,6 @@ import ac.grim.grimac.utils.math.VectorUtils;
|
||||
import ac.grim.grimac.utils.nmsutil.Collisions;
|
||||
import ac.grim.grimac.utils.nmsutil.GetBoundingBox;
|
||||
import ac.grim.grimac.utils.nmsutil.ReachUtils;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
||||
import com.github.retrooper.packetevents.protocol.player.GameMode;
|
||||
@@ -32,15 +31,13 @@ import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
import static ac.grim.grimac.utils.vector.VectorFactory.newVector3D;
|
||||
|
||||
public class SetbackTeleportUtil extends Check implements PostPredictionCheck {
|
||||
// Sync to netty
|
||||
public final ConcurrentLinkedQueue<TeleportData> pendingTeleports = new ConcurrentLinkedQueue<>();
|
||||
@@ -68,7 +65,7 @@ public class SetbackTeleportUtil extends Check implements PostPredictionCheck {
|
||||
@Override
|
||||
public void onPredictionComplete(final PredictionComplete predictionComplete) {
|
||||
// Grab friction now when we know player on ground and other variables
|
||||
Vector3D afterTickFriction = player.clientVelocity.clone();
|
||||
Vector afterTickFriction = player.clientVelocity.clone();
|
||||
|
||||
// We must first check if the player has accepted their setback
|
||||
// If the setback isn't complete, then this position is illegitimate
|
||||
@@ -118,7 +115,7 @@ public class SetbackTeleportUtil extends Check implements PostPredictionCheck {
|
||||
return false;
|
||||
}
|
||||
|
||||
private void simulateFriction(Vector3D vector) {
|
||||
private void simulateFriction(Vector vector) {
|
||||
// We must always do this before simulating positions, as this is the last actual (safe) movement
|
||||
// We must not do this for knockback or explosions, as they are at the start of the tick
|
||||
if (player.wasTouchingWater) {
|
||||
@@ -126,9 +123,9 @@ public class SetbackTeleportUtil extends Check implements PostPredictionCheck {
|
||||
} else if (player.wasTouchingLava) {
|
||||
vector.multiply(0.5D);
|
||||
if (player.hasGravity)
|
||||
vector.add(newVector3D(0.0D, -player.gravity / 4.0D, 0.0D));
|
||||
vector.add(new Vector(0.0D, -player.gravity / 4.0D, 0.0D));
|
||||
} else if (player.isGliding) {
|
||||
PredictionEngineElytra.getElytraMovement(player, vector, ReachUtils.getLook(player, player.xRot, player.yRot)).multiply(player.stuckSpeedMultiplier).multiply(newVector3D(0.99F, 0.98F, 0.99F));
|
||||
PredictionEngineElytra.getElytraMovement(player, vector, ReachUtils.getLook(player, player.xRot, player.yRot)).multiply(player.stuckSpeedMultiplier).multiply(new Vector(0.99F, 0.98F, 0.99F));
|
||||
vector.setY(vector.getY() - 0.05); // Make the player fall a bit
|
||||
} else { // Gliding doesn't have friction, we handle it differently
|
||||
PredictionEngineNormal.staticVectorEndOfTick(player, vector); // Lava and normal movement
|
||||
@@ -150,9 +147,9 @@ public class SetbackTeleportUtil extends Check implements PostPredictionCheck {
|
||||
lastWorldResync = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
Vector3D clientVel = lastKnownGoodPosition.vector.clone();
|
||||
Vector clientVel = lastKnownGoodPosition.vector.clone();
|
||||
|
||||
Pair<VelocityData, Vector3D> futureKb = player.checkManager.getKnockbackHandler().getFutureKnockback();
|
||||
Pair<VelocityData, Vector> futureKb = player.checkManager.getKnockbackHandler().getFutureKnockback();
|
||||
VelocityData futureExplosion = player.checkManager.getExplosionHandler().getFutureExplosion();
|
||||
|
||||
// Velocity sets
|
||||
@@ -172,7 +169,7 @@ public class SetbackTeleportUtil extends Check implements PostPredictionCheck {
|
||||
|
||||
// Mini prediction engine - simulate collisions
|
||||
if (simulateNextTickPosition) {
|
||||
Vector3D collide = Collisions.collide(player, clientVel.getX(), clientVel.getY(), clientVel.getZ());
|
||||
Vector collide = Collisions.collide(player, clientVel.getX(), clientVel.getY(), clientVel.getZ());
|
||||
|
||||
position = position.withX(position.getX() + collide.getX());
|
||||
// 1.8 players need the collision epsilon to not phase into blocks when being setback
|
||||
@@ -415,7 +412,7 @@ public class SetbackTeleportUtil extends Check implements PostPredictionCheck {
|
||||
data = new TeleportData(safePosition, flags, transaction, teleportId);
|
||||
requiredSetBack = new SetBackData(data, player.xRot, player.yRot, null, false, plugin);
|
||||
|
||||
this.lastKnownGoodPosition = new SetbackPosWithVector(safePosition, newVector3D());
|
||||
this.lastKnownGoodPosition = new SetbackPosWithVector(safePosition, new Vector());
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
@@ -423,6 +420,6 @@ public class SetbackTeleportUtil extends Check implements PostPredictionCheck {
|
||||
@Setter
|
||||
public static class SetbackPosWithVector {
|
||||
private Vector3d pos;
|
||||
private Vector3D vector;
|
||||
private Vector vector;
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,6 @@ import ac.grim.grimac.manager.tick.Tickable;
|
||||
import ac.grim.grimac.manager.tick.impl.ClientVersionSetter;
|
||||
import ac.grim.grimac.manager.tick.impl.ResetTick;
|
||||
import ac.grim.grimac.manager.tick.impl.TickInventory;
|
||||
import ac.grim.grimac.manager.tick.impl.UpdateChangedBlocksList;
|
||||
import com.google.common.collect.ClassToInstanceMap;
|
||||
import com.google.common.collect.ImmutableClassToInstanceMap;
|
||||
|
||||
@@ -23,7 +22,6 @@ public class TickManager {
|
||||
asyncTick = new ImmutableClassToInstanceMap.Builder<Tickable>()
|
||||
.put(ClientVersionSetter.class, new ClientVersionSetter()) // Async because permission lookups might take a while, depending on the plugin
|
||||
.put(TickInventory.class, new TickInventory()) // Async because I've never gotten an exception from this. It's probably safe.
|
||||
.put(UpdateChangedBlocksList.class, new UpdateChangedBlocksList())
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
package ac.grim.grimac.manager.config;
|
||||
|
||||
import ac.grim.grimac.api.config.ConfigManager;
|
||||
import ac.grim.grimac.utils.anticheat.LogUtil;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.PatternSyntaxException;
|
||||
|
||||
public class BaseConfigManager {
|
||||
|
||||
/*
|
||||
This is to hold whatever config manager was set via the reload method in the API
|
||||
and any global variables that are the same between players.
|
||||
*/
|
||||
|
||||
@Getter
|
||||
private ConfigManager config = null;
|
||||
|
||||
// initialize the config
|
||||
public void load(ConfigManager config) {
|
||||
this.config = config;
|
||||
//
|
||||
int configuredMaxTransactionTime = config.getIntElse("max-transaction-time", 60);
|
||||
if (configuredMaxTransactionTime > 180 || configuredMaxTransactionTime < 1) {
|
||||
LogUtil.warn("Detected invalid max-transaction-time! This setting is clamped between 1 and 180 to prevent issues. Attempting to disable or set this too high can result in memory usage issues.");
|
||||
}
|
||||
|
||||
ignoredClientPatterns.clear();
|
||||
for (String string : config.getStringList("client-brand.ignored-clients")) {
|
||||
try {
|
||||
ignoredClientPatterns.add(Pattern.compile(string));
|
||||
} catch (PatternSyntaxException e) {
|
||||
throw new RuntimeException("Failed to compile client pattern", e);
|
||||
}
|
||||
}
|
||||
|
||||
printAlertsToConsole = config.getBooleanElse("alerts.print-to-console", true);
|
||||
prefix = config.getStringElse("prefix", "&bGrim &8»");
|
||||
}
|
||||
|
||||
// ran on start, can be used to handle things that can't be done while loading
|
||||
public void start() {
|
||||
|
||||
}
|
||||
|
||||
@Getter private boolean printAlertsToConsole = false;
|
||||
|
||||
@Getter private String prefix = "&bGrim &8»";
|
||||
|
||||
private final List<Pattern> ignoredClientPatterns = new ArrayList<>();
|
||||
|
||||
public boolean isIgnoredClient(String brand) {
|
||||
for (Pattern pattern : ignoredClientPatterns) {
|
||||
if (pattern.matcher(brand).find()) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -4,17 +4,8 @@ import ac.grim.grimac.GrimAPI;
|
||||
import ac.grim.grimac.manager.init.Initable;
|
||||
import ac.grim.grimac.utils.anticheat.LogUtil;
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.protocol.chat.ChatTypes;
|
||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes;
|
||||
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
|
||||
import com.github.retrooper.packetevents.protocol.item.enchantment.type.EnchantmentTypes;
|
||||
import com.github.retrooper.packetevents.protocol.item.type.ItemTypes;
|
||||
import com.github.retrooper.packetevents.protocol.particle.type.ParticleTypes;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.type.StateTypes;
|
||||
import io.github.retrooper.packetevents.factory.spigot.SpigotPacketEventsBuilder;
|
||||
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
public class PacketEventsInit implements Initable {
|
||||
@Override
|
||||
public void start() {
|
||||
@@ -25,18 +16,7 @@ public class PacketEventsInit implements Initable {
|
||||
.fullStackTrace(true)
|
||||
.kickOnPacketException(true)
|
||||
.checkForUpdates(false)
|
||||
.reEncodeByDefault(false)
|
||||
.debug(false);
|
||||
PacketEvents.getAPI().load();
|
||||
// This may seem useless, but it causes java to start loading stuff async before we need it
|
||||
Executors.defaultThreadFactory().newThread(() -> {
|
||||
StateTypes.AIR.getName();
|
||||
ItemTypes.AIR.getName();
|
||||
EntityTypes.PLAYER.getParent();
|
||||
EntityDataTypes.BOOLEAN.getName();
|
||||
ChatTypes.CHAT.getName();
|
||||
EnchantmentTypes.ALL_DAMAGE_PROTECTION.getName();
|
||||
ParticleTypes.DUST.getName();
|
||||
}).start();
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@ public class BStats implements Initable {
|
||||
public void start() {
|
||||
int pluginId = 12820; // <-- Replace with the id of your plugin!
|
||||
try {
|
||||
new io.github.retrooper.packetevents.bstats.bukkit.Metrics(GrimAPI.INSTANCE.getPlugin(), pluginId);
|
||||
new io.github.retrooper.packetevents.bstats.Metrics(GrimAPI.INSTANCE.getPlugin(), pluginId);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ public class PacketManager implements Initable {
|
||||
PacketEvents.getAPI().getEventManager().registerListener(new PacketConfigurationListener());
|
||||
PacketEvents.getAPI().getEventManager().registerListener(new PacketPlayerJoinQuit());
|
||||
PacketEvents.getAPI().getEventManager().registerListener(new PacketPingListener());
|
||||
PacketEvents.getAPI().getEventManager().registerListener(new PacketPlayerWindow());
|
||||
PacketEvents.getAPI().getEventManager().registerListener(new PacketPlayerDigging());
|
||||
PacketEvents.getAPI().getEventManager().registerListener(new PacketPlayerAttack());
|
||||
PacketEvents.getAPI().getEventManager().registerListener(new PacketEntityAction());
|
||||
@@ -44,7 +43,7 @@ public class PacketManager implements Initable {
|
||||
}
|
||||
|
||||
PacketEvents.getAPI().getEventManager().registerListener(new ProxyAlertMessenger());
|
||||
PacketEvents.getAPI().getEventManager().registerListener(new PacketHidePlayerInfo());
|
||||
PacketEvents.getAPI().getEventManager().registerListener(new PacketSetWrapperNull());
|
||||
|
||||
PacketEvents.getAPI().init();
|
||||
}
|
||||
|
||||
@@ -10,29 +10,24 @@ import ac.grim.grimac.utils.anticheat.update.PredictionComplete;
|
||||
import ac.grim.grimac.utils.data.VectorData;
|
||||
import ac.grim.grimac.utils.lists.EvictingQueue;
|
||||
import ac.grim.grimac.utils.math.GrimMath;
|
||||
import ac.grim.grimac.utils.vector.Vector3D;
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.WrappedBlockState;
|
||||
import com.github.retrooper.packetevents.util.Vector3d;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static ac.grim.grimac.utils.vector.VectorFactory.newVector3D;
|
||||
|
||||
public final class SuperDebug extends Check implements PostPredictionCheck {
|
||||
private static final StringBuilder[] flags = new StringBuilder[256]; // 17 MB of logs in memory
|
||||
|
||||
Object2IntMap<StringBuilder> continuedDebug = new Object2IntOpenHashMap<>();
|
||||
Map<StringBuilder, Integer> continuedDebug = new HashMap<>();
|
||||
|
||||
List<VectorData> predicted = new EvictingQueue<>(60);
|
||||
List<Vector3D> actually = new EvictingQueue<>(60);
|
||||
List<Vector> actually = new EvictingQueue<>(60);
|
||||
List<Location> locations = new EvictingQueue<>(60);
|
||||
List<Vector3D> startTickClientVel = new EvictingQueue<>(60);
|
||||
List<Vector3D> baseTickAddition = new EvictingQueue<>(60);
|
||||
List<Vector3D> baseTickWater = new EvictingQueue<>(60);
|
||||
List<Vector> startTickClientVel = new EvictingQueue<>(60);
|
||||
List<Vector> baseTickAddition = new EvictingQueue<>(60);
|
||||
List<Vector> baseTickWater = new EvictingQueue<>(60);
|
||||
|
||||
public SuperDebug(GrimPlayer player) {
|
||||
super(player);
|
||||
@@ -50,7 +45,7 @@ public final class SuperDebug extends Check implements PostPredictionCheck {
|
||||
|
||||
Location location = new Location(player.x, player.y, player.z, player.xRot, player.yRot, player.bukkitPlayer == null ? "null" : player.bukkitPlayer.getWorld().getName());
|
||||
|
||||
for (Iterator<Object2IntMap.Entry<StringBuilder>> it = continuedDebug.object2IntEntrySet().iterator(); it.hasNext(); ) {
|
||||
for (Iterator<Map.Entry<StringBuilder, Integer>> it = continuedDebug.entrySet().iterator(); it.hasNext(); ) {
|
||||
Map.Entry<StringBuilder, Integer> debug = it.next();
|
||||
appendDebug(debug.getKey(), player.predictedVelocity, player.actualMovement, location, player.startTickClientVel, player.baseTickAddition, player.baseTickWaterPushing);
|
||||
debug.setValue(debug.getValue() - 1);
|
||||
@@ -83,11 +78,11 @@ public final class SuperDebug extends Check implements PostPredictionCheck {
|
||||
|
||||
for (int i = 0; i < predicted.size(); i++) {
|
||||
VectorData predict = predicted.get(i);
|
||||
Vector3D actual = actually.get(i);
|
||||
Vector actual = actually.get(i);
|
||||
Location loc = locations.get(i);
|
||||
Vector3D startTickVel = startTickClientVel.get(i);
|
||||
Vector3D addition = baseTickAddition.get(i);
|
||||
Vector3D water = baseTickWater.get(i);
|
||||
Vector startTickVel = startTickClientVel.get(i);
|
||||
Vector addition = baseTickAddition.get(i);
|
||||
Vector water = baseTickWater.get(i);
|
||||
appendDebug(sb, predict, actual, loc, startTickVel, addition, water);
|
||||
}
|
||||
|
||||
@@ -192,7 +187,7 @@ public final class SuperDebug extends Check implements PostPredictionCheck {
|
||||
continuedDebug.put(sb, 40);
|
||||
}
|
||||
|
||||
private void appendDebug(StringBuilder sb, VectorData predict, Vector3D actual, Location location, Vector3D startTick, Vector3D addition, Vector3D water) {
|
||||
private void appendDebug(StringBuilder sb, VectorData predict, Vector actual, Location location, Vector startTick, Vector addition, Vector water) {
|
||||
if (predict.isZeroPointZeroThree()) {
|
||||
sb.append("Movement threshold/tick skipping\n");
|
||||
}
|
||||
@@ -228,11 +223,11 @@ public final class SuperDebug extends Check implements PostPredictionCheck {
|
||||
// Apply 0.003/0.005 to make numbers more accurate
|
||||
Set<VectorData> set = new HashSet<>(Collections.singletonList(new VectorData(startTick.clone(), VectorData.VectorType.BestVelPicked)));
|
||||
new PredictionEngine().applyMovementThreshold(player, set);
|
||||
Vector3D trueStartVel = ((VectorData) set.toArray()[0]).vector;
|
||||
Vector trueStartVel = ((VectorData) set.toArray()[0]).vector;
|
||||
|
||||
Vector3D clientMovement = getPlayerMathMovement(player, actual.clone().subtract(trueStartVel), location.xRot);
|
||||
Vector3D simulatedMovement = getPlayerMathMovement(player, predict.vector.clone().subtract(trueStartVel), location.xRot);
|
||||
Vector3D offset = actual.clone().subtract(predict.vector);
|
||||
Vector clientMovement = getPlayerMathMovement(player, actual.clone().subtract(trueStartVel), location.xRot);
|
||||
Vector simulatedMovement = getPlayerMathMovement(player, predict.vector.clone().subtract(trueStartVel), location.xRot);
|
||||
Vector offset = actual.clone().subtract(predict.vector);
|
||||
trueStartVel.add(addition);
|
||||
trueStartVel.add(water);
|
||||
|
||||
@@ -271,14 +266,14 @@ public final class SuperDebug extends Check implements PostPredictionCheck {
|
||||
sb.append("\n\n");
|
||||
}
|
||||
|
||||
private Vector3D getPlayerMathMovement(GrimPlayer player, Vector3D wantedMovement, float f2) {
|
||||
private Vector getPlayerMathMovement(GrimPlayer player, Vector wantedMovement, float f2) {
|
||||
float f3 = player.trigHandler.sin(f2 * 0.017453292f);
|
||||
float f4 = player.trigHandler.cos(f2 * 0.017453292f);
|
||||
|
||||
float bestTheoreticalX = (float) (f3 * wantedMovement.getZ() + f4 * wantedMovement.getX()) / (f3 * f3 + f4 * f4);
|
||||
float bestTheoreticalZ = (float) (-f3 * wantedMovement.getX() + f4 * wantedMovement.getZ()) / (f3 * f3 + f4 * f4);
|
||||
|
||||
return newVector3D(bestTheoreticalX, 0, bestTheoreticalZ);
|
||||
return new Vector(bestTheoreticalX, 0, bestTheoreticalZ);
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
@@ -292,4 +287,4 @@ public final class SuperDebug extends Check implements PostPredictionCheck {
|
||||
return "x: " + x + " y: " + y + " z: " + z + " xRot: " + xRot + " yRot: " + yRot + " world: " + world;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -58,4 +58,4 @@ public class TickEndEvent implements Initable {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
package ac.grim.grimac.manager.init.start;
|
||||
|
||||
import ac.grim.grimac.manager.init.Initable;
|
||||
import ac.grim.grimac.utils.anticheat.LogUtil;
|
||||
import com.viaversion.viaversion.api.Via;
|
||||
import io.github.retrooper.packetevents.util.viaversion.ViaVersionUtil;
|
||||
|
||||
public class ViaVersion implements Initable {
|
||||
@Override
|
||||
public void start() {
|
||||
if (!ViaVersionUtil.isAvailable()) return;
|
||||
if (Via.getConfig().getValues().containsKey("fix-1_21-placement-rotation") && Via.getConfig().fix1_21PlacementRotation()) {
|
||||
LogUtil.warn("GrimAC has detected that you are using ViaVersion with the `fix-1_21-placement-rotation` option enabled.");
|
||||
LogUtil.warn("This option is known to cause issues with GrimAC and may result in false positives and bypasses.");
|
||||
LogUtil.warn("Please disable this option in your ViaVersion configuration to prevent these issues.");
|
||||
}
|
||||
}
|
||||
}
|
||||
Loaded 100 of 211 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user