Signed-off-by: Lixfel <agga-games@gmx.de>
Dieser Commit ist enthalten in:
Ursprung
6d574bd89d
Commit
36fd4941b5
@ -93,6 +93,7 @@ public class FightSystem extends JavaPlugin {
|
|||||||
new ClickAnalyzer();
|
new ClickAnalyzer();
|
||||||
new HotbarKit.HotbarKitListener();
|
new HotbarKit.HotbarKitListener();
|
||||||
new OneShotStateDependent(ArenaMode.All, FightState.PreSchemSetup, () -> Fight.playSound(SWSound.BLOCK_NOTE_PLING.getSound(), 100.0f, 2.0f));
|
new OneShotStateDependent(ArenaMode.All, FightState.PreSchemSetup, () -> Fight.playSound(SWSound.BLOCK_NOTE_PLING.getSound(), 100.0f, 2.0f));
|
||||||
|
new AntiCheat();
|
||||||
|
|
||||||
new EnterHandler();
|
new EnterHandler();
|
||||||
techHider = new TechHiderWrapper();
|
techHider = new TechHiderWrapper();
|
||||||
|
118
FightSystem_Core/src/de/steamwar/fightsystem/listener/AntiCheat.java
Normale Datei
118
FightSystem_Core/src/de/steamwar/fightsystem/listener/AntiCheat.java
Normale Datei
@ -0,0 +1,118 @@
|
|||||||
|
/*
|
||||||
|
This file is a part of the SteamWar software.
|
||||||
|
|
||||||
|
Copyright (C) 2022 SteamWar.de-Serverteam
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.fightsystem.listener;
|
||||||
|
|
||||||
|
import com.comphenix.tinyprotocol.Reflection;
|
||||||
|
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||||
|
import de.steamwar.fightsystem.FightSystem;
|
||||||
|
import de.steamwar.sql.SWException;
|
||||||
|
import de.steamwar.techhider.ProtocolUtils;
|
||||||
|
import de.steamwar.techhider.TechHider;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
public class AntiCheat {
|
||||||
|
|
||||||
|
public AntiCheat() {
|
||||||
|
TinyProtocol.instance.addFilter(teleport, this::onTeleport);
|
||||||
|
TinyProtocol.instance.addFilter(position, this::onMove);
|
||||||
|
TinyProtocol.instance.addFilter(positionLook, this::onMove);
|
||||||
|
TinyProtocol.instance.addFilter(blockDig, this::onDig);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Class<?> flying = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInFlying");
|
||||||
|
private static final Reflection.FieldAccessor<Double> moveX = Reflection.getField(flying, double.class, 0);
|
||||||
|
private static final Reflection.FieldAccessor<Double> moveY = Reflection.getField(flying, double.class, 1);
|
||||||
|
private static final Reflection.FieldAccessor<Double> moveZ = Reflection.getField(flying, double.class, 2);
|
||||||
|
private static final Class<?> position = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInFlying$PacketPlayInPosition");
|
||||||
|
private static final Class<?> positionLook = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInFlying$PacketPlayInPositionLook");
|
||||||
|
|
||||||
|
private static final Class<?> teleport = Reflection.getClass("{nms.network.protocol.game}.PacketPlayOutPosition");
|
||||||
|
private static final Reflection.FieldAccessor<Double> tpX = Reflection.getField(teleport, double.class, 0);
|
||||||
|
private static final Reflection.FieldAccessor<Double> tpY = Reflection.getField(teleport, double.class, 1);
|
||||||
|
private static final Reflection.FieldAccessor<Double> tpZ = Reflection.getField(teleport, double.class, 2);
|
||||||
|
|
||||||
|
private final ConcurrentHashMap<Player, Movement> lastMovement = new ConcurrentHashMap<>();
|
||||||
|
private Object onTeleport(Player player, Object packet) {
|
||||||
|
//TODO Possible false flag through crouching into forbidden area?
|
||||||
|
//TODO circumvention through fast consecutive movements? (checks are synchronous)
|
||||||
|
//TODO uncertainty through moving pistons/desync etc.? (slow limit with timer to check for occurances?)
|
||||||
|
//TODO: Clearing with movement events?
|
||||||
|
Movement last = lastMovement.get(player);
|
||||||
|
if(last != null && tpX.get(packet) == last.x && tpY.get(packet) == last.y && tpZ.get(packet) == last.z) {
|
||||||
|
FightSystem.getPlugin().getLogger().log(Level.INFO, player.getName() + " was backported after small movement");
|
||||||
|
}
|
||||||
|
return packet;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object onMove(Player player, Object packet) {
|
||||||
|
//TODO Idee: Messung kleiner Movements, bei nächstem Movement mit folgendem Teleport für illegal movement trigger
|
||||||
|
Location location = player.getLocation();
|
||||||
|
double x = moveX.get(packet);
|
||||||
|
double dx = x - location.getX();
|
||||||
|
double y = moveY.get(packet);
|
||||||
|
double dy = x - location.getY();
|
||||||
|
double z = moveZ.get(packet);
|
||||||
|
double dz = z - location.getZ();
|
||||||
|
double lSqared = dx*dx + dy*dy + dz*dz;
|
||||||
|
lastMovement.compute(player, (p, previous) -> {
|
||||||
|
if(lSqared <= 0.00390625) {
|
||||||
|
return new Movement(x, y, z);
|
||||||
|
} else if(previous != null && previous.last) {
|
||||||
|
previous.last = false;
|
||||||
|
return previous;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
return packet;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Class<?> blockDig = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInBlockDig");
|
||||||
|
private static final Reflection.FieldAccessor<?> digPosition = Reflection.getField(blockDig, TechHider.blockPosition, 0);
|
||||||
|
private Object onDig(Player player, Object packet) {
|
||||||
|
Object pos = digPosition.get(packet);
|
||||||
|
int x = TechHider.blockPositionX.get(pos);
|
||||||
|
int z = TechHider.blockPositionZ.get(pos);
|
||||||
|
if(!player.getWorld().isChunkLoaded(ProtocolUtils.posToChunk(x), ProtocolUtils.posToChunk(z))) {
|
||||||
|
Bukkit.getScheduler().runTask(FightSystem.getPlugin(), () -> player.kickPlayer(null));
|
||||||
|
SWException.log(player.getName() + " tried to dig an unloaded block", "");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return packet;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Movement {
|
||||||
|
private final double x;
|
||||||
|
private final double y;
|
||||||
|
private final double z;
|
||||||
|
private boolean last;
|
||||||
|
|
||||||
|
private Movement(double x, double y, double z) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.z = z;
|
||||||
|
last = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
In neuem Issue referenzieren
Einen Benutzer sperren