예제 #1
0
 /**
  * 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;
   }
 }
예제 #2
0
 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];
 }
예제 #3
0
 /**
  * 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());
 }
예제 #4
0
  /**
   * 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 (!).
  }
예제 #5
0
  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;
    }
  }
예제 #6
0
  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);
    }
  }
예제 #7
0
 /**
  * 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);
 }
예제 #8
0
 /**
  * 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;
 }
예제 #9
0
 /**
  * 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());
   }
 }
예제 #10
0
 /** 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;
  }
예제 #12
0
 public CheckListener(CheckType checkType) {
   this.checkType = checkType;
   this.mcAccess = NCPAPIProvider.getNoCheatPlusAPI().getMCAccess();
 }