/** * Return plugin + server commands [Subject to change]. * * @return Returns null if not CraftBukkit or CommandMap not available. */ public static CommandMap getCommandMap() { try { return NCPAPIProvider.getNoCheatPlusAPI().getGenericInstance(MCAccess.class).getCommandMap(); } catch (Throwable t) { StaticLog.logSevere(t); return null; } }
public ReflectBlock(ReflectBase base, ReflectBlockPosition blockPosition) throws ClassNotFoundException { final Class<?> clazz = Class.forName(base.nmsPackageName + ".Block"); // byID (static) nmsGetById = ReflectionUtil.getMethod(clazz, "getById", int.class); // getMaterial nmsGetMaterial = ReflectionUtil.getMethodNoArgs(clazz, "getMaterial"); // updateShape Method method = null; Class<?> clazzIBlockAccess = Class.forName(base.nmsPackageName + ".IBlockAccess"); if (blockPosition != null) { method = ReflectionUtil.getMethod(clazz, "updateShape", clazzIBlockAccess, blockPosition.nmsClass); } if (method == null) { method = ReflectionUtil.getMethod( clazz, "updateShape", clazzIBlockAccess, int.class, int.class, int.class); useBlockPosition = false; } else { useBlockPosition = true; } nmsUpdateShape = method; // Block bounds fetching. The array uses the order the methods (used to) appear in the nms // class. String[] names = new String[] { "getMinX", "getMaxX", "getMinY", "getMaxY", "getMinZ", "getMaxZ" }; // FUTURE GUESS. Method[] methods = tryBoundsMethods(clazz, names); if (methods == null) { names = guessBoundsMethodNames(clazz); if (names != null) { methods = tryBoundsMethods(clazz, names); } if (methods == null) { methods = new Method[] {null, null, null, null, null, null}; } } // TODO: Test which is which [ALLOW to configure and also save used ones to config, by mc // version]. // TODO: Dynamically test these ? [needs an extra world/space to place blocks inside of...] if (ConfigManager.getConfigFile().getBoolean(ConfPaths.LOGGING_EXTENDED_STATUS)) { NCPAPIProvider.getNoCheatPlusAPI() .getLogManager() .debug( Streams.INIT, "[NoCheatPlus] ReflectBlock: Use methods for shape: " + StringUtil.join(Arrays.asList(names), ", ")); } this.nmsGetMinX = methods[0]; this.nmsGetMaxX = methods[1]; this.nmsGetMinY = methods[2]; this.nmsGetMaxY = methods[3]; this.nmsGetMinZ = methods[4]; this.nmsGetMaxZ = methods[5]; }
/** * Intended for vehicle-move events. * * @param player * @param vehicle * @param from * @param to * @param fake true if the event was not fired by an external source (just gets noted). */ public static void outputDebugVehicleMove( final Player player, final Entity vehicle, final Location from, final Location to, final boolean fake) { final StringBuilder builder = new StringBuilder(250); final Location vLoc = vehicle.getLocation(); final Location loc = player.getLocation(); // TODO: Differentiate debug levels (needs setting up some policy + document in // BuildParamteres)? final Entity actualVehicle = player.getVehicle(); final boolean wrongVehicle = actualVehicle == null || actualVehicle.getEntityId() != vehicle.getEntityId(); if (BuildParameters.debugLevel > 0) { builder.append( "\n-------------- VEHICLE MOVE " + (fake ? "(fake)" : "") + "--------------\n"); builder.append(player.getName() + " " + from.getWorld().getName() + ":\n"); addMove(from, to, null, builder); builder.append("\n Vehicle: "); addLocation(vLoc, builder); builder.append("\n Player: "); addLocation(loc, builder); } else { builder.append( player.getName() + " " + from.getWorld().getName() + "veh." + (fake ? "(fake)" : "") + " "); addFormattedMove(from, to, null, builder); builder.append("\n Vehicle: "); addFormattedLocation(vLoc, builder); builder.append(" Player: "); addFormattedLocation(loc, builder); } builder.append( "\n Vehicle type: " + vehicle.getType() + (wrongVehicle ? (actualVehicle == null ? " (exited?)" : " actual: " + actualVehicle.getType()) : "")); NCPAPIProvider.getNoCheatPlusAPI() .getLogManager() .debug(Streams.TRACE_FILE, builder.toString()); }
/** * Handle the '/nocheatplus reload' command. * * @param sender the sender * @return true, if successful */ private void handleReloadCommand(final CommandSender sender) { final LogManager logManager = NCPAPIProvider.getNoCheatPlusAPI().getLogManager(); if (!sender.equals(Bukkit.getConsoleSender())) { sender.sendMessage(TAG + "Reloading configuration..."); } logManager.info(Streams.INIT, TAG + "Reloading configuration..."); // Do the actual reload. ConfigManager.cleanup(); ConfigManager.init(access); if (logManager instanceof INotifyReload) { // TODO: This is a band-aid. ((INotifyReload) logManager).onReload(); } // Remove all cached configs. DataManager.clearConfigs(); // There you have to add XConfig.clear() form now on. // Remove some checks data. // TODO: Better concept (INotifyReload). for (final CheckType checkType : new CheckType[] { CheckType.BLOCKBREAK, CheckType.FIGHT, }) { DataManager.clearData(checkType); } // Reset debug flags to default (temp, heavy). DataManager.restoreDefaultDebugFlags(); // Tell the registered listeners to adapt to new config, first sort them (!). Collections.sort(notifyReload, Order.cmpSetupOrder); for (final INotifyReload component : notifyReload) { component.onReload(); } // Say to the other plugins that we've reloaded the configuration. Bukkit.getPluginManager().callEvent(new NCPReloadEvent()); // Log reloading done. if (!sender.equals(Bukkit.getConsoleSender())) { sender.sendMessage(TAG + "Configuration reloaded!"); } logManager.info(Streams.INIT, TAG + "Configuration reloaded."); logManager.info( Streams.DEFAULT_FILE, StringUtil.join(VersionCommand.getVersionInfo(), "\n")); // Queued (!). }
private Location potentialViolation( final Player player, final Location loc, final PlayerLocation from, final PlayerLocation to, final int manhattan, String tags, final MovingData data, final MovingConfig cc) { // Moving into a block, possibly a violation. // Check the players location if different from others. // (It provides a better set-back for some exploits.) final int lbX = loc.getBlockX(); final int lbY = loc.getBlockY(); final int lbZ = loc.getBlockZ(); Location setBackLoc = null; // Alternative to from.getLocation(). // First check if the player is moving from a passable location. // If not, the move might still be allowed, if moving inside of the same block, or from and to // have head position passable. if (from.isPassable()) { // Put one workaround for 1.5 high blocks here: if (from.isBlockAbove(to) && (BlockProperties.getBlockFlags(to.getTypeId()) & BlockProperties.F_HEIGHT150) != 0) { // Check if the move went from inside of the block. if (BlockProperties.collidesBlock( to.getBlockCache(), from.getX(), from.getY(), from.getZ(), from.getX(), from.getY(), from.getZ(), to.getBlockX(), to.getBlockY(), to.getBlockZ(), to.getTypeId())) { // Allow moving inside of 1.5 high blocks. return null; } } // From should be the set-back. tags += "into"; } else if (BlockProperties.isPassable( from.getBlockCache(), loc.getX(), loc.getY(), loc.getZ(), from.getTypeId(lbX, lbY, lbZ))) { // Keep loc, because it it is passable. tags += "into_shift"; setBackLoc = loc; } // } else if (BlockProperties.isPassableExact(from.getBlockCache(), loc.getX(), loc.getY(), // loc.getZ(), from.getTypeId(lbX, lbY, lbZ))) { // (Mind that this can be the case on the same block theoretically.) // Keep loc as set-back. // } else if (!from.isSameBlock(lbX, lbY, lbZ)) { // Both loc and from are not passable. Use from as set.back (earliest). tags += "cross_shift"; } else if (manhattan == 1 && to.isBlockAbove(from) && BlockProperties.isPassable( from.getBlockCache(), from.getX(), from.getY() + player.getEyeHeight(), from.getZ(), from.getTypeId( from.getBlockX(), Location.locToBlock(from.getY() + player.getEyeHeight()), from.getBlockZ()))) { // else if (to.isBlockAbove(from) && BlockProperties.isPassableExact(from.getBlockCache(), // from.getX(), from.getY() + player.getEyeHeight(), from.getZ(), // from.getTypeId(from.getBlockX(), Location.locToBlock(from.getY() + player.getEyeHeight()), // from.getBlockZ()))) { // Allow the move up if the head is free. // TODO: Better distinguish ray-tracing (through something thin) or check to-head-passable // too? return null; } else if (manhattan > 0) { // Otherwise keep from as set-back. tags += "cross"; } else { // All blocks are the same, allow the move. return null; } // Discard inconsistent locations. // TODO: Might get rid of using the in-between loc - needs use-case checking. if (setBackLoc != null && (TrigUtil.distance(from, to) > 0.75 || TrigUtil.distance(from, setBackLoc) > 0.125)) { setBackLoc = null; } // Prefer the set-back location from the data. if (data.hasSetBack()) { // TODO: Review or make configurable. final Location ref = data.getSetBack(to); if (BlockProperties.isPassable(from.getBlockCache(), ref) || setBackLoc == null || TrigUtil.distance(from, setBackLoc) > 0.13) { // if (BlockProperties.isPassableExact(from.getBlockCache(), ref)) { setBackLoc = ref; if (data.debug) { NCPAPIProvider.getNoCheatPlusAPI() .getLogManager() .debug( Streams.TRACE_FILE, player.getName() + " Using set-back location for passable."); } } else if (data.debug) { NCPAPIProvider.getNoCheatPlusAPI() .getLogManager() .debug(Streams.TRACE_FILE, player.getName() + " Ignoring set-back for passable."); } } // TODO: set data.set-back ? or something: still some aji here. // Return the reset position. data.passableVL += 1d; final ViolationData vd = new ViolationData(this, player, data.passableVL, 1, cc.passableActions); if (data.debug || vd.needsParameters()) { vd.setParameter( ParameterName.LOCATION_FROM, String.format(Locale.US, "%.2f, %.2f, %.2f", from.getX(), from.getY(), from.getZ())); vd.setParameter( ParameterName.LOCATION_TO, String.format(Locale.US, "%.2f, %.2f, %.2f", to.getX(), to.getY(), to.getZ())); vd.setParameter( ParameterName.DISTANCE, String.format(Locale.US, "%.2f", TrigUtil.distance(from, to))); // TODO: Consider adding from.getTypeId() too, if blocks differ and non-air. vd.setParameter(ParameterName.BLOCK_ID, "" + to.getTypeId()); if (!tags.isEmpty()) { vd.setParameter(ParameterName.TAGS, tags); } } if (executeActions(vd)) { // TODO: Consider another set back position for this, also keeping track of players moving // around in blocks. final Location newTo; if (setBackLoc != null) { // Ensure the given location is cloned. newTo = LocUtil.clone(setBackLoc); } else { newTo = from.getLocation(); if (data.debug) { NCPAPIProvider.getNoCheatPlusAPI() .getLogManager() .debug(Streams.TRACE_FILE, player.getName() + " Using from location for passable."); } } newTo.setYaw(to.getYaw()); newTo.setPitch(to.getPitch()); return newTo; } else { // No cancel action set. return null; } }
public Location check( final Player player, Location loc, final PlayerLocation from, final PlayerLocation to, final MovingData data, final MovingConfig cc) { // TODO: if (!from.isSameCoords(loc)) {...check passable for loc -> from !?... + sf etc too?} // TODO: Future: Account for the players bounding box? [test very-strict setting for at least // the end points...] String tags = ""; // Block distances (sum, max) for from-to (not for loc!). final int manhattan = from.manhattan(to); // Skip moves inside of ignored blocks right away [works as long as we only check between // foot-locations]. if (manhattan <= 1 && BlockProperties.isPassable(from.getTypeId())) { // TODO: Monitor: BlockProperties.isPassable checks slightly different than before. if (manhattan == 0) { return null; } else { // manhattan == 1 if (BlockProperties.isPassable(to.getTypeId())) { return null; } } } boolean toPassable = to.isPassable(); // General condition check for using ray-tracing. if (toPassable && cc.passableRayTracingCheck && (!cc.passableRayTracingBlockChangeOnly || manhattan > 0)) { rayTracing.set(from, to); rayTracing.loop(); if (rayTracing.collides() || rayTracing.getStepsDone() >= rayTracing.getMaxSteps()) { final int maxBlockDist = manhattan <= 1 ? manhattan : from.maxBlockDist(to); if (maxBlockDist <= 1 && rayTracing.getStepsDone() == 1 && !from.isPassable()) { // Redo ray-tracing for moving out of blocks. if (collidesIgnoreFirst(from, to)) { toPassable = false; tags = "raytracing_2x_"; } else if (data.debug) { NCPAPIProvider.getNoCheatPlusAPI() .getLogManager() .debug( Streams.TRACE_FILE, player.getName() + " passable: allow moving out of a block."); } } else { if (!allowsSplitMove(from, to, manhattan)) { toPassable = false; tags = "raytracing_"; } } } // TODO: Future: If accuracy is demanded, also check the head position (or bounding box right // away). rayTracing.cleanup(); } // TODO: Checking order: If loc is not the same as from, a quick return here might not be // wanted. if (toPassable) { // Quick return. // (Might consider if vl>=1: only decrease if from and loc are passable too, though micro...) data.passableVL *= 0.99; return null; } else { return potentialViolation(player, loc, from, to, manhattan, tags, data, cc); } }
/** * Debug to TRACE_FILE. Meant for temporary use, use CheckUtils.debug for permanent inserts. * * @param message * @return */ public static void debug(String message) { NCPAPIProvider.getNoCheatPlusAPI().getLogManager().debug(Streams.TRACE_FILE, message); }
/** * Debug to TRACE_FILE. Meant for temporary use, use CheckUtils.debug for permanent inserts. * * @return The given returnValue. */ public static boolean debug(String message, boolean returnValue) { NCPAPIProvider.getNoCheatPlusAPI().getLogManager().debug(Streams.TRACE_FILE, message); return returnValue; }
/** * Output information specific to player-move events. * * @param player * @param from * @param to * @param mcAccess */ public static void outputMoveDebug( final Player player, final PlayerLocation from, final PlayerLocation to, final double maxYOnGround, final MCAccess mcAccess) { final StringBuilder builder = new StringBuilder(250); final Location loc = player.getLocation(); // TODO: Differentiate debug levels (needs setting up some policy + document in // BuildParamteres)? if (BuildParameters.debugLevel > 0) { builder.append("\n-------------- MOVE --------------\n"); builder.append(player.getName() + " " + from.getWorld().getName() + ":\n"); addMove(from, to, loc, builder); } else { builder.append(player.getName() + " " + from.getWorld().getName() + " "); addFormattedMove(from, to, loc, builder); } final double jump = mcAccess.getJumpAmplifier(player); final double speed = mcAccess.getFasterMovementAmplifier(player); final double strider = BridgeEnchant.getDepthStriderLevel(player); if (BuildParameters.debugLevel > 0) { try { // TODO: Check backwards compatibility (1.4.2). Remove try-catch builder.append( "\n(walkspeed=" + player.getWalkSpeed() + " flyspeed=" + player.getFlySpeed() + ")"); } catch (Throwable t) { } if (player.isSprinting()) { builder.append("(sprinting)"); } if (player.isSneaking()) { builder.append("(sneaking)"); } if (player.isBlocking()) { builder.append("(blocking)"); } final Vector v = player.getVelocity(); if (v.lengthSquared() > 0.0) { builder.append("(svel=" + v.getX() + "," + v.getY() + "," + v.getZ() + ")"); } } if (speed != Double.NEGATIVE_INFINITY) { builder.append("(e_speed=" + (speed + 1) + ")"); } final double slow = PotionUtil.getPotionEffectAmplifier(player, PotionEffectType.SLOW); if (slow != Double.NEGATIVE_INFINITY) { builder.append("(e_slow=" + (slow + 1) + ")"); } if (jump != Double.NEGATIVE_INFINITY) { builder.append("(e_jump=" + (jump + 1) + ")"); } if (strider != 0) { builder.append("(e_depth_strider=" + strider + ")"); } // Print basic info first in order NCPAPIProvider.getNoCheatPlusAPI() .getLogManager() .debug(Streams.TRACE_FILE, builder.toString()); // Extended info. if (BuildParameters.debugLevel > 0) { builder.setLength(0); // Note: the block flags are for normal on-ground checking, not with yOnGrond set to 0.5. from.collectBlockFlags(maxYOnGround); if (from.getBlockFlags() != 0) builder.append( "\nfrom flags: " + StringUtil.join(BlockProperties.getFlagNames(from.getBlockFlags()), "+")); if (from.getTypeId() != 0) addBlockInfo(builder, from, "\nfrom"); if (from.getTypeIdBelow() != 0) addBlockBelowInfo(builder, from, "\nfrom"); if (!from.isOnGround() && from.isOnGround(0.5)) builder.append(" (ground within 0.5)"); to.collectBlockFlags(maxYOnGround); if (to.getBlockFlags() != 0) builder.append( "\nto flags: " + StringUtil.join(BlockProperties.getFlagNames(to.getBlockFlags()), "+")); if (to.getTypeId() != 0) addBlockInfo(builder, to, "\nto"); if (to.getTypeIdBelow() != 0) addBlockBelowInfo(builder, to, "\nto"); if (!to.isOnGround() && to.isOnGround(0.5)) builder.append(" (ground within 0.5)"); NCPAPIProvider.getNoCheatPlusAPI() .getLogManager() .debug(Streams.TRACE_FILE, builder.toString()); } }
/** Instantiates a new creative fly check. */ public CreativeFly() { super(CheckType.MOVING_CREATIVEFLY); blockChangeTracker = NCPAPIProvider.getNoCheatPlusAPI().getBlockChangeTracker(); }
/** * This will be called from within the plugin in onEnable, after registration of all core * listeners and components. After each components addition processQueuedSubComponentHolders() * will be called to allow registries for further optional components. * * @param plugin * @return */ public Collection<Object> getAvailableComponentsOnEnable(NoCheatPlus plugin) { final List<Object> available = new LinkedList<Object>(); // Add components (try-catch). // TODO: catch ClassNotFound, incompatibleXY rather !? // Check: inventory.fastconsume. try { // TODO: Static test methods !? FastConsume.testAvailability(); available.add(new FastConsume()); NCPAPIProvider.getNoCheatPlusAPI() .addFeatureTags("checks", Arrays.asList(FastConsume.class.getSimpleName())); } catch (Throwable t) { StaticLog.logInfo("Inventory checks: FastConsume is not available."); } // Check: inventory.gutenberg. try { Gutenberg.testAvailability(); available.add(new Gutenberg()); NCPAPIProvider.getNoCheatPlusAPI() .addFeatureTags("checks", Arrays.asList(Gutenberg.class.getSimpleName())); } catch (Throwable t) { StaticLog.logInfo("Inventory checks: Gutenberg is not available."); } // Hot fix: falling block end portal. try { HotFixFallingBlockPortalEnter.testAvailability(); available.add(new HotFixFallingBlockPortalEnter()); NCPAPIProvider.getNoCheatPlusAPI() .addFeatureTags( "checks", Arrays.asList(HotFixFallingBlockPortalEnter.class.getSimpleName())); } catch (RuntimeException e) { } // ProtocolLib dependencies. if (protocolLibPresent.isAvailable()) { // Check conditions. boolean protocolLibAvailable = false; for (final IActivation condition : protocolLibActivation) { if (condition.isAvailable()) { protocolLibAvailable = true; break; } } // Attempt to react. if (protocolLibAvailable) { try { available.add(new ProtocolLibComponent(plugin)); } catch (Throwable t) { StaticLog.logWarning("Failed to set up packet level access with ProtocolLib."); if (ConfigManager.getConfigFile().getBoolean(ConfPaths.LOGGING_EXTENDED_STATUS)) { NCPAPIProvider.getNoCheatPlusAPI().getLogManager().debug(Streams.INIT, t); } } } else { List<String> parts = new LinkedList<String>(); parts.add("Packet level access via ProtocolLib not available, supported configurations: "); for (IDescriptiveActivation cond : protocolLibActivation) { parts.add(cond.getNeutralDescription()); } StaticLog.logWarning(StringUtil.join(parts, " | ")); } } else { StaticLog.logInfo("Packet level access: ProtocolLib is not available."); } return available; }
public CheckListener(CheckType checkType) { this.checkType = checkType; this.mcAccess = NCPAPIProvider.getNoCheatPlusAPI().getMCAccess(); }