Compare commits
48
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
15984b0a94 | ||
|
|
97de474b79 | ||
|
|
cea13a719d | ||
|
|
faa471b197 | ||
|
|
60f8812efd | ||
|
|
7e82f19961 | ||
|
|
27aae68f14 | ||
|
|
a65f24424f | ||
|
|
bfd3433423 | ||
|
|
09e6cec6ef | ||
|
|
4ffe6f4fc5 | ||
|
|
4aaeb579e7 | ||
|
|
487e9c6590 | ||
|
|
bdf7eb7c06 | ||
|
|
c70e5b8fff | ||
|
|
9599b1c631 | ||
|
|
85b42fa90e | ||
|
|
0c1a6c7775 | ||
|
|
d4508fa36b | ||
|
|
3cb1bb3792 | ||
|
|
faf0c7d3d6 | ||
|
|
c8ff1109e1 | ||
|
|
de0c28beab | ||
|
|
acdacffcc0 | ||
|
|
3cab3fe680 | ||
|
|
880a7b5e74 | ||
|
|
c4848efc8a | ||
|
|
0ddf0b5d22 | ||
|
|
fde6e03b98 | ||
|
|
55c084216d | ||
|
|
f3074e3934 | ||
|
|
748eb398b8 | ||
|
|
dc7f6dca93 | ||
|
|
472415e0d4 | ||
|
|
da61ff673a | ||
|
|
01ca8c894e | ||
|
|
f724d6d78e | ||
|
|
ee6183db90 | ||
|
|
e959ef37db | ||
|
|
f62d8602b8 | ||
|
|
bf44dd6855 | ||
|
|
1beedd77c3 | ||
|
|
c34ad88a13 | ||
|
|
619e7f1404 | ||
|
|
927b330c4b | ||
|
|
bff6854189 | ||
|
|
290bf9032e | ||
|
|
2629536ad7 |
No files matched your search
@@ -39,11 +39,11 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v4
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v1
|
||||
uses: github/codeql-action/init@v3
|
||||
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@v1
|
||||
uses: github/codeql-action/autobuild@v3
|
||||
|
||||
# ℹ️ 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@v1
|
||||
uses: github/codeql-action/analyze@v3
|
||||
@@ -19,9 +19,9 @@ jobs:
|
||||
packages: write
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Set up JDK 17
|
||||
uses: actions/setup-java@v3
|
||||
uses: actions/setup-java@v4
|
||||
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/gradle-build-action@67421db6bd0bf253fb4bd25b31ebb98943c375e1
|
||||
uses: gradle/actions/setup-gradle@v3
|
||||
with:
|
||||
arguments: build
|
||||
- name: Upload a Build Artifact
|
||||
uses: actions/upload-artifact@v3.1.0
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
path: /home/runner/work/Grim/Grim/build/libs/**.jar
|
||||
+7
-5
@@ -11,8 +11,8 @@ plugins {
|
||||
group = "ac.grim.grimac"
|
||||
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_1_8
|
||||
java.targetCompatibility = JavaVersion.VERSION_1_8
|
||||
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
|
||||
@@ -44,13 +44,14 @@ dependencies {
|
||||
implementation("it.unimi.dsi:fastutil:8.5.13")
|
||||
implementation("github.scarsz:configuralize:1.4.0")
|
||||
|
||||
implementation("com.github.grimanticheat:grimapi:1193c4fa41")
|
||||
// Used for local testing: implementation("ac.grim.grimac:grimapi:1.0")
|
||||
//implementation("com.github.grimanticheat:grimapi:1193c4fa41")
|
||||
// Used for local testing: implementation("ac.grim.grimac:GRIMAPI:1.0")
|
||||
implementation("com.github.grimanticheat:grimapi:fc5634e444")
|
||||
|
||||
implementation("org.jetbrains:annotations:24.1.0")
|
||||
compileOnly("org.geysermc.floodgate:api:2.0-SNAPSHOT")
|
||||
compileOnly("org.spigotmc:spigot-api:1.18.2-R0.1-SNAPSHOT")
|
||||
compileOnly("com.viaversion:viaversion-api:4.9.4-SNAPSHOT")
|
||||
compileOnly("com.viaversion:viaversion-api:5.0.4-SNAPSHOT")
|
||||
//
|
||||
compileOnly("io.netty:netty-all:4.1.85.Final")
|
||||
}
|
||||
@@ -59,6 +60,7 @@ bukkit {
|
||||
name = "GrimAC"
|
||||
author = "GrimAC"
|
||||
main = "ac.grim.grimac.GrimAC"
|
||||
website = "https://grim.ac/"
|
||||
apiVersion = "1.13"
|
||||
foliaSupported = true
|
||||
|
||||
|
||||
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.9-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.1-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
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();
|
||||
@@ -19,12 +18,10 @@ public enum GrimAPI {
|
||||
private final TickManager tickManager = new TickManager();
|
||||
private final GrimExternalAPI externalAPI = new GrimExternalAPI(this);
|
||||
private InitManager initManager;
|
||||
private ConfigManager configManager;
|
||||
private JavaPlugin plugin;
|
||||
|
||||
public void load(final JavaPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
this.configManager = new ConfigManager();
|
||||
initManager = new InitManager();
|
||||
initManager.load();
|
||||
}
|
||||
@@ -32,7 +29,6 @@ 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,25 +1,34 @@
|
||||
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;
|
||||
import io.github.retrooper.packetevents.util.folia.FoliaScheduler;
|
||||
import lombok.Getter;
|
||||
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;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Function;
|
||||
|
||||
//This is used for grim's external API. It has its own class just for organization.
|
||||
public class GrimExternalAPI implements GrimAbstractAPI, Initable {
|
||||
|
||||
public class GrimExternalAPI implements GrimAbstractAPI, ConfigReloadObserver, Initable {
|
||||
|
||||
private final GrimAPI api;
|
||||
|
||||
@@ -41,7 +50,8 @@ public class GrimExternalAPI implements GrimAbstractAPI, Initable {
|
||||
@Getter
|
||||
private final Map<String, Function<GrimUser, String>> variableReplacements = new ConcurrentHashMap<>();
|
||||
|
||||
@Getter private final Map<String, String> staticReplacements = new ConcurrentHashMap<>();
|
||||
@Getter
|
||||
private final Map<String, String> staticReplacements = new ConcurrentHashMap<>();
|
||||
|
||||
public String replaceVariables(GrimUser user, String content, boolean colors) {
|
||||
if (colors) content = ChatColor.translateAlternateColorCodes('&', content);
|
||||
@@ -56,12 +66,20 @@ public class GrimExternalAPI implements GrimAbstractAPI, Initable {
|
||||
|
||||
@Override
|
||||
public void registerVariable(String string, Function<GrimUser, String> replacement) {
|
||||
variableReplacements.put(string, replacement);
|
||||
if (replacement == null) {
|
||||
variableReplacements.remove(string);
|
||||
} else {
|
||||
variableReplacements.put(string, replacement);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerVariable(String variable, String replacement) {
|
||||
staticReplacements.put(variable, replacement);
|
||||
if (replacement == null) {
|
||||
staticReplacements.remove(variable);
|
||||
} else {
|
||||
staticReplacements.put(variable, replacement);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -70,34 +88,20 @@ public class GrimExternalAPI implements GrimAbstractAPI, Initable {
|
||||
return description.getVersion();
|
||||
}
|
||||
|
||||
private final Map<String, Function<Object, Object>> functions = new ConcurrentHashMap<>();
|
||||
|
||||
@Override
|
||||
public void registerFunction(String key, Function<Object, Object> function) {
|
||||
|
||||
if (function == null) {
|
||||
functions.remove(key);
|
||||
} else {
|
||||
functions.put(key, function);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Function<Object, Object> getFunction(String key) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
GrimAPI.INSTANCE.getConfigManager().reload();
|
||||
//Reload checks for all players
|
||||
for (GrimPlayer grimPlayer : GrimAPI.INSTANCE.getPlayerDataManager().getEntries()) {
|
||||
ChannelHelper.runInEventLoop(grimPlayer.user.getChannel(), () -> {
|
||||
grimPlayer.onReload();
|
||||
grimPlayer.updatePermissions();
|
||||
grimPlayer.punishmentManager.reload();
|
||||
for (AbstractCheck value : grimPlayer.checkManager.allChecks.values()) {
|
||||
value.reload();
|
||||
}
|
||||
});
|
||||
}
|
||||
//Restart
|
||||
GrimAPI.INSTANCE.getDiscordManager().start();
|
||||
GrimAPI.INSTANCE.getSpectateManager().start();
|
||||
GrimAPI.INSTANCE.getExternalAPI().start();
|
||||
return functions.get(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -106,16 +110,106 @@ public class GrimExternalAPI implements GrimAbstractAPI, Initable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
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»")));
|
||||
public ConfigManager getConfigManager() {
|
||||
return configManager;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload(ConfigManager config) {
|
||||
if (config.isLoadedAsync() && started) {
|
||||
FoliaScheduler.getAsyncScheduler().runNow(GrimAPI.INSTANCE.getPlugin(),
|
||||
o -> successfulReload(config));
|
||||
} else {
|
||||
successfulReload(config);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> reloadAsync(ConfigManager config) {
|
||||
if (config.isLoadedAsync() && started) {
|
||||
CompletableFuture<Boolean> future = new CompletableFuture<>();
|
||||
FoliaScheduler.getAsyncScheduler().runNow(GrimAPI.INSTANCE.getPlugin(),
|
||||
o -> future.complete(successfulReload(config)));
|
||||
return future;
|
||||
}
|
||||
return CompletableFuture.completedFuture(successfulReload(config));
|
||||
}
|
||||
|
||||
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(),
|
||||
o -> Bukkit.getPluginManager().callEvent(new GrimReloadEvent(true)));
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (started) 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
|
||||
for (GrimPlayer grimPlayer : GrimAPI.INSTANCE.getPlayerDataManager().getEntries()) {
|
||||
ChannelHelper.runInEventLoop(grimPlayer.user.getChannel(), () -> {
|
||||
grimPlayer.updatePermissions();
|
||||
grimPlayer.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());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,11 +2,12 @@ package ac.grim.grimac.checks;
|
||||
|
||||
import ac.grim.grimac.GrimAPI;
|
||||
import ac.grim.grimac.api.AbstractCheck;
|
||||
import ac.grim.grimac.api.config.ConfigManager;
|
||||
import ac.grim.grimac.api.events.FlagEvent;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.common.ConfigReloadObserver;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
|
||||
import com.github.retrooper.packetevents.protocol.packettype.PacketTypeCommon;
|
||||
import github.scarsz.configuralize.DynamicConfig;
|
||||
import io.github.retrooper.packetevents.util.folia.FoliaScheduler;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
@@ -14,7 +15,7 @@ import org.bukkit.Bukkit;
|
||||
|
||||
// Class from https://github.com/Tecnio/AntiCheatBase/blob/master/src/main/java/me/tecnio/anticheat/check/Check.java
|
||||
@Getter
|
||||
public class Check implements AbstractCheck {
|
||||
public class Check implements AbstractCheck, ConfigReloadObserver {
|
||||
protected final GrimPlayer player;
|
||||
|
||||
public double violations;
|
||||
@@ -53,7 +54,7 @@ public class Check implements AbstractCheck {
|
||||
this.experimental = checkData.experimental();
|
||||
this.description = checkData.description();
|
||||
}
|
||||
|
||||
//
|
||||
reload();
|
||||
}
|
||||
|
||||
@@ -81,7 +82,7 @@ public class Check implements AbstractCheck {
|
||||
}
|
||||
|
||||
public final boolean flag() {
|
||||
if (player.disableGrim || (experimental && !GrimAPI.INSTANCE.getConfigManager().isExperimentalChecks()) || exempted)
|
||||
if (player.disableGrim || (experimental && !player.isExperimentalChecks()) || exempted)
|
||||
return false; // Avoid calling event if disabled
|
||||
|
||||
FlagEvent event = new FlagEvent(player, this);
|
||||
@@ -107,23 +108,24 @@ public class Check implements AbstractCheck {
|
||||
violations = Math.max(0, violations - decay);
|
||||
}
|
||||
|
||||
public void reload() {
|
||||
decay = getConfig().getDoubleElse(configName + ".decay", decay);
|
||||
setbackVL = getConfig().getDoubleElse(configName + ".setbackvl", setbackVL);
|
||||
|
||||
@Override
|
||||
public void reload(ConfigManager configuration) {
|
||||
decay = configuration.getDoubleElse(configName + ".decay", decay);
|
||||
setbackVL = configuration.getDoubleElse(configName + ".setbackvl", setbackVL);
|
||||
if (setbackVL == -1) setbackVL = Double.MAX_VALUE;
|
||||
|
||||
updateExempted();
|
||||
onReload(configuration);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReload(ConfigManager config) {
|
||||
|
||||
}
|
||||
|
||||
public boolean alert(String verbose) {
|
||||
return player.punishmentManager.handleAlert(player, verbose, this);
|
||||
}
|
||||
|
||||
public DynamicConfig getConfig() {
|
||||
return GrimAPI.INSTANCE.getConfigManager().getConfig();
|
||||
}
|
||||
|
||||
public boolean setbackIfAboveSetbackVL() {
|
||||
if (getViolations() > setbackVL) {
|
||||
return player.getSetbackTeleportUtil().executeViolationSetback();
|
||||
@@ -144,5 +146,10 @@ public class Check implements AbstractCheck {
|
||||
packetType == PacketType.Play.Client.WINDOW_CONFIRMATION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
reload(GrimAPI.INSTANCE.getConfigManager().getConfig());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,12 +19,14 @@ public class AimModulo360 extends Check implements RotationCheck {
|
||||
|
||||
@Override
|
||||
public void process(final RotationUpdate rotationUpdate) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
@@ -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.anticheat.MessageUtil;
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
||||
@@ -39,10 +40,6 @@ public class BadPacketsZ extends Check implements PacketCheck {
|
||||
return player.getClientVersion().isOlderThan(ClientVersion.V_1_14_4) || getBlockDamage(player, pos) < 1;
|
||||
}
|
||||
|
||||
private String formatted(Vector3i vec) {
|
||||
return vec == null ? "null" : vec.x + ", " + vec.y + ", " + vec.z;
|
||||
}
|
||||
|
||||
public void handle(PacketReceiveEvent event, WrapperPlayClientPlayerDigging dig) {
|
||||
if (dig.getAction() == DiggingAction.START_DIGGING) {
|
||||
final Vector3i pos = dig.getBlockPosition();
|
||||
@@ -57,7 +54,7 @@ public class BadPacketsZ extends Check implements PacketCheck {
|
||||
final Vector3i pos = dig.getBlockPosition();
|
||||
|
||||
if (shouldExempt(pos)) {
|
||||
lastCancelledBlock = null;
|
||||
lastCancelledBlock = pos;
|
||||
lastLastBlock = null;
|
||||
lastBlock = null;
|
||||
return;
|
||||
@@ -66,7 +63,7 @@ public class BadPacketsZ extends Check implements PacketCheck {
|
||||
if (!pos.equals(lastBlock)) {
|
||||
// https://github.com/GrimAnticheat/Grim/issues/1512
|
||||
if (player.getClientVersion().isOlderThan(ClientVersion.V_1_14_4) || (!lastBlockWasInstantBreak && pos.equals(lastCancelledBlock))) {
|
||||
if (flagAndAlert("action=CANCELLED_DIGGING" + ", last=" + formatted(lastBlock) + ", pos=" + formatted(pos))) {
|
||||
if (flagAndAlert("action=CANCELLED_DIGGING" + ", last=" + MessageUtil.toUnlabledString(lastBlock) + ", pos=" + MessageUtil.toUnlabledString(pos))) {
|
||||
if (shouldModifyPackets()) {
|
||||
event.setCancelled(true);
|
||||
player.onPacketCancel();
|
||||
@@ -87,7 +84,7 @@ public class BadPacketsZ extends Check implements PacketCheck {
|
||||
|
||||
// when a player looks away from the mined block, they send a cancel, and if they look at it again, they don't send another start. (thanks mojang!)
|
||||
if (!pos.equals(lastCancelledBlock) && (!lastBlockWasInstantBreak || player.getClientVersion().isOlderThan(ClientVersion.V_1_14_4)) && !pos.equals(lastBlock)) {
|
||||
if (flagAndAlert("action=FINISHED_DIGGING" + ", last=" + formatted(lastBlock) + ", pos=" + formatted(pos))) {
|
||||
if (flagAndAlert("action=FINISHED_DIGGING" + ", last=" + MessageUtil.toUnlabledString(lastBlock) + ", pos=" + MessageUtil.toUnlabledString(pos))) {
|
||||
if (shouldModifyPackets()) {
|
||||
event.setCancelled(true);
|
||||
player.onPacketCancel();
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
package ac.grim.grimac.checks.impl.combat;
|
||||
|
||||
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.PacketCheck;
|
||||
@@ -201,8 +202,9 @@ 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 (Vector lookVec : possibleLookDirs) {
|
||||
for (double eye : player.getPossibleEyeHeights()) {
|
||||
for (double eye : possibleEyeHeights) {
|
||||
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));
|
||||
|
||||
@@ -236,9 +238,8 @@ public class Reach extends Check implements PacketCheck {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
super.reload();
|
||||
this.cancelImpossibleHits = getConfig().getBooleanElse("Reach.block-impossible-hits", true);
|
||||
this.threshold = getConfig().getDoubleElse("Reach.threshold", 0.0005);
|
||||
public void onReload(ConfigManager config) {
|
||||
this.cancelImpossibleHits = config.getBooleanElse("Reach.block-impossible-hits", true);
|
||||
this.threshold = config.getDoubleElse("Reach.threshold", 0.0005);
|
||||
}
|
||||
}
|
||||
@@ -43,7 +43,10 @@ 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);
|
||||
if (shouldModifyPackets()) {
|
||||
wrapper.setOnGround(false);
|
||||
event.markForReEncode(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -59,10 +62,16 @@ 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());
|
||||
if (shouldModifyPackets()) {
|
||||
wrapper.setOnGround(!wrapper.isOnGround());
|
||||
event.markForReEncode(true);
|
||||
}
|
||||
}
|
||||
if (player.packetStateData.lastPacketWasTeleport) {
|
||||
if (shouldModifyPackets()) wrapper.setOnGround(false);
|
||||
if (shouldModifyPackets()) {
|
||||
wrapper.setOnGround(false);
|
||||
event.markForReEncode(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package ac.grim.grimac.checks.impl.misc;
|
||||
|
||||
import ac.grim.grimac.api.config.ConfigManager;
|
||||
import ac.grim.grimac.checks.type.BlockPlaceCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.anticheat.update.BlockPlace;
|
||||
@@ -63,10 +64,9 @@ public class GhostBlockMitigation extends BlockPlaceCheck {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
super.reload();
|
||||
allow = getConfig().getBooleanElse("exploit.allow-building-on-ghostblocks", true);
|
||||
distance = getConfig().getIntElse("exploit.distance-to-check-for-ghostblocks", 2);
|
||||
public void onReload(ConfigManager config) {
|
||||
allow = config.getBooleanElse("exploit.allow-building-on-ghostblocks", true);
|
||||
distance = config.getIntElse("exploit.distance-to-check-for-ghostblocks", 2);
|
||||
|
||||
if (distance < 2 || distance > 4) distance = 2;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package ac.grim.grimac.checks.impl.movement;
|
||||
|
||||
import ac.grim.grimac.api.config.ConfigManager;
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.PostPredictionCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
@@ -35,8 +36,7 @@ public class NegativeTimerCheck extends TimerCheck implements PostPredictionChec
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
super.reload();
|
||||
clockDrift = (long) (getConfig().getDoubleElse(getConfigName() + ".drift", 1200.0) * 1e6);
|
||||
public void onReload(ConfigManager config) {
|
||||
clockDrift = (long) (config.getDoubleElse(getConfigName() + ".drift", 1200.0) * 1e6);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package ac.grim.grimac.checks.impl.movement;
|
||||
|
||||
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;
|
||||
@@ -51,8 +52,7 @@ public class NoSlowA extends Check implements PostPredictionCheck {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
super.reload();
|
||||
offsetToFlag = getConfig().getDoubleElse("NoSlowA.threshold", 0.001);
|
||||
public void onReload(ConfigManager config) {
|
||||
offsetToFlag = config.getDoubleElse("NoSlowA.threshold", 0.001);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package ac.grim.grimac.checks.impl.movement;
|
||||
|
||||
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.PacketCheck;
|
||||
@@ -19,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) 120e6;
|
||||
long clockDrift;
|
||||
|
||||
long limitAbuseOverPing = 1000;
|
||||
long limitAbuseOverPing;
|
||||
|
||||
boolean hasGottenMovementAfterTransaction = false;
|
||||
|
||||
@@ -115,9 +116,8 @@ public class TimerCheck extends Check implements PacketCheck {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
super.reload();
|
||||
clockDrift = (long) (getConfig().getDoubleElse(getConfigName() + ".drift", 120.0) * 1e6);
|
||||
limitAbuseOverPing = (long) (getConfig().getDoubleElse(getConfigName() + ".ping-abuse-limit-threshold", 1000));
|
||||
public void onReload(ConfigManager config) {
|
||||
clockDrift = (long) (config.getDoubleElse(getConfigName() + ".drift", 120.0) * 1e6);
|
||||
limitAbuseOverPing = (long) (config.getDoubleElse(getConfigName() + ".ping-abuse-limit-threshold", 1000));
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package ac.grim.grimac.checks.impl.prediction;
|
||||
|
||||
import ac.grim.grimac.api.config.ConfigManager;
|
||||
import ac.grim.grimac.api.events.CompletePredictionEvent;
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
@@ -99,14 +100,12 @@ public class OffsetHandler extends Check implements PostPredictionCheck {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
super.reload();
|
||||
setbackDecayMultiplier = getConfig().getDoubleElse("Simulation.setback-decay-multiplier", 0.999);
|
||||
threshold = getConfig().getDoubleElse("Simulation.threshold", 0.001);
|
||||
immediateSetbackThreshold = getConfig().getDoubleElse("Simulation.immediate-setback-threshold", 0.1);
|
||||
maxAdvantage = getConfig().getDoubleElse("Simulation.max-advantage", 1);
|
||||
maxCeiling = getConfig().getDoubleElse("Simulation.max-ceiling", 4);
|
||||
|
||||
public void onReload(ConfigManager config) {
|
||||
setbackDecayMultiplier = config.getDoubleElse("Simulation.setback-decay-multiplier", 0.999);
|
||||
threshold = config.getDoubleElse("Simulation.threshold", 0.001);
|
||||
immediateSetbackThreshold = config.getDoubleElse("Simulation.immediate-setback-threshold", 0.1);
|
||||
maxAdvantage = config.getDoubleElse("Simulation.max-advantage", 1);
|
||||
maxCeiling = config.getDoubleElse("Simulation.max-ceiling", 4);
|
||||
if (maxAdvantage == -1) maxAdvantage = Double.MAX_VALUE;
|
||||
if (immediateSetbackThreshold == -1) immediateSetbackThreshold = Double.MAX_VALUE;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package ac.grim.grimac.checks.impl.scaffolding;
|
||||
|
||||
import ac.grim.grimac.api.config.ConfigManager;
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.BlockPlaceCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
@@ -29,8 +30,7 @@ public class AirLiquidPlace extends BlockPlaceCheck {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
super.reload();
|
||||
this.cancelVL = getConfig().getIntElse(getConfigName() + ".cancelVL", 0);
|
||||
public void onReload(ConfigManager config) {
|
||||
this.cancelVL = config.getIntElse(getConfigName() + ".cancelVL", 0);
|
||||
}
|
||||
}
|
||||
@@ -26,7 +26,8 @@ public class FarPlace extends BlockPlaceCheck {
|
||||
if (place.getMaterial() == StateTypes.SCAFFOLDING) return;
|
||||
|
||||
double min = Double.MAX_VALUE;
|
||||
for (double d : player.getPossibleEyeHeights()) {
|
||||
final double[] possibleEyeHeights = player.getPossibleEyeHeights();
|
||||
for (double d : possibleEyeHeights) {
|
||||
SimpleCollisionBox box = new SimpleCollisionBox(blockPos);
|
||||
Vector eyes = new Vector(player.x, player.y + d, player.z);
|
||||
Vector best = VectorUtils.cutBoxToVector(eyes, box);
|
||||
|
||||
@@ -63,7 +63,7 @@ public class MultiPlace extends BlockPlaceCheck {
|
||||
|
||||
@Override
|
||||
public void onPredictionComplete(PredictionComplete predictionComplete) {
|
||||
if (player.getClientVersion().isNewerThan(ClientVersion.V_1_8) && !player.skippedTickInActualMovement) {
|
||||
if (player.getClientVersion().isNewerThan(ClientVersion.V_1_8) && !player.skippedTickInActualMovement && predictionComplete.isChecked()) {
|
||||
for (String verbose : flags) {
|
||||
flagAndAlert(verbose);
|
||||
}
|
||||
|
||||
@@ -28,8 +28,13 @@ public class PositionPlace extends BlockPlaceCheck {
|
||||
// Each position represents the best case scenario to have clicked
|
||||
//
|
||||
// We will now calculate the most optimal position for the player's head to be in
|
||||
double minEyeHeight = Collections.min(player.getPossibleEyeHeights());
|
||||
double maxEyeHeight = Collections.max(player.getPossibleEyeHeights());
|
||||
final double[] possibleEyeHeights = player.getPossibleEyeHeights();
|
||||
double minEyeHeight = Double.MAX_VALUE;
|
||||
double maxEyeHeight = Double.MIN_VALUE;
|
||||
for (double height : possibleEyeHeights) {
|
||||
minEyeHeight = Math.min(minEyeHeight, height);
|
||||
maxEyeHeight = Math.max(maxEyeHeight, height);
|
||||
}
|
||||
// I love the idle packet, why did you remove it mojang :(
|
||||
// Don't give 0.03 lenience if the player is a 1.8 player and we know they couldn't have 0.03'd because idle packet
|
||||
double movementThreshold = !player.packetStateData.didLastMovementIncludePosition || player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_9) ? player.getMovementThreshold() : 0;
|
||||
|
||||
@@ -75,9 +75,15 @@ public class RotationPlace extends BlockPlaceCheck {
|
||||
new Vector3f(player.lastXRot, player.yRot, 0)
|
||||
));
|
||||
|
||||
final double[] possibleEyeHeights = player.getPossibleEyeHeights();
|
||||
|
||||
// Start checking if player is in the block
|
||||
double minEyeHeight = Collections.min(player.getPossibleEyeHeights());
|
||||
double maxEyeHeight = Collections.max(player.getPossibleEyeHeights());
|
||||
double minEyeHeight = Double.MAX_VALUE;
|
||||
double maxEyeHeight = Double.MIN_VALUE;
|
||||
for (double height : possibleEyeHeights) {
|
||||
minEyeHeight = Math.min(minEyeHeight, height);
|
||||
maxEyeHeight = Math.max(maxEyeHeight, height);
|
||||
}
|
||||
|
||||
SimpleCollisionBox eyePositions = new SimpleCollisionBox(player.x, player.y + minEyeHeight, player.z, player.x, player.y + maxEyeHeight, player.z);
|
||||
eyePositions.expand(player.getMovementThreshold());
|
||||
@@ -99,7 +105,7 @@ public class RotationPlace extends BlockPlaceCheck {
|
||||
}
|
||||
|
||||
final double distance = player.compensatedEntities.getSelf().getAttributeValue(Attributes.PLAYER_BLOCK_INTERACTION_RANGE);
|
||||
for (double d : player.getPossibleEyeHeights()) {
|
||||
for (double d : possibleEyeHeights) {
|
||||
for (Vector3f lookDir : possibleLookDirs) {
|
||||
// x, y, z are correct for the block placement even after post tick because of code elsewhere
|
||||
Vector3d starting = new Vector3d(player.x, player.y + d, player.z);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package ac.grim.grimac.checks.impl.velocity;
|
||||
|
||||
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;
|
||||
@@ -18,7 +19,6 @@ 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 org.bukkit.Bukkit;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -256,12 +256,10 @@ public class ExplosionHandler extends Check implements PostPredictionCheck {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
super.reload();
|
||||
|
||||
offsetToFlag = getConfig().getDoubleElse("Explosion.threshold", 0.00001);
|
||||
setbackVL = getConfig().getDoubleElse("Explosion.setbackvl", 10);
|
||||
|
||||
public void onReload(ConfigManager config) {
|
||||
offsetToFlag = config.getDoubleElse("Explosion.threshold", 0.00001);
|
||||
setbackVL = config.getDoubleElse("Explosion.setbackvl", 10);
|
||||
if (setbackVL == -1) setbackVL = Double.MAX_VALUE;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package ac.grim.grimac.checks.impl.velocity;
|
||||
|
||||
import ac.grim.grimac.GrimAPI;
|
||||
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;
|
||||
@@ -240,15 +241,14 @@ public class KnockbackHandler extends Check implements PostPredictionCheck {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
super.reload();
|
||||
offsetToFlag = getConfig().getDoubleElse("Knockback.threshold", 0.001);
|
||||
maxAdv = getConfig().getDoubleElse("Knockback.max-advantage", 1);
|
||||
immediate = getConfig().getDoubleElse("Knockback.immediate-setback-threshold", 0.1);
|
||||
multiplier = getConfig().getDoubleElse("Knockback.setback-decay-multiplier", 0.999);
|
||||
ceiling = getConfig().getDoubleElse("Knockback.max-ceiling", 4);
|
||||
|
||||
public void onReload(ConfigManager config) {
|
||||
offsetToFlag = config.getDoubleElse("Knockback.threshold", 0.001);
|
||||
maxAdv = config.getDoubleElse("Knockback.max-advantage", 1);
|
||||
immediate = config.getDoubleElse("Knockback.immediate-setback-threshold", 0.1);
|
||||
multiplier = config.getDoubleElse("Knockback.setback-decay-multiplier", 0.999);
|
||||
ceiling = config.getDoubleElse("Knockback.max-ceiling", 4);
|
||||
if (maxAdv < 0) maxAdv = Double.MAX_VALUE;
|
||||
if (immediate < 0) immediate = Double.MAX_VALUE;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package ac.grim.grimac.checks.type;
|
||||
|
||||
import ac.grim.grimac.api.config.ConfigManager;
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.anticheat.update.BlockPlace;
|
||||
@@ -33,9 +34,8 @@ public class BlockPlaceCheck extends Check implements RotationCheck, PostPredict
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
super.reload();
|
||||
this.cancelVL = getConfig().getIntElse(getConfigName() + ".cancelVL", 5);
|
||||
public void onReload(ConfigManager config) {
|
||||
this.cancelVL = config.getIntElse(getConfigName() + ".cancelVL", 5);
|
||||
}
|
||||
|
||||
protected boolean shouldCancel() {
|
||||
|
||||
@@ -1,15 +1,11 @@
|
||||
package ac.grim.grimac.commands;
|
||||
|
||||
import ac.grim.grimac.GrimAPI;
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.anticheat.MessageUtil;
|
||||
import co.aikar.commands.BaseCommand;
|
||||
import co.aikar.commands.annotation.CommandAlias;
|
||||
import co.aikar.commands.annotation.CommandPermission;
|
||||
import co.aikar.commands.annotation.Subcommand;
|
||||
import com.github.retrooper.packetevents.netty.channel.ChannelHelper;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
@CommandAlias("grim|grimac")
|
||||
@@ -18,14 +14,15 @@ public class GrimReload extends BaseCommand {
|
||||
@CommandPermission("grim.reload")
|
||||
public void onReload(CommandSender sender) {
|
||||
//reload config
|
||||
try {
|
||||
GrimAPI.INSTANCE.getExternalAPI().reload();
|
||||
} catch (RuntimeException e) {
|
||||
sender.sendMessage(ChatColor.RED + e.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
sender.sendMessage(MessageUtil.format("%prefix% &fConfig has been reloaded."));
|
||||
sender.sendMessage(MessageUtil.format("%prefix% &7Reloading config..."));
|
||||
GrimAPI.INSTANCE.getExternalAPI().reloadAsync().exceptionally(throwable -> false)
|
||||
.thenAccept(bool -> {
|
||||
if (bool) {
|
||||
sender.sendMessage(MessageUtil.format("%prefix% &fConfig has been reloaded."));
|
||||
} else {
|
||||
sender.sendMessage(MessageUtil.format("%prefix% &cFailed to reload config."));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -20,7 +20,7 @@ public class GrimSendAlert extends BaseCommand {
|
||||
bukkitPlayer.sendMessage(string);
|
||||
}
|
||||
|
||||
if (GrimAPI.INSTANCE.getConfigManager().getConfig().getBooleanElse("alerts.print-to-console", true)) {
|
||||
if (GrimAPI.INSTANCE.getConfigManager().isPrintAlertsToConsole()) {
|
||||
LogUtil.console(string); // Print alert to console
|
||||
}
|
||||
}
|
||||
|
||||
@@ -348,7 +348,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 (GrimAPI.INSTANCE.getConfigManager().getConfig().getBooleanElse("cancel-duplicate-packet", true)) {
|
||||
if (player.isCancelDuplicatePacket()) {
|
||||
player.packetStateData.cancelDuplicatePacket = true;
|
||||
}
|
||||
} else {
|
||||
@@ -358,7 +358,7 @@ public class CheckManagerListener extends PacketListenerAbstract {
|
||||
|
||||
player.packetStateData.lastPacketWasOnePointSeventeenDuplicate = true;
|
||||
|
||||
if (!GrimAPI.INSTANCE.getConfigManager().isIgnoreDuplicatePacketRotation()) {
|
||||
if (!player.isIgnoreDuplicatePacketRotation()) {
|
||||
if (player.xRot != location.getYaw() || player.yRot != location.getPitch()) {
|
||||
player.lastXRot = player.xRot;
|
||||
player.lastYRot = player.yRot;
|
||||
@@ -428,7 +428,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 && GrimAPI.INSTANCE.getConfigManager().isIgnoreDuplicatePacketRotation();
|
||||
boolean ignoreRotation = player.packetStateData.lastPacketWasOnePointSeventeenDuplicate && player.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);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package ac.grim.grimac.events.packets;
|
||||
|
||||
import ac.grim.grimac.GrimAPI;
|
||||
import ac.grim.grimac.api.config.ConfigManager;
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.checks.type.PacketCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
@@ -53,7 +53,6 @@ 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);
|
||||
@@ -500,4 +499,12 @@ 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);
|
||||
}
|
||||
|
||||
}
|
||||
+15
-34
@@ -5,14 +5,11 @@ 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.wrapper.play.client.WrapperPlayClientPlayerFlying;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerEntityMetadata;
|
||||
import com.github.retrooper.packetevents.protocol.player.UserProfile;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPlayerInfo;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPlayerInfoUpdate;
|
||||
|
||||
@@ -20,22 +17,15 @@ import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
|
||||
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() {
|
||||
public class PacketHidePlayerInfo extends PacketListenerAbstract {
|
||||
|
||||
public PacketHidePlayerInfo() {
|
||||
super(PacketListenerPriority.HIGHEST);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPacketSend(PacketSendEvent event) {
|
||||
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) {
|
||||
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;
|
||||
@@ -62,8 +52,8 @@ public class PacketSetWrapperNull 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.setLastUsedWrapper(null);
|
||||
} else if (hideCount > 0) {
|
||||
event.markForReEncode(true);
|
||||
}
|
||||
}
|
||||
} else if (event.getPacketType() == PacketType.Play.Server.PLAYER_INFO_UPDATE) {
|
||||
@@ -81,12 +71,13 @@ public class PacketSetWrapperNull extends PacketListenerAbstract {
|
||||
for (WrapperPlayServerPlayerInfoUpdate.PlayerInfo entry : wrapper.getEntries()) {
|
||||
//check if the player should be hidden
|
||||
WrapperPlayServerPlayerInfoUpdate.PlayerInfo modifiedPacket = null;
|
||||
if (GrimAPI.INSTANCE.getSpectateManager().shouldHidePlayer(receiver, entry.getProfileId())) {
|
||||
final UserProfile gameProfile = entry.getGameProfile();
|
||||
if (GrimAPI.INSTANCE.getSpectateManager().shouldHidePlayer(receiver, gameProfile.getUUID())) {
|
||||
hideCount++;
|
||||
//modify & create a new packet from pre-existing one if they are a spectator
|
||||
if (entry.getGameMode() == GameMode.SPECTATOR) {
|
||||
modifiedPacket = new WrapperPlayServerPlayerInfoUpdate.PlayerInfo(
|
||||
entry.getGameProfile(),
|
||||
gameProfile,
|
||||
entry.isListed(),
|
||||
entry.getLatency(),
|
||||
GameMode.SURVIVAL,
|
||||
@@ -104,30 +95,20 @@ public class PacketSetWrapperNull extends PacketListenerAbstract {
|
||||
} //if only the game mode was updated and the packet was modified, don't send anything
|
||||
|
||||
}
|
||||
//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 the amount of hidden players & modified entries are the same
|
||||
if (hideCount == modified.size()) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package ac.grim.grimac.events.packets;
|
||||
|
||||
import ac.grim.grimac.GrimAPI;
|
||||
import ac.grim.grimac.api.config.ConfigManager;
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.checks.type.PacketCheck;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
@@ -37,7 +37,6 @@ 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) {
|
||||
@@ -56,4 +55,12 @@ 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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -24,6 +24,7 @@ import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public class PacketSelfMetadataListener extends PacketListenerAbstract {
|
||||
|
||||
public PacketSelfMetadataListener() {
|
||||
super(PacketListenerPriority.HIGH);
|
||||
}
|
||||
@@ -68,6 +69,7 @@ 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);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
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;
|
||||
@@ -33,6 +32,7 @@ import ac.grim.grimac.manager.init.start.SuperDebug;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.predictionengine.GhostBlockDetector;
|
||||
import ac.grim.grimac.predictionengine.SneakingEstimator;
|
||||
import ac.grim.grimac.utils.anticheat.LogUtil;
|
||||
import ac.grim.grimac.utils.anticheat.update.*;
|
||||
import ac.grim.grimac.utils.latency.CompensatedCooldown;
|
||||
import ac.grim.grimac.utils.latency.CompensatedFireworks;
|
||||
@@ -42,8 +42,13 @@ 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;
|
||||
|
||||
public class CheckManager {
|
||||
private static boolean inited;
|
||||
|
||||
ClassToInstanceMap<PacketCheck> packetChecks;
|
||||
ClassToInstanceMap<PositionCheck> positionCheck;
|
||||
ClassToInstanceMap<RotationCheck> rotationCheck;
|
||||
@@ -172,6 +177,8 @@ public class CheckManager {
|
||||
.putAll(blockPlaceCheck)
|
||||
.putAll(prePredictionChecks)
|
||||
.build();
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -324,4 +331,22 @@ public class CheckManager {
|
||||
public <T extends PostPredictionCheck> T getPostPredictionCheck(Class<T> check) {
|
||||
return (T) postPredictionCheck.get(check);
|
||||
}
|
||||
|
||||
private void init() {
|
||||
if (inited) return;
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inited = true;
|
||||
}
|
||||
}
|
||||
@@ -1,60 +1,72 @@
|
||||
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.ClassToInstanceMap;
|
||||
import com.google.common.collect.ImmutableClassToInstanceMap;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import lombok.Getter;
|
||||
|
||||
public class InitManager {
|
||||
ClassToInstanceMap<Initable> initializersOnLoad;
|
||||
ClassToInstanceMap<Initable> initializersOnStart;
|
||||
ClassToInstanceMap<Initable> initializersOnStop;
|
||||
|
||||
private final ImmutableList<Initable> initializersOnLoad;
|
||||
private final ImmutableList<Initable> initializersOnStart;
|
||||
private final ImmutableList<Initable> initializersOnStop;
|
||||
|
||||
@Getter private boolean loaded = false;
|
||||
@Getter private boolean started = false;
|
||||
@Getter private boolean stopped = false;
|
||||
|
||||
public InitManager() {
|
||||
initializersOnLoad = new ImmutableClassToInstanceMap.Builder<Initable>()
|
||||
.put(PacketEventsInit.class, new PacketEventsInit())
|
||||
initializersOnLoad = ImmutableList.<Initable>builder()
|
||||
.add(new PacketEventsInit())
|
||||
.add(() -> GrimAPI.INSTANCE.getExternalAPI().load())
|
||||
.build();
|
||||
|
||||
initializersOnStart = new ImmutableClassToInstanceMap.Builder<Initable>()
|
||||
.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(GrimExternalAPI.class, GrimAPI.INSTANCE.getExternalAPI())
|
||||
.put(JavaVersion.class, new JavaVersion())
|
||||
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())
|
||||
.build();
|
||||
|
||||
initializersOnStop = new ImmutableClassToInstanceMap.Builder<Initable>()
|
||||
.put(TerminatePacketEvents.class, new TerminatePacketEvents())
|
||||
initializersOnStop = ImmutableList.<Initable>builder()
|
||||
.add(new TerminatePacketEvents())
|
||||
.build();
|
||||
}
|
||||
|
||||
public void load() {
|
||||
for (Initable initable : initializersOnLoad.values()) {
|
||||
initable.start();
|
||||
}
|
||||
for (Initable initable : initializersOnLoad) handle(initable);
|
||||
loaded = true;
|
||||
}
|
||||
|
||||
public void start() {
|
||||
for (Initable initable : initializersOnStart.values()) {
|
||||
initable.start();
|
||||
}
|
||||
for (Initable initable : initializersOnStart) handle(initable);
|
||||
started = true;
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
for (Initable initable : initializersOnStop.values()) {
|
||||
for (Initable initable : initializersOnStop) handle(initable);
|
||||
stopped = true;
|
||||
}
|
||||
|
||||
private void handle(Initable initable) {
|
||||
try {
|
||||
initable.start();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,13 +2,14 @@ package ac.grim.grimac.manager;
|
||||
|
||||
import ac.grim.grimac.GrimAPI;
|
||||
import ac.grim.grimac.api.AbstractCheck;
|
||||
import ac.grim.grimac.api.config.ConfigManager;
|
||||
import ac.grim.grimac.api.config.ConfigReloadable;
|
||||
import ac.grim.grimac.api.events.CommandExecuteEvent;
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.events.packets.ProxyAlertMessenger;
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import ac.grim.grimac.utils.anticheat.LogUtil;
|
||||
import ac.grim.grimac.utils.anticheat.MessageUtil;
|
||||
import github.scarsz.configuralize.DynamicConfig;
|
||||
import io.github.retrooper.packetevents.util.folia.FoliaScheduler;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
@@ -17,21 +18,27 @@ import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class PunishmentManager {
|
||||
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();
|
||||
}
|
||||
|
||||
public void reload() {
|
||||
DynamicConfig config = 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();
|
||||
|
||||
@@ -111,8 +118,6 @@ public class PunishmentManager {
|
||||
}
|
||||
|
||||
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
|
||||
@@ -128,7 +133,7 @@ public class PunishmentManager {
|
||||
for (Player bukkitPlayer : GrimAPI.INSTANCE.getAlertManager().getEnabledVerbose()) {
|
||||
bukkitPlayer.sendMessage(cmd);
|
||||
}
|
||||
if (GrimAPI.INSTANCE.getConfigManager().getConfig().getBooleanElse("verbose.print-to-console", false)) {
|
||||
if (printToConsole) {
|
||||
LogUtil.console(cmd); // Print verbose to console
|
||||
}
|
||||
}
|
||||
@@ -146,9 +151,7 @@ public class PunishmentManager {
|
||||
String vl = group.violations.values().stream().filter((e) -> e == check).count() + "";
|
||||
GrimAPI.INSTANCE.getDiscordManager().sendAlert(player, verbose, check.getCheckName(), vl);
|
||||
} else if (command.command.equals("[proxy]")) {
|
||||
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);
|
||||
ProxyAlertMessenger.sendPluginMessage(replaceAlertPlaceholders(command.getCommand(), group, check, proxyAlertString, verbose));
|
||||
} else {
|
||||
if (command.command.equals("[alert]")) {
|
||||
sentDebug = true;
|
||||
@@ -160,9 +163,8 @@ public class PunishmentManager {
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+64
-63
@@ -1,57 +1,43 @@
|
||||
package ac.grim.grimac.manager;
|
||||
package ac.grim.grimac.manager.config;
|
||||
|
||||
import ac.grim.grimac.GrimAC;
|
||||
import ac.grim.grimac.GrimAPI;
|
||||
import ac.grim.grimac.api.common.BasicReloadable;
|
||||
import ac.grim.grimac.api.config.ConfigManager;
|
||||
import ac.grim.grimac.utils.anticheat.LogUtil;
|
||||
import ac.grim.grimac.utils.math.GrimMath;
|
||||
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 ConfigManager {
|
||||
@Getter
|
||||
public class ConfigManagerFileImpl implements ConfigManager, BasicReloadable {
|
||||
|
||||
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 int maxPingTransaction = 60; // This is just a really hot variable so cache it.
|
||||
@Getter
|
||||
private boolean ignoreDuplicatePacketRotation = false;
|
||||
|
||||
@Getter
|
||||
private boolean experimentalChecks = false;
|
||||
|
||||
private final List<Pattern> ignoredClientPatterns = new ArrayList<>();
|
||||
|
||||
public ConfigManager() {
|
||||
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());
|
||||
|
||||
reload();
|
||||
private File getConfigFile(String path) {
|
||||
return new File(GrimAPI.INSTANCE.getPlugin().getDataFolder(), path);
|
||||
}
|
||||
|
||||
public ConfigManagerFileImpl() {
|
||||
config = new DynamicConfig();
|
||||
}
|
||||
|
||||
private boolean initialized = false;
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
GrimAPI.INSTANCE.getPlugin().getDataFolder().mkdirs();
|
||||
if (!initialized) {
|
||||
initialized = true;
|
||||
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 {
|
||||
@@ -78,32 +64,6 @@ public class ConfigManager {
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to load config", e);
|
||||
}
|
||||
|
||||
final int configuredMaxTransactionTime = config.getIntElse("max-transaction-time", 60);
|
||||
maxPingTransaction = (int) GrimMath.clamp(configuredMaxTransactionTime, 1, 180);
|
||||
if (maxPingTransaction != configuredMaxTransactionTime) {
|
||||
LogUtil.warn("Detected invalid max-transaction-time! This setting is clamped between 1 and 180 to prevent issues. " +
|
||||
"Changed: " + configuredMaxTransactionTime + " -> " + maxPingTransaction);
|
||||
LogUtil.warn("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() {
|
||||
@@ -326,4 +286,45 @@ public class ConfigManager {
|
||||
);
|
||||
Files.write(config.toPath(), configString.getBytes());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStringElse(String key, String otherwise) {
|
||||
return config.getStringElse(key, otherwise);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getStringList(String key) {
|
||||
return config.getStringList(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getStringListElse(String key, List<String> otherwise) {
|
||||
return config.getStringListElse(key, otherwise);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIntElse(String key, int other) {
|
||||
return config.getIntElse(key, other);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLongElse(String key, long otherwise) {
|
||||
return config.getLongElse(key, otherwise);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getDoubleElse(String key, double otherwise) {
|
||||
return config.getDoubleElse(key, otherwise);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getBooleanElse(String key, boolean otherwise) {
|
||||
return config.getBooleanElse(key, otherwise);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T get(String key) {
|
||||
return config.get(key);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,8 +4,17 @@ 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() {
|
||||
@@ -16,7 +25,18 @@ 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();
|
||||
}
|
||||
}
|
||||
@@ -43,7 +43,7 @@ public class PacketManager implements Initable {
|
||||
}
|
||||
|
||||
PacketEvents.getAPI().getEventManager().registerListener(new ProxyAlertMessenger());
|
||||
PacketEvents.getAPI().getEventManager().registerListener(new PacketSetWrapperNull());
|
||||
PacketEvents.getAPI().getEventManager().registerListener(new PacketHidePlayerInfo());
|
||||
|
||||
PacketEvents.getAPI().init();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package ac.grim.grimac.player;
|
||||
import ac.grim.grimac.GrimAPI;
|
||||
import ac.grim.grimac.api.AbstractCheck;
|
||||
import ac.grim.grimac.api.GrimUser;
|
||||
import ac.grim.grimac.api.config.ConfigManager;
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.checks.impl.aim.processor.AimProcessor;
|
||||
import ac.grim.grimac.checks.impl.misc.ClientBrand;
|
||||
@@ -47,6 +48,7 @@ import io.github.retrooper.packetevents.adventure.serializer.legacy.LegacyCompon
|
||||
import io.github.retrooper.packetevents.util.folia.FoliaScheduler;
|
||||
import io.github.retrooper.packetevents.util.viaversion.ViaVersionUtil;
|
||||
import io.netty.channel.Channel;
|
||||
import lombok.Getter;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.TranslatableComponent;
|
||||
import org.bukkit.Bukkit;
|
||||
@@ -199,6 +201,8 @@ public class GrimPlayer implements GrimUser {
|
||||
public long lastBlockPlaceUseItem = 0;
|
||||
public AtomicInteger cancelledPackets = new AtomicInteger(0);
|
||||
public MainSupportingBlockData mainSupportingBlockData = new MainSupportingBlockData(null, false);
|
||||
// possibleEyeHeights[0] = Standing eye heights, [1] = Sneaking. [2] = Elytra, Swimming, and Riptide Trident which only exists in 1.9+
|
||||
public double[][] possibleEyeHeights = new double[3][];
|
||||
|
||||
public void onPacketCancel() {
|
||||
if (spamThreshold != -1 && cancelledPackets.incrementAndGet() > spamThreshold) {
|
||||
@@ -217,7 +221,6 @@ public class GrimPlayer implements GrimUser {
|
||||
public GrimPlayer(User user) {
|
||||
this.user = user;
|
||||
this.playerUUID = user.getUUID();
|
||||
onReload();
|
||||
|
||||
boundingBox = GetBoundingBox.getBoundingBoxFromPosAndSizeRaw(x, y, z, 0.6f, 1.8f);
|
||||
|
||||
@@ -240,6 +243,24 @@ public class GrimPlayer implements GrimUser {
|
||||
packetStateData = new PacketStateData();
|
||||
|
||||
uncertaintyHandler.collidingEntities.add(0);
|
||||
|
||||
if (getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_14)) {
|
||||
final float scale = (float) compensatedEntities.getSelf().getAttributeValue(Attributes.GENERIC_SCALE);
|
||||
possibleEyeHeights[2] = new double[]{0.4 * scale, 1.62 * scale, 1.27 * scale}; // Elytra, standing, sneaking (1.14)
|
||||
possibleEyeHeights[1] = new double[]{1.27 * scale, 1.62 * scale, 0.4 * scale}; // sneaking (1.14), standing, Elytra
|
||||
possibleEyeHeights[0] = new double[]{1.62 * scale, 1.27 * scale, 0.4 * scale}; // standing, sneaking (1.14), Elytra
|
||||
|
||||
} else if (getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_9)) { // standing, sneaking Elytra
|
||||
possibleEyeHeights[2] = new double[]{0.4, 1.62, 1.54}; // Elytra, standing, sneaking (1.13)
|
||||
possibleEyeHeights[1] = new double[]{1.54, 1.62, 0.4}; // sneaking (1.9-1.13), standing, Elytra
|
||||
possibleEyeHeights[0] = new double[]{1.62, 1.54, 0.4}; // standing, sneaking (1.9-1.13), Elytra
|
||||
} else {
|
||||
possibleEyeHeights[1] = new double[]{(double) (1.62f - 0.08f), (double) (1.62f)}; // sneaking, standing
|
||||
possibleEyeHeights[0] = new double[]{(double) (1.62f), (double) (1.62f - 0.08f)}; // standing, sneaking
|
||||
}
|
||||
|
||||
// reload last
|
||||
reload();
|
||||
}
|
||||
|
||||
public Set<VectorData> getPossibleVelocities() {
|
||||
@@ -316,7 +337,8 @@ public class GrimPlayer implements GrimUser {
|
||||
// Transactions that we send don't count towards total limit
|
||||
if (packetTracker != null) packetTracker.setIntervalPackets(packetTracker.getIntervalPackets() - 1);
|
||||
|
||||
if (skipped > 0 && System.currentTimeMillis() - joinTime > 5000) checkManager.getPacketCheck(TransactionOrder.class).flagAndAlert("skipped: " + skipped);
|
||||
if (skipped > 0 && System.currentTimeMillis() - joinTime > 5000)
|
||||
checkManager.getPacketCheck(TransactionOrder.class).flagAndAlert("skipped: " + skipped);
|
||||
|
||||
do {
|
||||
data = transactionsSent.poll();
|
||||
@@ -450,7 +472,7 @@ public class GrimPlayer implements GrimUser {
|
||||
if (lastTransSent != 0 && lastTransSent + 80 < System.currentTimeMillis()) {
|
||||
sendTransaction(true); // send on netty thread
|
||||
}
|
||||
if ((System.nanoTime() - getPlayerClockAtLeast()) > GrimAPI.INSTANCE.getConfigManager().getMaxPingTransaction() * 1e9) {
|
||||
if ((System.nanoTime() - getPlayerClockAtLeast()) > maxTransactionTime * 1e9) {
|
||||
timedOut();
|
||||
}
|
||||
|
||||
@@ -515,10 +537,6 @@ public class GrimPlayer implements GrimUser {
|
||||
|
||||
private int spamThreshold = 100;
|
||||
|
||||
public void onReload() {
|
||||
spamThreshold = GrimAPI.INSTANCE.getConfigManager().getConfig().getIntElse("packet-spam-threshold", 100);
|
||||
}
|
||||
|
||||
public boolean isPointThree() {
|
||||
return getClientVersion().isOlderThan(ClientVersion.V_1_18_2);
|
||||
}
|
||||
@@ -548,7 +566,7 @@ public class GrimPlayer implements GrimUser {
|
||||
// - 3 ticks is a magic value, but it should buffer out incorrect predictions somewhat.
|
||||
// 2. The player is in a vehicle
|
||||
public boolean isTickingReliablyFor(int ticks) {
|
||||
return (getClientVersion().isOlderThan(ClientVersion.V_1_9)
|
||||
return (getClientVersion().isOlderThan(ClientVersion.V_1_9)
|
||||
|| !uncertaintyHandler.lastPointThree.hasOccurredSince(ticks))
|
||||
|| compensatedEntities.getSelf().inVehicle();
|
||||
}
|
||||
@@ -561,14 +579,23 @@ public class GrimPlayer implements GrimUser {
|
||||
return checkManager.getInventory();
|
||||
}
|
||||
|
||||
public List<Double> getPossibleEyeHeights() { // We don't return sleeping eye height
|
||||
if (getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_14)) { // Elytra, sneaking (1.14), standing
|
||||
final float scale = (float) compensatedEntities.getSelf().getAttributeValue(Attributes.GENERIC_SCALE);
|
||||
return Arrays.asList(0.4 * scale, 1.27 * scale, 1.62 * scale);
|
||||
} else if (getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_9)) { // Elytra, sneaking, standing
|
||||
return Arrays.asList(0.4, 1.54, 1.62);
|
||||
} else { // Only sneaking or standing
|
||||
return Arrays.asList((double) (1.62f - 0.08f), (double) (1.62f));
|
||||
public double[] getPossibleEyeHeights() { // We don't return sleeping eye height
|
||||
// 1.8 Players once again ruin my clean switch-case
|
||||
if (this.getClientVersion().isOlderThan(ClientVersion.V_1_9)) {
|
||||
return this.isSneaking ? this.possibleEyeHeights[1] : this.possibleEyeHeights[0];
|
||||
} else {
|
||||
// 1.8 players just have their pose set to standing all the time
|
||||
switch (pose) {
|
||||
case FALL_FLYING: // Elytra gliding
|
||||
case SPIN_ATTACK: // Riptide trident
|
||||
case SWIMMING: // Swimming (includes crawling in 1.14+)
|
||||
return this.possibleEyeHeights[2]; // [swimming/gliding/riptide height, standing height, sneaking height]
|
||||
case NINE_CROUCHING:
|
||||
case CROUCHING:
|
||||
return this.possibleEyeHeights[1]; // [sneaking height, standing height, swimming/gliding/riptide height]
|
||||
default:
|
||||
return this.possibleEyeHeights[0]; // [standing height, sneaking height, swimming/gliding/riptide height]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -716,10 +743,31 @@ public class GrimPlayer implements GrimUser {
|
||||
return checkManager.allChecks.values();
|
||||
}
|
||||
|
||||
|
||||
public void runNettyTaskInMs(Runnable runnable, int ms) {
|
||||
Channel channel = (Channel) user.getChannel();
|
||||
channel.eventLoop().schedule(runnable, ms, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
private int maxTransactionTime = 60;
|
||||
@Getter private boolean ignoreDuplicatePacketRotation = false;
|
||||
@Getter private boolean experimentalChecks = false;
|
||||
@Getter private boolean cancelDuplicatePacket = true;
|
||||
|
||||
@Override
|
||||
public void reload(ConfigManager config) {
|
||||
spamThreshold = config.getIntElse("packet-spam-threshold", 100);
|
||||
maxTransactionTime = (int) GrimMath.clamp(config.getIntElse("max-transaction-time", 60), 1, 180);
|
||||
experimentalChecks = config.getBooleanElse("experimental-checks", false);
|
||||
ignoreDuplicatePacketRotation = config.getBooleanElse("ignore-duplicate-packet-rotation", false);
|
||||
cancelDuplicatePacket = config.getBooleanElse("cancel-duplicate-packet", true);
|
||||
// reload all checks
|
||||
for (AbstractCheck value : checkManager.allChecks.values()) value.reload(config);
|
||||
// reload punishment manager
|
||||
punishmentManager.reload(config);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
reload(GrimAPI.INSTANCE.getConfigManager().getConfig());
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package ac.grim.grimac.predictionengine;
|
||||
|
||||
import ac.grim.grimac.GrimAPI;
|
||||
import ac.grim.grimac.api.config.ConfigManager;
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.checks.impl.movement.EntityControl;
|
||||
import ac.grim.grimac.checks.impl.prediction.Phase;
|
||||
@@ -22,7 +22,6 @@ import ac.grim.grimac.utils.data.packetentity.PacketEntityHorse;
|
||||
import ac.grim.grimac.utils.data.packetentity.PacketEntityRideable;
|
||||
import ac.grim.grimac.utils.data.packetentity.PacketEntityTrackXRot;
|
||||
import ac.grim.grimac.utils.enums.Pose;
|
||||
import ac.grim.grimac.utils.inventory.EnchantmentHelper;
|
||||
import ac.grim.grimac.utils.latency.CompensatedWorld;
|
||||
import ac.grim.grimac.utils.math.GrimMath;
|
||||
import ac.grim.grimac.utils.math.VectorUtils;
|
||||
@@ -32,7 +31,6 @@ 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;
|
||||
import com.github.retrooper.packetevents.protocol.item.type.ItemType;
|
||||
import com.github.retrooper.packetevents.protocol.item.type.ItemTypes;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
@@ -544,8 +542,7 @@ public class MovementCheckRunner extends Check implements PositionCheck {
|
||||
player.checkManager.onPredictionFinish(new PredictionComplete(offset, update, wasChecked));
|
||||
|
||||
// Patch sprint jumping with elytra exploit
|
||||
if (player.bukkitPlayer != null && player.isGliding && player.predictedVelocity.isJump() && player.isSprinting
|
||||
&& !GrimAPI.INSTANCE.getConfigManager().getConfig().getBooleanElse("exploit.allow-sprint-jumping-when-using-elytra", true)) {
|
||||
if (player.bukkitPlayer != null && player.isGliding && player.predictedVelocity.isJump() && player.isSprinting && !allowSprintJumpingWithElytra) {
|
||||
SetbackTeleportUtil.SetbackPosWithVector lastKnownGoodPosition = player.getSetbackTeleportUtil().lastKnownGoodPosition;
|
||||
lastKnownGoodPosition.setVector(lastKnownGoodPosition.getVector().multiply(new Vector(0.6 * 0.91, 1, 0.6 * 0.91)));
|
||||
player.getSetbackTeleportUtil().executeNonSimulatingSetback();
|
||||
@@ -635,4 +632,12 @@ public class MovementCheckRunner extends Check implements PositionCheck {
|
||||
// (Patches issues with slime and other desync's)
|
||||
return riptideDiffToGround < riptideDiffToBase;
|
||||
}
|
||||
|
||||
private boolean allowSprintJumpingWithElytra = true;
|
||||
|
||||
@Override
|
||||
public void onReload(ConfigManager config) {
|
||||
allowSprintJumpingWithElytra = config.getBooleanElse("exploit.allow-sprint-jumping-when-using-elytra", true);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -29,13 +29,14 @@ public class MessageUtil {
|
||||
}
|
||||
|
||||
public String formatWithNoColor(String string) {
|
||||
return string.replace("%prefix%", GrimAPI.INSTANCE.getConfigManager().getConfig().getStringElse("prefix", "&bGrim &8»"));
|
||||
return string.replace("%prefix%", GrimAPI.INSTANCE.getConfigManager().getPrefix());
|
||||
}
|
||||
|
||||
private static final Pattern HEX_PATTERN = Pattern.compile("#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{8})");
|
||||
|
||||
private String translateHexCodes(String message) {
|
||||
final String hexPattern = "#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{8})";
|
||||
Matcher matcher = Pattern.compile(hexPattern).matcher(message);
|
||||
StringBuffer sb = new StringBuffer(message.length());
|
||||
Matcher matcher = HEX_PATTERN.matcher(message);
|
||||
StringBuilder sb = new StringBuilder(message.length());
|
||||
while (matcher.find()) {
|
||||
String hex = matcher.group(1);
|
||||
ChatColor color = ChatColor.of("#" + hex);
|
||||
@@ -44,4 +45,5 @@ public class MessageUtil {
|
||||
matcher.appendTail(sb);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package ac.grim.grimac.utils.common;
|
||||
|
||||
|
||||
import ac.grim.grimac.api.config.ConfigManager;
|
||||
|
||||
public interface ConfigReloadObserver {
|
||||
|
||||
void onReload(ConfigManager config);
|
||||
|
||||
}
|
||||
@@ -101,29 +101,29 @@ public final class ValuedAttribute {
|
||||
}
|
||||
|
||||
public double with(WrapperPlayServerUpdateAttributes.Property property) {
|
||||
double d0 = property.getValue();
|
||||
double baseValue = property.getValue();
|
||||
double additionSum = 0;
|
||||
double multiplyBaseSum = 0;
|
||||
double multiplyTotalProduct = 1.0;
|
||||
|
||||
List<WrapperPlayServerUpdateAttributes.PropertyModifier> modifiers = property.getModifiers();
|
||||
modifiers.removeIf(modifier -> modifier.getUUID().equals(SPRINTING_MODIFIER_UUID) || modifier.getName().getKey().equals("sprinting"));
|
||||
|
||||
for (WrapperPlayServerUpdateAttributes.PropertyModifier attributemodifier : modifiers) {
|
||||
if (attributemodifier.getOperation() == WrapperPlayServerUpdateAttributes.PropertyModifier.Operation.ADDITION)
|
||||
d0 += attributemodifier.getAmount();
|
||||
for (WrapperPlayServerUpdateAttributes.PropertyModifier modifier : modifiers) {
|
||||
switch (modifier.getOperation()) {
|
||||
case ADDITION:
|
||||
additionSum += modifier.getAmount();
|
||||
break;
|
||||
case MULTIPLY_BASE:
|
||||
multiplyBaseSum += modifier.getAmount();
|
||||
break;
|
||||
case MULTIPLY_TOTAL:
|
||||
multiplyTotalProduct *= (1.0 + modifier.getAmount());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
double d1 = d0;
|
||||
|
||||
for (WrapperPlayServerUpdateAttributes.PropertyModifier attributemodifier : modifiers) {
|
||||
if (attributemodifier.getOperation() == WrapperPlayServerUpdateAttributes.PropertyModifier.Operation.MULTIPLY_BASE)
|
||||
d1 += d0 * attributemodifier.getAmount();
|
||||
}
|
||||
|
||||
for (WrapperPlayServerUpdateAttributes.PropertyModifier attributemodifier : modifiers) {
|
||||
if (attributemodifier.getOperation() == WrapperPlayServerUpdateAttributes.PropertyModifier.Operation.MULTIPLY_TOTAL)
|
||||
d1 *= 1.0D + attributemodifier.getAmount();
|
||||
}
|
||||
|
||||
double newValue = GrimMath.clampFloat((float) d1, (float) min, (float) max);
|
||||
double newValue = GrimMath.clamp((baseValue + additionSum) * (1 + multiplyBaseSum) * multiplyTotalProduct, min, max);
|
||||
if (setRewriter != null) {
|
||||
newValue = setRewriter.apply(this.value, newValue);
|
||||
}
|
||||
|
||||
@@ -99,14 +99,19 @@ public class PacketEntity extends TypedPacketEntity {
|
||||
}
|
||||
|
||||
public void setAttribute(Attribute attribute, double value) {
|
||||
ValuedAttribute property = getAttribute(attribute).orElse(null);
|
||||
if (property == null) throw new IllegalArgumentException("Cannot set attribute " + attribute.getName() + " for entity " + getType().getName().toString() + "!");
|
||||
ValuedAttribute property = attributeMap.get(attribute);
|
||||
if (property == null) {
|
||||
throw new IllegalArgumentException("Cannot set attribute " + attribute.getName() + " for entity " + getType().getName().toString() + "!");
|
||||
}
|
||||
property.override(value);
|
||||
}
|
||||
|
||||
public double getAttributeValue(Attribute attribute) {
|
||||
return getAttribute(attribute).map(ValuedAttribute::get)
|
||||
.orElseThrow(() -> new IllegalArgumentException("Cannot get attribute " + attribute.getName() + " for entity " + getType().getName().toString() + "!"));
|
||||
final ValuedAttribute property = attributeMap.get(attribute);
|
||||
if (property == null) {
|
||||
throw new IllegalArgumentException("Cannot get attribute " + attribute.getName() + " for entity " + getType().getName().toString() + "!");
|
||||
}
|
||||
return property.get();
|
||||
}
|
||||
|
||||
public void resetAttributes() {
|
||||
|
||||
@@ -47,6 +47,28 @@ public class PacketEntitySelf extends PacketEntity {
|
||||
setAttribute(Attributes.GENERIC_STEP_HEIGHT, 0.5f);
|
||||
}
|
||||
|
||||
getAttribute(Attributes.GENERIC_SCALE).get().withSetRewriter((oldValue, newValue) -> {
|
||||
if (player.getClientVersion().isOlderThanOrEquals(ClientVersion.V_1_20_5) || (newValue).equals(oldValue)) {
|
||||
return oldValue;
|
||||
} else {
|
||||
// Elytra, standing, sneaking (1.14)
|
||||
player.possibleEyeHeights[2][0] = 0.4 * newValue;
|
||||
player.possibleEyeHeights[2][1] = 1.62 * newValue;
|
||||
player.possibleEyeHeights[2][2] = 1.27 * newValue;
|
||||
|
||||
// sneaking (1.14), standing, Elytra
|
||||
player.possibleEyeHeights[1][0] = 1.27 * newValue;
|
||||
player.possibleEyeHeights[1][1] = 1.62 * newValue;
|
||||
player.possibleEyeHeights[1][2] = 0.4 * newValue;
|
||||
|
||||
// standing, sneaking (1.14), Elytra
|
||||
player.possibleEyeHeights[0][0] = 1.62 * newValue;
|
||||
player.possibleEyeHeights[0][1] = 1.27 * newValue;
|
||||
player.possibleEyeHeights[0][2] = 0.4 * newValue;
|
||||
return newValue;
|
||||
}
|
||||
});
|
||||
|
||||
final ValuedAttribute movementSpeed = ValuedAttribute.ranged(Attributes.GENERIC_MOVEMENT_SPEED, 0.1f, 0, 1024);
|
||||
movementSpeed.with(new WrapperPlayServerUpdateAttributes.Property("MOVEMENT_SPEED", 0.1f, new ArrayList<>()));
|
||||
trackAttribute(movementSpeed);
|
||||
|
||||
@@ -181,7 +181,8 @@ public class ReachUtils {
|
||||
|
||||
double lowest = Double.MAX_VALUE;
|
||||
|
||||
for (double eyes : player.getPossibleEyeHeights()) {
|
||||
final double[] possibleEyeHeights = player.getPossibleEyeHeights();
|
||||
for (double eyes : possibleEyeHeights) {
|
||||
if (giveMovementThresholdLenience) targetBox.expand(player.getMovementThreshold());
|
||||
Vector from = new Vector(player.x, player.y + eyes, player.z);
|
||||
Vector closestPoint = VectorUtils.cutBoxToVector(from, targetBox);
|
||||
|
||||
@@ -87,7 +87,7 @@ RotationPlace:
|
||||
# Vérification de no-slow basée sur la prédiction.
|
||||
# Grim tient compte des problèmes de netcode ici... difficile à tromper même en spamant le clic droit et le bouton de la main secondaire.
|
||||
# Bien plus stable que les autres anti-triche, mais veuillez signaler toute fausse détection... J'ai corrigé de nombreux problèmes de netcode ici.
|
||||
NoSlow:
|
||||
NoSlowA:
|
||||
# Quel est le niveau d'écart considéré comme "triche"
|
||||
# Par défaut, cela est inférieur à d'autres écarts.
|
||||
# Génère des avertissements avec des valeurs comprises entre 0,03 et 0,2 lors de l'utilisation de NoSlow
|
||||
|
||||
Reference in new issue
Block a user