Fix AttackFrequency for MC 1.7.10 and MC 1.7.2.
This commit is contained in:
parent
b3a9898900
commit
672c6cf71f
|
@ -14,6 +14,7 @@
|
|||
*/
|
||||
package fr.neatmonster.nocheatplus.checks.net.protocollib;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
@ -31,11 +32,70 @@ import fr.neatmonster.nocheatplus.checks.net.NetConfig;
|
|||
import fr.neatmonster.nocheatplus.checks.net.NetData;
|
||||
import fr.neatmonster.nocheatplus.config.ConfPaths;
|
||||
import fr.neatmonster.nocheatplus.config.ConfigManager;
|
||||
import fr.neatmonster.nocheatplus.utilities.ReflectionUtil;
|
||||
|
||||
public class UseEntityAdapter extends BaseAdapter {
|
||||
|
||||
private static class LegacyReflectionSet {
|
||||
/** Hacks. */
|
||||
final Class<?> packetClass_legacy;
|
||||
final Class<?> enumClassAction_legacy;
|
||||
final Method methodGetAction_legacy;
|
||||
final Method methodName_legacy;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param versionDetail
|
||||
* @throws RuntimeException
|
||||
* if not matching/supported.
|
||||
*/
|
||||
private LegacyReflectionSet(String versionDetail) {
|
||||
Class<?> packetClass = ReflectionUtil.getClass("net.minecraft.server." + versionDetail + ".PacketPlayInUseEntity");
|
||||
Class<?> actionClass = ReflectionUtil.getClass("net.minecraft.server." + versionDetail + ".EnumEntityUseAction");
|
||||
Method methodGetAction = (packetClass == null || actionClass == null) ? null : ReflectionUtil.getMethodNoArgs(packetClass, "c", actionClass);
|
||||
if (packetClass == null || actionClass == null || methodGetAction == null) {
|
||||
this.packetClass_legacy = null;
|
||||
this.enumClassAction_legacy = null;
|
||||
this.methodGetAction_legacy = null;
|
||||
this.methodName_legacy = null;
|
||||
}
|
||||
else {
|
||||
this.packetClass_legacy = packetClass;
|
||||
this.enumClassAction_legacy = actionClass;
|
||||
this.methodGetAction_legacy = methodGetAction;
|
||||
this.methodName_legacy = ReflectionUtil.getMethodNoArgs(enumClassAction_legacy, "name", String.class);
|
||||
}
|
||||
if (this.methodName_legacy == null) {
|
||||
throw new RuntimeException("Not supported.");
|
||||
}
|
||||
}
|
||||
|
||||
String getActionFromNMSPacket(Object handle) {
|
||||
final Class<?> clazz = handle.getClass();
|
||||
if (clazz != packetClass_legacy) {
|
||||
return null;
|
||||
}
|
||||
final Object action = ReflectionUtil.invokeMethodNoArgs(methodGetAction_legacy, handle);
|
||||
if (action == null) {
|
||||
return null;
|
||||
}
|
||||
final Object actionName = ReflectionUtil.invokeMethodNoArgs(methodName_legacy, action);
|
||||
if (actionName instanceof String) {
|
||||
return (String) actionName;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final int INTERPRETED = 0x01;
|
||||
private static final int ATTACK = 0x02;
|
||||
|
||||
private final AttackFrequency attackFrequency;
|
||||
|
||||
private final LegacyReflectionSet legacySet;
|
||||
|
||||
public UseEntityAdapter(Plugin plugin) {
|
||||
super(plugin, PacketType.Play.Client.USE_ENTITY);
|
||||
|
||||
|
@ -44,6 +104,18 @@ public class UseEntityAdapter extends BaseAdapter {
|
|||
NCPAPIProvider.getNoCheatPlusAPI().addFeatureTags("checks", Arrays.asList(AttackFrequency.class.getSimpleName()));
|
||||
}
|
||||
attackFrequency = new AttackFrequency();
|
||||
|
||||
LegacyReflectionSet set = null;
|
||||
for (String versionDetail : new String[] {"v1_7_R4", "v1_7_R1"}) {
|
||||
try {
|
||||
set = new LegacyReflectionSet(versionDetail);
|
||||
if (set != null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (RuntimeException e) {} // +-
|
||||
}
|
||||
this.legacySet = set;
|
||||
NCPAPIProvider.getNoCheatPlusAPI().addComponent(attackFrequency);
|
||||
}
|
||||
|
||||
|
@ -67,23 +139,53 @@ public class UseEntityAdapter extends BaseAdapter {
|
|||
}
|
||||
|
||||
final PacketContainer packet = event.getPacket();
|
||||
final StructureModifier<EntityUseAction> actions = packet.getEntityUseActions();
|
||||
if (actions.size() != 1) {
|
||||
// TODO: Log warning once.
|
||||
return;
|
||||
}
|
||||
final EntityUseAction action = actions.read(0);
|
||||
|
||||
boolean cancel = false;
|
||||
if (action == EntityUseAction.ATTACK && attackFrequency.isEnabled(player, data, cc) && attackFrequency.check(player, time, data, cc)) {
|
||||
cancel = true;
|
||||
}
|
||||
|
||||
// MIGHT: use entity, use block both on packet level?
|
||||
boolean isAttack = false;
|
||||
boolean packetInterpreted = false;
|
||||
if (legacySet != null) {
|
||||
// Attempt to extract legacy information.
|
||||
final int flags = getAction_legacy(packet);
|
||||
if ((flags & INTERPRETED) != 0 ) {
|
||||
packetInterpreted = true;
|
||||
if ((flags & ATTACK) != 0) {
|
||||
isAttack = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!packetInterpreted) {
|
||||
// Handle as if latest.
|
||||
final StructureModifier<EntityUseAction> actions;
|
||||
actions = packet.getEntityUseActions();
|
||||
if (actions.size() == 1 && actions.read(0) == EntityUseAction.ATTACK) {
|
||||
isAttack = true;
|
||||
packetInterpreted = true;
|
||||
}
|
||||
}
|
||||
if (!packetInterpreted) {
|
||||
// TODO: Log warning once, if the packet could not be interpreted.
|
||||
return;
|
||||
}
|
||||
|
||||
// Run checks.
|
||||
boolean cancel = false;
|
||||
|
||||
// AttackFrequency
|
||||
if (isAttack && attackFrequency.isEnabled(player, data, cc)
|
||||
&& attackFrequency.check(player, time, data, cc)) {
|
||||
cancel = true;
|
||||
}
|
||||
|
||||
if (cancel) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private int getAction_legacy(final PacketContainer packetContainer) {
|
||||
// (For some reason the object didn't appear work with equality checks, thus compare the short string.)
|
||||
final String actionName = legacySet.getActionFromNMSPacket(packetContainer.getHandle());
|
||||
return actionName == null ? 0 : (INTERPRETED | ("ATTACK".equals(actionName) ? ATTACK : 0));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue