Skip to content

Commit

Permalink
Update LightAntiCheat's hook implementation (fixes #120)
Browse files Browse the repository at this point in the history
  • Loading branch information
2008Choco committed Aug 27, 2024
1 parent 5d85b3c commit b1e8f2a
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 48 deletions.
2 changes: 2 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ anticheat-aac = "5.0.0"
anticheat-matrix = "317d4635fd" # This repository is dead now, but we're going to keep using it because it exists on JitPack :)
anticheat-nocheatplus = "3.16.1-SNAPSHOT"
anticheat-spartan = "1.0"
anticheat-light = "99d1930f2a" # https://github.com/tiredvekster/LightAntiCheat/commit/99d1930f2afa0e5dd23a5e212aadf49499e3fd83
bstats = "3.0.2"
mcmmo = "2.1.228"
placeholder-api = "2.11.5"
Expand Down Expand Up @@ -42,6 +43,7 @@ anticheat-aac = { module = "de.janmm14:aac-api", version.ref = "anticheat-aac" }
anticheat-matrix = { module = "com.github.jiangdashao:matrix-api-repo", version.ref = "anticheat-matrix" }
anticheat-nocheatplus = { module = "fr.neatmonster:nocheatplus", version.ref = "anticheat-nocheatplus" }
anticheat-spartan = { module = "me.vagdedes:SpartanAPI", version.ref = "anticheat-spartan" }
anticheat-light = { module = "com.github.tiredvekster:LightAntiCheat", version.ref = "anticheat-light" }
bstats-base = { module = "org.bstats:bstats-base", version.ref = "bstats" }
bstats-bukkit = { module = "org.bstats:bstats-bukkit", version.ref = "bstats" }
choco-networking-bukkit = { module = "wtf.choco:networking-bukkit", version.ref = "choco-networking" }
Expand Down
3 changes: 2 additions & 1 deletion veinminer-bukkit/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ repositories {
maven("https://maven.enginehub.org/repo/") // WorldGuard
maven("https://nexus.neetgames.com/repository/maven-public/") // mcMMO

maven("https://jitpack.io") // mcMMO, Grim AntiCheat, Matrix AntiCheat
maven("https://jitpack.io") // mcMMO, Grim AntiCheat, Matrix AntiCheat, Light AntiCheat
maven("https://repo.janmm14.de/repository/public/") // Advanced AntiCheat
maven("https://repo.md-5.net/content/repositories/snapshots/") // NoCheatPlus
maven("https://repo.extendedclip.com/content/repositories/placeholderapi/") // PlaceholderAPI
Expand All @@ -36,6 +36,7 @@ dependencies {
compileOnly(libs.anticheat.matrix)
compileOnly(libs.anticheat.nocheatplus)
compileOnly(libs.anticheat.spartan)
compileOnly(libs.anticheat.light)

testImplementation(libs.junit.jupiter.api)
testRuntimeOnly(libs.junit.jupiter.engine)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ public void onEnable() {
this.registerAntiCheatHookIfEnabled(manager, "AAC5", AntiCheatHookAAC::new);
this.registerAntiCheatHookIfEnabled(manager, "AntiAura", () -> new AntiCheatHookAntiAura(this));
this.registerAntiCheatHookIfEnabled(manager, "GrimAC", () -> new AntiCheatHookGrim(this));
this.registerAntiCheatHookIfEnabled(manager, "LightAntiCheat", () -> new AntiCheatHookLightAntiCheat(this));
this.registerAntiCheatHookIfEnabled(manager, "LightAntiCheat", AntiCheatHookLightAntiCheat::new);
this.registerAntiCheatHookIfEnabled(manager, "Matrix", AntiCheatHookMatrix::new);
this.registerAntiCheatHookIfEnabled(manager, "NoCheatPlus", () -> new AntiCheatHookNCP(this));
this.registerAntiCheatHookIfEnabled(manager, "Spartan", () -> new AntiCheatHookSpartan(this));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,75 +1,52 @@
package wtf.choco.veinminer.anticheat;

import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Set;
import com.google.common.collect.Multimap;
import com.google.common.collect.MultimapBuilder;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import org.apache.commons.lang.reflect.MethodUtils;
import me.vekster.lightanticheat.api.CheckType;
import me.vekster.lightanticheat.api.DetectionStatus;
import me.vekster.lightanticheat.api.LACApi;

import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;

import wtf.choco.veinminer.VeinMinerPlugin;

/**
* The default LightAntiCheat hook implementation.
*/
public final class AntiCheatHookLightAntiCheat implements AntiCheatHook {

private Class<?> lightAntiCheatApiClass;
private Method methodIsApiBypass, methodSetApiBypass;

private boolean supported;

private final Set<UUID> exempt = new HashSet<>();

public AntiCheatHookLightAntiCheat(@NotNull VeinMinerPlugin plugin) {
try {
this.lightAntiCheatApiClass = Class.forName("vekster.lightanticheat.api.Utils");
this.methodIsApiBypass = MethodUtils.getAccessibleMethod(lightAntiCheatApiClass, "isApiBypass", Player.class);
this.methodSetApiBypass = MethodUtils.getAccessibleMethod(lightAntiCheatApiClass, "setApiBypass", new Class[] {
Player.class, Boolean.TYPE
});

this.supported = (methodIsApiBypass != null && methodSetApiBypass != null);
} catch (ReflectiveOperationException e) {
plugin.getLogger().severe("The version of LightAntiCheat on this server is incompatible with Veinminer. Please post information on the spigot resource discussion page.");
e.printStackTrace();
}
}
private final Multimap<UUID, String> exempt = MultimapBuilder.hashKeys().arrayListValues().build();

@Override
public void exempt(@NotNull Player player) {
try {
if (Boolean.TRUE.equals(methodIsApiBypass.invoke(null, player))) {
return;
}
List<String> checks = new ArrayList<>();

if (exempt.add(player.getUniqueId())) {
this.methodSetApiBypass.invoke(null, player, true);
LACApi api = LACApi.getInstance();
for (String checkName : api.getCheckNames(CheckType.ALL)) {
if (api.getDetectionStatus(player, checkName) == DetectionStatus.ENABLED) {
api.disableDetection(player, checkName);
checks.add(checkName);
}
} catch (ReflectiveOperationException e) { } // Ignore
}

this.exempt.putAll(player.getUniqueId(), checks);
}

@Override
public void unexempt(@NotNull Player player) {
if (!exempt.remove(player.getUniqueId())) {
return;
LACApi api = LACApi.getInstance();
for (String checkName : exempt.removeAll(player.getUniqueId())) {
api.enableDetection(player, checkName);
}

try {
this.methodSetApiBypass.invoke(null, player, false);
} catch (ReflectiveOperationException e) { } // Ignore
}

@Override
public boolean shouldUnexempt(@NotNull Player player) {
return exempt.contains(player.getUniqueId());
}

@Override
public boolean isSupported() {
return supported;
return exempt.containsKey(player.getUniqueId());
}

}

0 comments on commit b1e8f2a

Please sign in to comment.