mirror of
https://github.com/NoCheatPlus/NoCheatPlus.git
synced 2024-06-28 23:34:43 +02:00
Allow to detect delegate players for some contexts. Other fix(es).
Attempt to treat fake players less Concept is subject to change, might want fall-back methods or skipping native access in general where it's not needed (thus not need to check for native entities). Other * Don't insert dataMan into disableListeners twice.
This commit is contained in:
parent
d5b45e53f9
commit
0868e30994
|
@ -16,6 +16,7 @@ package fr.neatmonster.nocheatplus.checks.fight;
|
|||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
|
@ -45,20 +46,22 @@ public class Direction extends Check {
|
|||
* the damaged
|
||||
* @return true, if successful
|
||||
*/
|
||||
public boolean check(final Player player, final Location loc, final Entity damaged, final Location dLoc, final FightData data, final FightConfig cc) {
|
||||
public boolean check(final Player player, final Location loc,
|
||||
final Entity damaged, final boolean damagedIsFake, final Location dLoc,
|
||||
final FightData data, final FightConfig cc) {
|
||||
boolean cancel = false;
|
||||
|
||||
// Safeguard, if entity is complex, this check will fail due to giant and hard to define hitboxes.
|
||||
// if (damaged instanceof EntityComplex || damaged instanceof EntityComplexPart)
|
||||
if (mcAccess.isComplexPart(damaged)) {
|
||||
if (!damagedIsFake && mcAccess.isComplexPart(damaged)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Find out how wide the entity is.
|
||||
final double width = mcAccess.getWidth(damaged);
|
||||
final double width = damagedIsFake ? 0.6 : mcAccess.getWidth(damaged);
|
||||
|
||||
// entity.height is broken and will always be 0, therefore. Calculate height instead based on boundingBox.
|
||||
final double height = mcAccess.getHeight(damaged);
|
||||
final double height = damagedIsFake ? (damaged instanceof LivingEntity ? ((LivingEntity) damaged).getEyeHeight() : 1.75) : mcAccess.getHeight(damaged);
|
||||
|
||||
// TODO: allow any hit on the y axis (might just adapt interface to use foot position + height)!
|
||||
|
||||
|
@ -109,11 +112,20 @@ public class Direction extends Check {
|
|||
* @param cc
|
||||
* @return
|
||||
*/
|
||||
public DirectionContext getContext(final Player player, final Location loc, final Entity damaged, final Location damagedLoc, final FightData data, final FightConfig cc, final SharedContext sharedContext) {
|
||||
public DirectionContext getContext(final Player player, final Location loc,
|
||||
final Entity damaged, final boolean damagedIsFake, final Location damagedLoc,
|
||||
final FightData data, final FightConfig cc, final SharedContext sharedContext) {
|
||||
final DirectionContext context = new DirectionContext();
|
||||
context.damagedComplex = mcAccess.isComplexPart(damaged);
|
||||
// Find out how wide the entity is.
|
||||
if (damagedIsFake) {
|
||||
// Assume player / default.
|
||||
context.damagedComplex = false; // Later prefer bukkit based provider.
|
||||
context.damagedWidth = 0.6;
|
||||
}
|
||||
else {
|
||||
context.damagedComplex = mcAccess.isComplexPart(damaged);
|
||||
context.damagedWidth = mcAccess.getWidth(damaged);
|
||||
}
|
||||
// entity.height is broken and will always be 0, therefore. Calculate height instead based on boundingBox.
|
||||
context.damagedHeight = sharedContext.damagedHeight;
|
||||
context.direction = loc.getDirection();
|
||||
|
|
|
@ -54,6 +54,7 @@ import fr.neatmonster.nocheatplus.checks.moving.util.MovingUtil;
|
|||
import fr.neatmonster.nocheatplus.compat.Bridge1_9;
|
||||
import fr.neatmonster.nocheatplus.compat.BridgeEnchant;
|
||||
import fr.neatmonster.nocheatplus.compat.BridgeHealth;
|
||||
import fr.neatmonster.nocheatplus.compat.IBridgeCrossPlugin;
|
||||
import fr.neatmonster.nocheatplus.compat.MCAccess;
|
||||
import fr.neatmonster.nocheatplus.components.registry.feature.JoinLeaveListener;
|
||||
import fr.neatmonster.nocheatplus.permissions.Permissions;
|
||||
|
@ -109,6 +110,9 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
|
|||
private final Counters counters = NCPAPIProvider.getNoCheatPlusAPI().getGenericInstance(Counters.class);
|
||||
private final int idCancelDead = counters.registerKey("canceldead");
|
||||
|
||||
// Assume it to stay the same all time.
|
||||
private final IBridgeCrossPlugin crossPlugin = NCPAPIProvider.getNoCheatPlusAPI().getGenericInstance(IBridgeCrossPlugin.class);
|
||||
|
||||
public FightListener() {
|
||||
super(CheckType.FIGHT);
|
||||
}
|
||||
|
@ -119,18 +123,22 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
|
|||
}
|
||||
|
||||
/**
|
||||
* A player attacked something with DamageCause ENTITY_ATTACK. That's most
|
||||
* likely what we want to really check.
|
||||
* A player attacked something with DamageCause ENTITY_ATTACK.
|
||||
*
|
||||
* @param player
|
||||
* The attacking player.
|
||||
* @param damaged
|
||||
* @param originalDamage Damage before applying modifiers.
|
||||
* @param finalDamage Damage after applying modifiers.
|
||||
* @param originalDamage
|
||||
* Damage before applying modifiers.
|
||||
* @param finalDamage
|
||||
* Damage after applying modifiers.
|
||||
* @param tick
|
||||
* @param data
|
||||
* @return
|
||||
*/
|
||||
private boolean handleNormalDamage(final Player player, final Entity damaged, final double originalDamage, final double finalDamage, final int tick, final FightData data) {
|
||||
private boolean handleNormalDamage(final Player player, final boolean attackerIsFake,
|
||||
final Entity damaged, final boolean damagedIsFake,
|
||||
final double originalDamage, final double finalDamage, final int tick, final FightData data) {
|
||||
final FightConfig cc = FightConfig.getConfig(player);
|
||||
|
||||
// Hotfix attempt for enchanted books.
|
||||
|
@ -295,15 +303,15 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
|
|||
if (reachEnabled || directionEnabled) {
|
||||
if (damagedTrace != null) {
|
||||
// Checks that use the LocationTrace instance of the attacked entity/player.
|
||||
cancelled = locationTraceChecks(player, loc, data, cc, damaged, damagedLoc, damagedTrace, tick, now, reachEnabled, directionEnabled);
|
||||
cancelled = locationTraceChecks(player, loc, data, cc, damaged, damagedIsFake, damagedLoc, damagedTrace, tick, now, reachEnabled, directionEnabled);
|
||||
}
|
||||
else {
|
||||
// Still use the classic methods for non-players. maybe[]
|
||||
if (reachEnabled && reach.check(player, loc, damaged, damagedLoc, data, cc)) {
|
||||
if (reachEnabled && reach.check(player, loc, damaged, damagedIsFake, damagedLoc, data, cc)) {
|
||||
cancelled = true;
|
||||
}
|
||||
|
||||
if (directionEnabled && direction.check(player, loc, damaged, damagedLoc, data, cc)) {
|
||||
if (directionEnabled && direction.check(player, loc, damaged, damagedIsFake, damagedLoc, data, cc)) {
|
||||
cancelled = true;
|
||||
}
|
||||
}
|
||||
|
@ -399,16 +407,18 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
|
|||
* @param directionEnabled
|
||||
* @return If to cancel (true) or not (false).
|
||||
*/
|
||||
private boolean locationTraceChecks(final Player player, final Location loc, final FightData data, final FightConfig cc,
|
||||
final Entity damaged, final Location damagedLoc, LocationTrace damagedTrace,
|
||||
private boolean locationTraceChecks(final Player player, final Location loc,
|
||||
final FightData data, final FightConfig cc,
|
||||
final Entity damaged, final boolean damagedIsFake,
|
||||
final Location damagedLoc, LocationTrace damagedTrace,
|
||||
final long tick, final long now, final boolean reachEnabled, final boolean directionEnabled) {
|
||||
// TODO: Order / splitting off generic stuff.
|
||||
boolean cancelled = false;
|
||||
|
||||
// (Might pass generic context to factories, for shared + heavy properties.)
|
||||
final SharedContext sharedContext = new SharedContext(damaged, mcAccess);
|
||||
final SharedContext sharedContext = new SharedContext(damaged, damagedIsFake, mcAccess);
|
||||
final ReachContext reachContext = reachEnabled ? reach.getContext(player, loc, damaged, damagedLoc, data, cc, sharedContext) : null;
|
||||
final DirectionContext directionContext = directionEnabled ? direction.getContext(player, loc, damaged, damagedLoc, data, cc, sharedContext) : null;
|
||||
final DirectionContext directionContext = directionEnabled ? direction.getContext(player, loc, damaged, damagedIsFake, damagedLoc, data, cc, sharedContext) : null;
|
||||
|
||||
final long traceOldest = tick - cc.loopMaxLatencyTicks; // TODO: Set by latency-window.
|
||||
// TODO: Iterating direction, which, static/dynamic choice.
|
||||
|
@ -484,9 +494,12 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
|
|||
final Player damagedPlayer = damaged instanceof Player ? (Player) damaged : null;
|
||||
final FightData damagedData = damagedPlayer == null ? null : FightData.getData(damagedPlayer);
|
||||
final boolean damagedIsDead = damaged.isDead();
|
||||
final boolean damagedIsFake = !crossPlugin.isNativeEntity(damaged);
|
||||
if (damagedPlayer != null && !damagedIsDead) {
|
||||
// God mode check.
|
||||
if (godMode.isEnabled(damagedPlayer) && godMode.check(damagedPlayer, BridgeHealth.getDamage(event), damagedData)) {
|
||||
// (Do not test the savage.)
|
||||
if (godMode.isEnabled(damagedPlayer)
|
||||
&& godMode.check(damagedPlayer, damagedIsFake, BridgeHealth.getDamage(event), damagedData)) {
|
||||
// It requested to "cancel" the players invulnerability, so set their noDamageTicks to 0.
|
||||
damagedPlayer.setNoDamageTicks(0);
|
||||
}
|
||||
|
@ -508,7 +521,8 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
|
|||
}
|
||||
// Attacking entities.
|
||||
if (event instanceof EntityDamageByEntityEvent) {
|
||||
onEntityDamageByEntity(damaged, damagedPlayer, damagedIsDead, damagedData, (EntityDamageByEntityEvent) event);
|
||||
onEntityDamageByEntity(damaged, damagedPlayer, damagedIsDead, damagedIsFake,
|
||||
damagedData, (EntityDamageByEntityEvent) event);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -522,7 +536,8 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
|
|||
* @param event
|
||||
*/
|
||||
private void onEntityDamageByEntity(final Entity damaged, final Player damagedPlayer,
|
||||
final boolean damagedIsDead, final FightData damagedData, final EntityDamageByEntityEvent event) {
|
||||
final boolean damagedIsDead, final boolean damagedIsFake,
|
||||
final FightData damagedData, final EntityDamageByEntityEvent event) {
|
||||
final Entity damager = event.getDamager();
|
||||
final int tick = TickTask.getTick();
|
||||
if (damagedPlayer != null && !damagedIsDead) {
|
||||
|
@ -556,6 +571,7 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
|
|||
if (attackerData.debug) {
|
||||
// TODO: Pass result to further checks for reference?
|
||||
// TODO: attackerData.debug flag.
|
||||
// TODO: Fake players likely have unused velocity, just clear unused?
|
||||
UnusedVelocity.checkUnusedVelocity(attacker, CheckType.FIGHT);
|
||||
}
|
||||
// Workaround for subsequent melee damage eventsfor explosions. TODO: Legacy or not, need a KB.
|
||||
|
@ -577,7 +593,8 @@ public class FightListener extends CheckListener implements JoinLeaveListener{
|
|||
attackerData.lastExplosionDamageTick = -1;
|
||||
attackerData.lastExplosionEntityId = Integer.MAX_VALUE;
|
||||
}
|
||||
else if (handleNormalDamage(player, damaged,
|
||||
else if (handleNormalDamage(player, !crossPlugin.isNativePlayer(player),
|
||||
damaged, damagedIsFake,
|
||||
BridgeHealth.getOriginalDamage(event), BridgeHealth.getFinalDamage(event),
|
||||
tick, attackerData)) {
|
||||
event.setCancelled(true);
|
||||
|
|
|
@ -22,6 +22,7 @@ import fr.neatmonster.nocheatplus.checks.Check;
|
|||
import fr.neatmonster.nocheatplus.checks.CheckType;
|
||||
import fr.neatmonster.nocheatplus.checks.net.NetData;
|
||||
import fr.neatmonster.nocheatplus.compat.BridgeHealth;
|
||||
import fr.neatmonster.nocheatplus.compat.IBridgeCrossPlugin;
|
||||
import fr.neatmonster.nocheatplus.utilities.CheckUtils;
|
||||
import fr.neatmonster.nocheatplus.utilities.TickTask;
|
||||
|
||||
|
@ -43,11 +44,11 @@ public class GodMode extends Check {
|
|||
* @param damage
|
||||
* @return
|
||||
*/
|
||||
public boolean check(final Player player, final double damage, final FightData data){
|
||||
public boolean check(final Player player, final boolean playerIsFake, final double damage, final FightData data){
|
||||
final int tick = TickTask.getTick();
|
||||
|
||||
final int noDamageTicks = Math.max(0, player.getNoDamageTicks());
|
||||
final int invulnerabilityTicks = mcAccess.getInvulnerableTicks(player);
|
||||
final int invulnerabilityTicks = playerIsFake ? 0 : mcAccess.getInvulnerableTicks(player);
|
||||
|
||||
// TODO: cleanup this leugique beume...
|
||||
|
||||
|
@ -193,7 +194,8 @@ public class GodMode extends Check {
|
|||
public void death(final Player player) {
|
||||
// TODO: Is this still relevant ?
|
||||
// First check if the player is really dead (e.g. another plugin could have just fired an artificial event).
|
||||
if (BridgeHealth.getHealth(player) <= 0.0 && player.isDead()) {
|
||||
if (BridgeHealth.getHealth(player) <= 0.0 && player.isDead()
|
||||
&& NCPAPIProvider.getNoCheatPlusAPI().getGenericInstance(IBridgeCrossPlugin.class).isNativeEntity(player)) {
|
||||
try {
|
||||
// Schedule a task to be executed in roughly 1.5 seconds.
|
||||
// TODO: Get plugin otherwise !?
|
||||
|
|
|
@ -20,6 +20,7 @@ import org.bukkit.Location;
|
|||
import org.bukkit.entity.EnderDragon;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Giant;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
|
@ -67,7 +68,9 @@ public class Reach extends Check {
|
|||
* the damaged
|
||||
* @return true, if successful
|
||||
*/
|
||||
public boolean check(final Player player, final Location pLoc, final Entity damaged, final Location dRef, final FightData data, final FightConfig cc) {
|
||||
public boolean check(final Player player, final Location pLoc,
|
||||
final Entity damaged, final boolean damagedIsFake, final Location dRef,
|
||||
final FightData data, final FightConfig cc) {
|
||||
boolean cancel = false;
|
||||
|
||||
// The maximum distance allowed to interact with an entity in survival mode.
|
||||
|
@ -80,7 +83,7 @@ public class Reach extends Check {
|
|||
final double distanceLimit = player.getGameMode() == GameMode.CREATIVE ? CREATIVE_DISTANCE : SURVIVAL_DISTANCE + getDistMod(damaged);
|
||||
final double distanceMin = (distanceLimit - DYNAMIC_RANGE) / distanceLimit;
|
||||
|
||||
final double height = mcAccess.getHeight(damaged);
|
||||
final double height = damagedIsFake ? (damaged instanceof LivingEntity ? ((LivingEntity) damaged).getEyeHeight() : 1.75) : mcAccess.getHeight(damaged);
|
||||
|
||||
// Refine y position.
|
||||
// TODO: Make a little more accurate by counting in the actual bounding box.
|
||||
|
|
|
@ -15,13 +15,20 @@
|
|||
package fr.neatmonster.nocheatplus.checks.fight;
|
||||
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
|
||||
import fr.neatmonster.nocheatplus.compat.MCAccess;
|
||||
|
||||
public class SharedContext {
|
||||
public final double damagedHeight;
|
||||
|
||||
public SharedContext(Entity damaged, MCAccess mcAccess) {
|
||||
public SharedContext(Entity damaged, boolean damagedIsFake, MCAccess mcAccess) {
|
||||
if (damagedIsFake) {
|
||||
// Assume something lenient then.
|
||||
damagedHeight = damaged instanceof LivingEntity ? ((LivingEntity) damaged).getEyeHeight() : 1.75;
|
||||
}
|
||||
else {
|
||||
this.damagedHeight = mcAccess.getHeight(damaged);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
package fr.neatmonster.nocheatplus.compat;
|
||||
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
* Registered as generic instance.
|
||||
*
|
||||
* @author asofold
|
||||
*
|
||||
*/
|
||||
public interface IBridgeCrossPlugin {
|
||||
|
||||
/**
|
||||
* Safety check, enabling to skip certain checks or tests for delegate
|
||||
* players.
|
||||
*
|
||||
* @param player
|
||||
* @return
|
||||
*/
|
||||
public boolean isNativePlayer(Player player);
|
||||
|
||||
/**
|
||||
* Safety check, enabling to skip certain checks or tests for delegate
|
||||
* entities.
|
||||
*
|
||||
* @param player
|
||||
* @return
|
||||
*/
|
||||
public boolean isNativeEntity(Entity entity);
|
||||
|
||||
}
|
|
@ -70,6 +70,7 @@ import fr.neatmonster.nocheatplus.compat.BridgeMisc;
|
|||
import fr.neatmonster.nocheatplus.compat.MCAccess;
|
||||
import fr.neatmonster.nocheatplus.compat.blocks.BlockChangeTracker;
|
||||
import fr.neatmonster.nocheatplus.compat.blocks.BlockChangeTracker.BlockChangeListener;
|
||||
import fr.neatmonster.nocheatplus.compat.meta.BridgeCrossPlugin;
|
||||
import fr.neatmonster.nocheatplus.compat.registry.AttributeAccessFactory;
|
||||
import fr.neatmonster.nocheatplus.compat.registry.DefaultComponentFactory;
|
||||
import fr.neatmonster.nocheatplus.compat.registry.EntityAccessFactory;
|
||||
|
@ -905,6 +906,7 @@ public class NoCheatPlus extends JavaPlugin implements NoCheatPlusAPI {
|
|||
registerGenericInstance(new WRPT());
|
||||
registerGenericInstance(new Random(System.currentTimeMillis() ^ ((long) this.hashCode() * (long) listenerManager.hashCode() * (long) logManager.hashCode())));
|
||||
registerGenericInstance(new TraceEntryPool(1000)); // Random number.
|
||||
addComponent(new BridgeCrossPlugin());
|
||||
|
||||
// Initialize MCAccess.
|
||||
initMCAccess(config);
|
||||
|
@ -913,7 +915,6 @@ public class NoCheatPlus extends JavaPlugin implements NoCheatPlusAPI {
|
|||
initBlockProperties(config);
|
||||
|
||||
// Initialize data manager.
|
||||
disableListeners.add(0, dataMan);
|
||||
dataMan.onEnable();
|
||||
|
||||
// Register components.
|
||||
|
@ -975,6 +976,7 @@ public class NoCheatPlus extends JavaPlugin implements NoCheatPlusAPI {
|
|||
// Set up the tick task.
|
||||
TickTask.start(this);
|
||||
|
||||
// dataMan expiration checking.
|
||||
this.dataManTaskId = Bukkit.getScheduler().scheduleSyncRepeatingTask(this, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
@ -982,6 +984,10 @@ public class NoCheatPlus extends JavaPlugin implements NoCheatPlusAPI {
|
|||
}
|
||||
}, 1207, 1207);
|
||||
|
||||
// Ensure dataMan is first on disableListeners.
|
||||
disableListeners.remove(dataMan);
|
||||
disableListeners.add(0, dataMan);
|
||||
|
||||
// Set up consistency checking.
|
||||
scheduleConsistencyCheckers();
|
||||
|
||||
|
@ -1211,6 +1217,7 @@ public class NoCheatPlus extends JavaPlugin implements NoCheatPlusAPI {
|
|||
public void setMCAccess(final MCAccess mcAccess) {
|
||||
// Just sets it and propagates it.
|
||||
// TODO: Might fire a NCPSetMCAccessEvent (include getting and setting)!
|
||||
// TODO: Store a list of MCAccessHolder.
|
||||
this.mcAccess = mcAccess;
|
||||
for (final Object obj : this.allComponents) {
|
||||
if (obj instanceof MCAccessHolder) {
|
||||
|
|
|
@ -1,9 +1,15 @@
|
|||
package fr.neatmonster.nocheatplus.compat.meta;
|
||||
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import fr.neatmonster.nocheatplus.NCPAPIProvider;
|
||||
import fr.neatmonster.nocheatplus.compat.IBridgeCrossPlugin;
|
||||
import fr.neatmonster.nocheatplus.compat.MCAccess;
|
||||
import fr.neatmonster.nocheatplus.compat.cbreflect.reflect.ReflectBase;
|
||||
import fr.neatmonster.nocheatplus.components.registry.feature.IPostRegisterRunnable;
|
||||
import fr.neatmonster.nocheatplus.components.registry.feature.MCAccessHolder;
|
||||
import fr.neatmonster.nocheatplus.utilities.ReflectionUtil;
|
||||
|
||||
/**
|
||||
* Utility to probe for cross-plugin issues, such as Player delegates.
|
||||
|
@ -12,16 +18,47 @@ import fr.neatmonster.nocheatplus.components.registry.feature.MCAccessHolder;
|
|||
* @author asofold
|
||||
*
|
||||
*/
|
||||
public class BridgeCrossPlugin implements MCAccessHolder {
|
||||
public class BridgeCrossPlugin implements IBridgeCrossPlugin, IPostRegisterRunnable, MCAccessHolder {
|
||||
|
||||
// TODO: More sophisticated checking ?
|
||||
|
||||
private MCAccess mcAccess;
|
||||
|
||||
public BridgeCrossPlugin(MCAccess mcAccess) {
|
||||
this.mcAccess = mcAccess;
|
||||
private final Class<?> playerClass;
|
||||
private final Class<?> entityClass;
|
||||
|
||||
public BridgeCrossPlugin() {
|
||||
ReflectBase reflectBase = new ReflectBase();
|
||||
this.playerClass = getEntityClass(reflectBase, "Player");
|
||||
this.entityClass = getEntityClass(reflectBase, "Entity", "");
|
||||
}
|
||||
|
||||
private Class<?> getEntityClass(ReflectBase reflectBase, String entityName) {
|
||||
return getEntityClass(reflectBase, entityName, entityName);
|
||||
}
|
||||
|
||||
private Class<?> getEntityClass(ReflectBase reflectBase, String obcSuffix, String nmsSuffix) {
|
||||
if (reflectBase.nmsPackageName == null || reflectBase.obcPackageName == null) {
|
||||
return null;
|
||||
}
|
||||
Class<?> obcPlayer = ReflectionUtil.getClass(reflectBase.obcPackageName + ".entity.Craft" + obcSuffix);
|
||||
Class<?> nmsPlayer = ReflectionUtil.getClass(reflectBase.nmsPackageName + ".Entity" + nmsSuffix);
|
||||
if (obcPlayer == null || nmsPlayer == null) {
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
return obcPlayer;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runPostRegister() {
|
||||
NCPAPIProvider.getNoCheatPlusAPI().registerGenericInstance(IBridgeCrossPlugin.class, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMCAccess(MCAccess mcAccess) {
|
||||
// TODO: Should adapt to mcAccess?
|
||||
this.mcAccess = mcAccess;
|
||||
}
|
||||
|
||||
|
@ -30,9 +67,14 @@ public class BridgeCrossPlugin implements MCAccessHolder {
|
|||
return mcAccess;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNativePlayer(final Player player) {
|
||||
// Possibly better within MCAccess later on.
|
||||
return player.getClass().getSimpleName().equals("CraftPlayer");
|
||||
return playerClass != null && playerClass.isAssignableFrom(player.getClass());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNativeEntity(final Entity entity) {
|
||||
return entityClass != null && entityClass.isAssignableFrom(entity.getClass());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user