Search in sources :

Example 1 with Summary

use of com.ichorpowered.guardianapi.detection.report.Summary in project guardian by ichorpowered.

the class FlightCheck method getSequence.

@Override
public SequenceBlueprint<Event> getSequence(final Detection detection) {
    final Double analysisTime = detection.getContentContainer().get(ContentKeys.ANALYSIS_TIME).orElse(GuardianValue.empty()).getDirect().orElse(0d) / 0.05;
    final Double analysisIntercept = detection.getContentContainer().get(ContentKeys.ANALYSIS_INTERCEPT).orElse(GuardianValue.empty()).getDirect().orElse(0d);
    final Double minimumTickRate = detection.getContentContainer().get(ContentKeys.ANALYSIS_MINIMUM_TICK).orElse(GuardianValue.empty()).getDirect().orElse(0d) / 0.05;
    final Double maximumTickRate = detection.getContentContainer().get(ContentKeys.ANALYSIS_MAXIMUM_TICK).orElse(GuardianValue.empty()).getDirect().orElse(0d) / 0.05;
    return new GuardianSequenceBuilder().capture(new ControlCapture(detection.getPlugin(), detection)).capture(new AltitudeCapture(detection.getPlugin(), detection)).capture(new MaterialCapture(detection.getPlugin(), detection)).capture(new PotionEffectCapture(detection.getPlugin(), detection)).observe(MoveEntityEvent.class).after().delay(analysisTime.intValue()).condition(sequenceContext -> {
        final GuardianPlayerEntry<Player> entityEntry = sequenceContext.get(CommonContextKeys.ENTITY_ENTRY);
        final Summary summary = sequenceContext.get(CommonContextKeys.SUMMARY);
        final GuardianCaptureRegistry captureRegistry = sequenceContext.get(CommonContextKeys.CAPTURE_REGISTRY);
        final long lastActionTime = sequenceContext.get(CommonContextKeys.LAST_ACTION_TIME);
        summary.set(SequenceReport.class, new SequenceReport(false, Origin.source(sequenceContext.getRoot()).owner(entityEntry).build()));
        if (!entityEntry.getEntity(Player.class).isPresent())
            return false;
        final Player player = entityEntry.getEntity(Player.class).get();
        /*
                         * Capture Collection
                         */
        final CaptureContainer captureContainer = captureRegistry.getContainer();
        final Optional<Location> initial = captureContainer.get(GuardianSequence.INITIAL_LOCATION);
        final Optional<Double> effectLiftAmplifier = captureContainer.get(PotionEffectCapture.VERTICAL_SPEED_MODIFIER);
        final Optional<Double> materialSpeedAmplifier = captureContainer.get(MaterialCapture.SPEED_MODIFIER);
        final Optional<Double> altitude = captureContainer.get(AltitudeCapture.RELATIVE_ALTITUDE);
        final Optional<Map<String, Integer>> materialStateTicks = captureContainer.get(MaterialCapture.ACTIVE_MATERIAL_TICKS);
        final Optional<Map<String, Integer>> controlStateTicks = captureContainer.get(ControlCapture.ACTIVE_CONTROL_TICKS);
        if (!initial.isPresent() || !materialSpeedAmplifier.isPresent() || !altitude.isPresent() || !materialStateTicks.isPresent())
            return false;
        final Value<Double> playerBoxWidth = ContentUtil.getFirst(ContentKeys.BOX_PLAYER_WIDTH, entityEntry, detection.getContentContainer()).orElse(GuardianValue.empty());
        final Value<Double> playerBoxHeight = ContentUtil.getFirst(ContentKeys.BOX_PLAYER_HEIGHT, entityEntry, detection.getContentContainer()).orElse(GuardianValue.empty());
        final Value<Double> playerBoxSafety = ContentUtil.getFirst(ContentKeys.BOX_PLAYER_SAFETY, entityEntry, detection.getContentContainer()).orElse(GuardianValue.empty());
        final double playerWidth = playerBoxWidth.getDirect().orElse(1.2) + playerBoxSafety.getDirect().orElse(0.05);
        final double playerHeight = playerBoxHeight.getDirect().orElse(1.8) + playerBoxSafety.getDirect().orElse(0.05);
        final boolean isSneaking = player.get(Keys.IS_SNEAKING).isPresent() && player.get(Keys.IS_SNEAKING).get();
        final BoundingBox playerBox = WorldUtil.getBoundingBox(playerWidth, isSneaking ? (playerHeight - 0.15) : playerHeight);
        long current = System.currentTimeMillis();
        // Gets the average time between now and the last action.
        double averageActionTime = ((current - lastActionTime) / 1000) / 0.05;
        if (averageActionTime < minimumTickRate) {
            detection.getLogger().warn("The server may be overloaded. A check could not be completed.");
            return false;
        } else if (averageActionTime > maximumTickRate) {
            return false;
        }
        if (player.get(Keys.VEHICLE).isPresent() || (player.get(Keys.IS_FLYING).isPresent() && player.get(Keys.IS_FLYING).get()) || player.getLocation().getY() < 1)
            return false;
        final double intercept = analysisIntercept + (effectLiftAmplifier.orElse(0d) / analysisTime);
        // Gets the players vertical displacement in the world.
        final double verticalDisplacement = ((player.getLocation().getY() - initial.get().getY()) == 0) ? intercept : player.getLocation().getY() - initial.get().getY();
        // Gets the players relative altitude to the ground.
        final double averageAltitude = altitude.get() / averageActionTime;
        // Gets the time the player is on solid ground or a liquid.
        final int solidMaterialTime = materialStateTicks.get().get(MaterialCapture.SOLID);
        final int liquidMaterialTime = materialStateTicks.get().get(MaterialCapture.LIQUID);
        // Gets the time the player is using flight.
        final int flightControlTime = controlStateTicks.get().get(ControlCapture.FLY);
        if (verticalDisplacement <= 1 || averageAltitude <= 1 || WorldUtil.containsBlocksUnder(player.getLocation(), playerBox, 1d) || solidMaterialTime > 1 || liquidMaterialTime > 1 || flightControlTime > 1)
            return false;
        if (((verticalDisplacement / averageAltitude) + averageAltitude) > intercept) {
            // ------------------------- DEBUG -----------------------------
            System.out.println(player.getName() + " has been caught using fly hacks. (" + ((verticalDisplacement / averageAltitude) + averageAltitude) + ")");
            // -------------------------------------------------------------
            SequenceReport report = new SequenceReport(true, Origin.source(sequenceContext.getRoot()).owner(entityEntry).build());
            report.put("type", "Flight");
            report.put("information", Collections.singletonList("Gained altitude over " + ((verticalDisplacement / averageAltitude) + averageAltitude) + "."));
            report.put("initial_location", initial.get());
            report.put("final_location", player.getLocation());
            report.put("severity", ((verticalDisplacement / averageAltitude) + averageAltitude) / (verticalDisplacement + averageAltitude));
            summary.set(SequenceReport.class, report);
            return true;
        }
        return false;
    }, ConditionType.NORMAL).build(SequenceContext.builder().owner(detection).root(this).build());
}
Also used : GuardianSequenceBuilder(com.ichorpowered.guardian.sequence.GuardianSequenceBuilder) Summary(com.ichorpowered.guardianapi.detection.report.Summary) ContentKeys(com.ichorpowered.guardianapi.content.ContentKeys) Keys(org.spongepowered.api.data.key.Keys) GuardianValue(com.ichorpowered.guardian.util.item.mutable.GuardianValue) Origin(com.ichorpowered.guardianapi.event.origin.Origin) PotionEffectCapture(com.ichorpowered.guardian.common.capture.player.PotionEffectCapture) GuardianCaptureRegistry(com.ichorpowered.guardian.sequence.capture.GuardianCaptureRegistry) Value(com.ichorpowered.guardianapi.util.item.value.mutable.Value) SequenceReport(com.ichorpowered.guardian.sequence.SequenceReport) Map(java.util.Map) ConditionType(com.abilityapi.sequenceapi.action.condition.ConditionType) Location(org.spongepowered.api.world.Location) GuardianSequence(com.ichorpowered.guardian.sequence.GuardianSequence) ContentUtil(com.ichorpowered.guardian.util.ContentUtil) Event(org.spongepowered.api.event.Event) Set(java.util.Set) AltitudeCapture(com.ichorpowered.guardian.common.capture.player.AltitudeCapture) SequenceContext(com.abilityapi.sequenceapi.SequenceContext) Sets(com.google.common.collect.Sets) BoundingBox(com.ichorpowered.guardian.util.entity.BoundingBox) Check(com.ichorpowered.guardianapi.detection.check.Check) GuardianPlayerEntry(com.ichorpowered.guardian.entry.GuardianPlayerEntry) Detection(com.ichorpowered.guardianapi.detection.Detection) CommonContextKeys(com.ichorpowered.guardian.sequence.context.CommonContextKeys) CaptureContainer(com.ichorpowered.guardianapi.detection.capture.CaptureContainer) ControlCapture(com.ichorpowered.guardian.common.capture.player.ControlCapture) Optional(java.util.Optional) WorldUtil(com.ichorpowered.guardian.util.WorldUtil) Player(org.spongepowered.api.entity.living.player.Player) SequenceBlueprint(com.abilityapi.sequenceapi.SequenceBlueprint) MaterialCapture(com.ichorpowered.guardian.common.capture.world.MaterialCapture) Collections(java.util.Collections) MoveEntityEvent(org.spongepowered.api.event.entity.MoveEntityEvent) Player(org.spongepowered.api.entity.living.player.Player) Optional(java.util.Optional) AltitudeCapture(com.ichorpowered.guardian.common.capture.player.AltitudeCapture) ControlCapture(com.ichorpowered.guardian.common.capture.player.ControlCapture) SequenceReport(com.ichorpowered.guardian.sequence.SequenceReport) GuardianPlayerEntry(com.ichorpowered.guardian.entry.GuardianPlayerEntry) MaterialCapture(com.ichorpowered.guardian.common.capture.world.MaterialCapture) PotionEffectCapture(com.ichorpowered.guardian.common.capture.player.PotionEffectCapture) CaptureContainer(com.ichorpowered.guardianapi.detection.capture.CaptureContainer) BoundingBox(com.ichorpowered.guardian.util.entity.BoundingBox) GuardianValue(com.ichorpowered.guardian.util.item.mutable.GuardianValue) Value(com.ichorpowered.guardianapi.util.item.value.mutable.Value) Summary(com.ichorpowered.guardianapi.detection.report.Summary) GuardianSequenceBuilder(com.ichorpowered.guardian.sequence.GuardianSequenceBuilder) GuardianCaptureRegistry(com.ichorpowered.guardian.sequence.capture.GuardianCaptureRegistry)

Example 2 with Summary

use of com.ichorpowered.guardianapi.detection.report.Summary in project guardian by ichorpowered.

the class HorizontalSpeedCheck method getSequence.

@Override
public SequenceBlueprint<Event> getSequence(final Detection detection) {
    final Double analysisTime = detection.getContentContainer().get(ContentKeys.ANALYSIS_TIME).orElse(GuardianValue.empty()).getDirect().orElse(0d) / 0.05;
    final Double analysisIntercept = detection.getContentContainer().get(ContentKeys.ANALYSIS_INTERCEPT).orElse(GuardianValue.empty()).getDirect().orElse(0d);
    final Double minimumTickRate = detection.getContentContainer().get(ContentKeys.ANALYSIS_MINIMUM_TICK).orElse(GuardianValue.empty()).getDirect().orElse(0d) / 0.05;
    final Double maximumTickRate = detection.getContentContainer().get(ContentKeys.ANALYSIS_MAXIMUM_TICK).orElse(GuardianValue.empty()).getDirect().orElse(0d) / 0.05;
    return new GuardianSequenceBuilder().capture(new ControlCapture(detection.getPlugin(), detection)).capture(new MaterialCapture(detection.getPlugin(), detection)).capture(new PotionEffectCapture(detection.getPlugin(), detection)).observe(MoveEntityEvent.class).after().delay(analysisTime.intValue()).condition(sequenceContext -> {
        final GuardianPlayerEntry<Player> entityEntry = sequenceContext.get(CommonContextKeys.ENTITY_ENTRY);
        final Summary summary = sequenceContext.get(CommonContextKeys.SUMMARY);
        final GuardianCaptureRegistry captureRegistry = sequenceContext.get(CommonContextKeys.CAPTURE_REGISTRY);
        final long lastActionTime = sequenceContext.get(CommonContextKeys.LAST_ACTION_TIME);
        summary.set(SequenceReport.class, new SequenceReport(false, Origin.source(sequenceContext.getRoot()).owner(entityEntry).build()));
        if (!entityEntry.getEntity(Player.class).isPresent())
            return false;
        final Player player = entityEntry.getEntity(Player.class).get();
        /*
                         * Capture Collection
                         */
        final CaptureContainer captureContainer = captureRegistry.getContainer();
        final Optional<Location> initial = captureContainer.get(GuardianSequence.INITIAL_LOCATION);
        final Optional<Double> effectSpeedAmplifier = captureContainer.get(PotionEffectCapture.HORIZONTAL_SPEED_MODIFIER);
        final Optional<Double> materialSpeedAmplifier = captureContainer.get(MaterialCapture.SPEED_MODIFIER);
        final Optional<Double> horizontalOffset = captureContainer.get(ControlCapture.HORIZONTAL_DISTANCE);
        final Optional<Map<String, Integer>> activeControls = captureContainer.get(ControlCapture.ACTIVE_CONTROL_TICKS);
        if (!initial.isPresent() || !materialSpeedAmplifier.isPresent() || !horizontalOffset.isPresent())
            return false;
        long current = System.currentTimeMillis();
        // Gets the average between now and the last action.
        final double averageActionTime = ((current - lastActionTime) / 1000) / 0.05;
        if (averageActionTime < minimumTickRate) {
            detection.getLogger().warn("The server may be overloaded. A check could not be completed.");
            return false;
        } else if (averageActionTime > maximumTickRate) {
            return false;
        }
        if (player.get(Keys.VEHICLE).isPresent())
            return false;
        double intercept = analysisIntercept + (effectSpeedAmplifier.orElse(0d) / analysisTime);
        final Optional<Map.Entry<String, Integer>> validControlTicks = activeControls.get().entrySet().stream().max(Comparator.comparingInt(Map.Entry::getValue));
        // Gets the players horizontal displacement in the world.
        final double horizontalDisplacement = Math.abs((player.getLocation().getX() - initial.get().getX()) + (player.getLocation().getZ() - initial.get().getZ()));
        // Gets the percentage of the displacement that is the most important.
        final double maximumHorizontalDisplacement = validControlTicks.map(entry -> horizontalDisplacement * (entry.getValue() / averageActionTime)).orElse(horizontalDisplacement);
        // Gets the players maximum horizontal speed in the world, for this analysis.
        final double maximumHorizontalSpeed = (((horizontalOffset.get() * materialSpeedAmplifier.get()) / 2) / averageActionTime) + intercept;
        if (horizontalDisplacement <= 1 || maximumHorizontalDisplacement < 1 || maximumHorizontalSpeed < 1)
            return false;
        if (maximumHorizontalDisplacement > maximumHorizontalSpeed) {
            // ------------------------- DEBUG -----------------------------
            System.out.println(player.getName() + " has been caught using horizontal speed hacks. (" + (maximumHorizontalDisplacement - maximumHorizontalSpeed) + ")");
            // -------------------------------------------------------------
            SequenceReport report = new SequenceReport(true, Origin.source(sequenceContext.getRoot()).owner(entityEntry).build());
            report.put("type", "Horizontal Speed");
            report.put("information", Collections.singletonList("Overshot maximum movement by " + (maximumHorizontalDisplacement - maximumHorizontalSpeed) + "."));
            report.put("initial_location", initial.get());
            report.put("final_location", player.getLocation());
            report.put("severity", (maximumHorizontalDisplacement - maximumHorizontalSpeed) / maximumHorizontalDisplacement);
            summary.set(SequenceReport.class, report);
            return true;
        }
        return false;
    }, ConditionType.NORMAL).build(SequenceContext.builder().owner(detection).root(this).build());
}
Also used : GuardianSequenceBuilder(com.ichorpowered.guardian.sequence.GuardianSequenceBuilder) Summary(com.ichorpowered.guardianapi.detection.report.Summary) ContentKeys(com.ichorpowered.guardianapi.content.ContentKeys) Keys(org.spongepowered.api.data.key.Keys) GuardianValue(com.ichorpowered.guardian.util.item.mutable.GuardianValue) Origin(com.ichorpowered.guardianapi.event.origin.Origin) PotionEffectCapture(com.ichorpowered.guardian.common.capture.player.PotionEffectCapture) GuardianCaptureRegistry(com.ichorpowered.guardian.sequence.capture.GuardianCaptureRegistry) SequenceReport(com.ichorpowered.guardian.sequence.SequenceReport) Map(java.util.Map) ConditionType(com.abilityapi.sequenceapi.action.condition.ConditionType) Location(org.spongepowered.api.world.Location) GuardianSequence(com.ichorpowered.guardian.sequence.GuardianSequence) Event(org.spongepowered.api.event.Event) Set(java.util.Set) SequenceContext(com.abilityapi.sequenceapi.SequenceContext) Sets(com.google.common.collect.Sets) Check(com.ichorpowered.guardianapi.detection.check.Check) GuardianPlayerEntry(com.ichorpowered.guardian.entry.GuardianPlayerEntry) Detection(com.ichorpowered.guardianapi.detection.Detection) CommonContextKeys(com.ichorpowered.guardian.sequence.context.CommonContextKeys) CaptureContainer(com.ichorpowered.guardianapi.detection.capture.CaptureContainer) ControlCapture(com.ichorpowered.guardian.common.capture.player.ControlCapture) Optional(java.util.Optional) Player(org.spongepowered.api.entity.living.player.Player) SequenceBlueprint(com.abilityapi.sequenceapi.SequenceBlueprint) Comparator(java.util.Comparator) MaterialCapture(com.ichorpowered.guardian.common.capture.world.MaterialCapture) Collections(java.util.Collections) MoveEntityEvent(org.spongepowered.api.event.entity.MoveEntityEvent) Player(org.spongepowered.api.entity.living.player.Player) Optional(java.util.Optional) ControlCapture(com.ichorpowered.guardian.common.capture.player.ControlCapture) SequenceReport(com.ichorpowered.guardian.sequence.SequenceReport) GuardianPlayerEntry(com.ichorpowered.guardian.entry.GuardianPlayerEntry) GuardianPlayerEntry(com.ichorpowered.guardian.entry.GuardianPlayerEntry) MaterialCapture(com.ichorpowered.guardian.common.capture.world.MaterialCapture) PotionEffectCapture(com.ichorpowered.guardian.common.capture.player.PotionEffectCapture) CaptureContainer(com.ichorpowered.guardianapi.detection.capture.CaptureContainer) Summary(com.ichorpowered.guardianapi.detection.report.Summary) GuardianSequenceBuilder(com.ichorpowered.guardian.sequence.GuardianSequenceBuilder) Map(java.util.Map) GuardianCaptureRegistry(com.ichorpowered.guardian.sequence.capture.GuardianCaptureRegistry)

Example 3 with Summary

use of com.ichorpowered.guardianapi.detection.report.Summary in project guardian by ichorpowered.

the class InvalidCheck method getSequence.

@Nonnull
@Override
public SequenceBlueprint<Event> getSequence(final Detection detection) {
    final Double analysisTime = detection.getContentContainer().get(ContentKeys.ANALYSIS_TIME).orElse(GuardianValue.empty()).getDirect().orElse(0d) / 0.05;
    final Double minimumTickRate = detection.getContentContainer().get(ContentKeys.ANALYSIS_MINIMUM_TICK).orElse(GuardianValue.empty()).getDirect().orElse(0d) / 0.05;
    final Double maximumTickRate = detection.getContentContainer().get(ContentKeys.ANALYSIS_MAXIMUM_TICK).orElse(GuardianValue.empty()).getDirect().orElse(0d) / 0.05;
    return new GuardianSequenceBuilder().capture(new InvalidControlCapture(detection.getPlugin(), detection)).observe(MoveEntityEvent.class).observe(MoveEntityEvent.class).delay(analysisTime.intValue()).expire(maximumTickRate.intValue()).condition(sequenceContext -> {
        final GuardianPlayerEntry<Player> entityEntry = sequenceContext.get(CommonContextKeys.ENTITY_ENTRY);
        final Summary summary = sequenceContext.get(CommonContextKeys.SUMMARY);
        final GuardianCaptureRegistry captureRegistry = sequenceContext.get(CommonContextKeys.CAPTURE_REGISTRY);
        final long lastActionTime = sequenceContext.get(CommonContextKeys.LAST_ACTION_TIME);
        summary.set(SequenceReport.class, new SequenceReport(false, Origin.source(sequenceContext.getRoot()).owner(entityEntry).build()));
        if (!entityEntry.getEntity(Player.class).isPresent())
            return false;
        final Player player = entityEntry.getEntity(Player.class).get();
        /*
                         * Capture Collection
                         */
        final CaptureContainer captureContainer = captureRegistry.getContainer();
        Optional<Location> initial = captureContainer.get(GuardianSequence.INITIAL_LOCATION);
        Optional<Set<String>> invalidControls = captureContainer.get(InvalidControlCapture.INVALID_CONTROLS);
        if (!initial.isPresent() || !invalidControls.isPresent())
            return false;
        long current = System.currentTimeMillis();
        // Finds the average between now and the last action.
        double averageClockRate = ((current - lastActionTime) / 1000) / 0.05;
        if (averageClockRate < minimumTickRate) {
            detection.getLogger().warn("The server may be overloaded. A check could not be completed.");
            return false;
        } else if (averageClockRate > maximumTickRate) {
            return false;
        }
        if (invalidControls.get().isEmpty() || player.get(Keys.VEHICLE).isPresent())
            return false;
        // ------------------------- DEBUG -----------------------------
        System.out.println(player.getName() + " has been caught using invalid movement hacks.");
        // -------------------------------------------------------------
        SequenceReport report = new SequenceReport(true, Origin.source(sequenceContext.getRoot()).owner(entityEntry).build());
        report.put("type", "InvalidControlCapture Movement");
        report.put("information", Collections.singletonList("Received invalid controls of " + StringUtils.join((Set<String>) invalidControls.get(), ", ") + "."));
        report.put("initial_location", initial.get());
        report.put("final_location", player.getLocation());
        report.put("severity", 1d);
        summary.set(SequenceReport.class, report);
        return true;
    }, ConditionType.NORMAL).build(SequenceContext.builder().owner(detection).root(this).build());
}
Also used : GuardianSequenceBuilder(com.ichorpowered.guardian.sequence.GuardianSequenceBuilder) Summary(com.ichorpowered.guardianapi.detection.report.Summary) ContentKeys(com.ichorpowered.guardianapi.content.ContentKeys) Keys(org.spongepowered.api.data.key.Keys) StringUtils(org.apache.commons.lang3.StringUtils) GuardianValue(com.ichorpowered.guardian.util.item.mutable.GuardianValue) Origin(com.ichorpowered.guardianapi.event.origin.Origin) GuardianCaptureRegistry(com.ichorpowered.guardian.sequence.capture.GuardianCaptureRegistry) SequenceReport(com.ichorpowered.guardian.sequence.SequenceReport) Nonnull(javax.annotation.Nonnull) ConditionType(com.abilityapi.sequenceapi.action.condition.ConditionType) Location(org.spongepowered.api.world.Location) GuardianSequence(com.ichorpowered.guardian.sequence.GuardianSequence) Event(org.spongepowered.api.event.Event) InvalidControlCapture(com.ichorpowered.guardian.common.capture.player.InvalidControlCapture) Set(java.util.Set) SequenceContext(com.abilityapi.sequenceapi.SequenceContext) Sets(com.google.common.collect.Sets) Check(com.ichorpowered.guardianapi.detection.check.Check) GuardianPlayerEntry(com.ichorpowered.guardian.entry.GuardianPlayerEntry) Detection(com.ichorpowered.guardianapi.detection.Detection) CommonContextKeys(com.ichorpowered.guardian.sequence.context.CommonContextKeys) CaptureContainer(com.ichorpowered.guardianapi.detection.capture.CaptureContainer) Optional(java.util.Optional) Player(org.spongepowered.api.entity.living.player.Player) SequenceBlueprint(com.abilityapi.sequenceapi.SequenceBlueprint) Collections(java.util.Collections) MoveEntityEvent(org.spongepowered.api.event.entity.MoveEntityEvent) Player(org.spongepowered.api.entity.living.player.Player) MoveEntityEvent(org.spongepowered.api.event.entity.MoveEntityEvent) Set(java.util.Set) InvalidControlCapture(com.ichorpowered.guardian.common.capture.player.InvalidControlCapture) Optional(java.util.Optional) SequenceReport(com.ichorpowered.guardian.sequence.SequenceReport) GuardianPlayerEntry(com.ichorpowered.guardian.entry.GuardianPlayerEntry) CaptureContainer(com.ichorpowered.guardianapi.detection.capture.CaptureContainer) Summary(com.ichorpowered.guardianapi.detection.report.Summary) GuardianSequenceBuilder(com.ichorpowered.guardian.sequence.GuardianSequenceBuilder) GuardianCaptureRegistry(com.ichorpowered.guardian.sequence.capture.GuardianCaptureRegistry) Nonnull(javax.annotation.Nonnull)

Example 4 with Summary

use of com.ichorpowered.guardianapi.detection.report.Summary in project guardian by ichorpowered.

the class VerticalSpeedCheck method getSequence.

@Nonnull
@Override
public SequenceBlueprint<Event> getSequence(final Detection detection) {
    final Double analysisTime = detection.getContentContainer().get(ContentKeys.ANALYSIS_TIME).orElse(GuardianValue.empty()).getDirect().orElse(0d) / 0.05;
    final Double minimumTickRate = detection.getContentContainer().get(ContentKeys.ANALYSIS_MINIMUM_TICK).orElse(GuardianValue.empty()).getDirect().orElse(0d) / 0.05;
    final Double maximumTickRate = detection.getContentContainer().get(ContentKeys.ANALYSIS_MAXIMUM_TICK).orElse(GuardianValue.empty()).getDirect().orElse(0d) / 0.05;
    return new GuardianSequenceBuilder().capture(new ControlCapture(detection.getPlugin(), detection)).capture(new PotionEffectCapture(detection.getPlugin(), detection)).observe(MoveEntityEvent.class).after().delay(analysisTime.intValue()).condition(sequenceContext -> {
        final GuardianPlayerEntry<Player> entityEntry = sequenceContext.get(CommonContextKeys.ENTITY_ENTRY);
        final Summary summary = sequenceContext.get(CommonContextKeys.SUMMARY);
        final GuardianCaptureRegistry captureRegistry = sequenceContext.get(CommonContextKeys.CAPTURE_REGISTRY);
        final long lastActionTime = sequenceContext.get(CommonContextKeys.LAST_ACTION_TIME);
        summary.set(SequenceReport.class, new SequenceReport(false, Origin.source(sequenceContext.getRoot()).owner(entityEntry).build()));
        if (!entityEntry.getEntity(Player.class).isPresent())
            return false;
        Player player = entityEntry.getEntity(Player.class).get();
        /*
                         * Capture Collection
                         */
        final CaptureContainer captureContainer = captureRegistry.getContainer();
        Optional<Location> initial = captureContainer.get(GuardianSequence.INITIAL_LOCATION);
        Optional<Double> verticalOffset = captureContainer.get(ControlCapture.VERTICAL_DISTANCE);
        if (!initial.isPresent() || !verticalOffset.isPresent())
            return false;
        long current = System.currentTimeMillis();
        // Finds the average between now and the last action.
        double averageClockRate = ((current - lastActionTime) / 1000) / 0.05;
        if (averageClockRate < minimumTickRate) {
            detection.getLogger().warn("The server may be overloaded. A check could not be completed.");
            return false;
        } else if (averageClockRate > maximumTickRate) {
            return false;
        }
        if (player.get(Keys.VEHICLE).isPresent())
            return false;
        double verticalDisplacement = MathUtil.truncateDownTo(player.getLocation().getY() - initial.get().getY(), 4);
        double verticalPlacement = MathUtil.truncateDownTo((verticalOffset.get() * (verticalOffset.get() / 0.2)) / averageClockRate + 0.1, 4);
        if (verticalDisplacement < 1 || verticalOffset.get() < 1)
            return false;
        if (verticalDisplacement > verticalPlacement) {
            // ------------------------- DEBUG -----------------------------
            System.out.println(player.getName() + " has been caught using vertical speed hacks. (" + (verticalDisplacement - verticalPlacement) + ")");
            // -------------------------------------------------------------
            SequenceReport report = new SequenceReport(true, Origin.source(sequenceContext.getRoot()).owner(entityEntry).build());
            report.put("type", "Vertical Speed");
            report.put("information", Collections.singletonList("Overshot maximum movement by " + (verticalDisplacement - verticalPlacement) + "."));
            report.put("initial_location", initial.get());
            report.put("final_location", player.getLocation());
            report.put("severity", (verticalDisplacement - verticalPlacement) / verticalDisplacement);
            summary.set(SequenceReport.class, report);
            return true;
        }
        return false;
    }, ConditionType.NORMAL).build(SequenceContext.builder().owner(detection).root(this).build());
}
Also used : ControlCapture(com.ichorpowered.guardian.common.capture.player.ControlCapture) GuardianSequenceBuilder(com.ichorpowered.guardian.sequence.GuardianSequenceBuilder) Summary(com.ichorpowered.guardianapi.detection.report.Summary) ContentKeys(com.ichorpowered.guardianapi.content.ContentKeys) Keys(org.spongepowered.api.data.key.Keys) GuardianValue(com.ichorpowered.guardian.util.item.mutable.GuardianValue) Origin(com.ichorpowered.guardianapi.event.origin.Origin) PotionEffectCapture(com.ichorpowered.guardian.common.capture.player.PotionEffectCapture) GuardianCaptureRegistry(com.ichorpowered.guardian.sequence.capture.GuardianCaptureRegistry) SequenceReport(com.ichorpowered.guardian.sequence.SequenceReport) Nonnull(javax.annotation.Nonnull) ConditionType(com.abilityapi.sequenceapi.action.condition.ConditionType) Location(org.spongepowered.api.world.Location) GuardianSequence(com.ichorpowered.guardian.sequence.GuardianSequence) Event(org.spongepowered.api.event.Event) Set(java.util.Set) SequenceContext(com.abilityapi.sequenceapi.SequenceContext) Sets(com.google.common.collect.Sets) Check(com.ichorpowered.guardianapi.detection.check.Check) GuardianPlayerEntry(com.ichorpowered.guardian.entry.GuardianPlayerEntry) Detection(com.ichorpowered.guardianapi.detection.Detection) MathUtil(com.ichorpowered.guardian.util.MathUtil) CommonContextKeys(com.ichorpowered.guardian.sequence.context.CommonContextKeys) CaptureContainer(com.ichorpowered.guardianapi.detection.capture.CaptureContainer) ControlCapture(com.ichorpowered.guardian.common.capture.player.ControlCapture) Optional(java.util.Optional) Player(org.spongepowered.api.entity.living.player.Player) SequenceBlueprint(com.abilityapi.sequenceapi.SequenceBlueprint) Collections(java.util.Collections) MoveEntityEvent(org.spongepowered.api.event.entity.MoveEntityEvent) SequenceReport(com.ichorpowered.guardian.sequence.SequenceReport) Player(org.spongepowered.api.entity.living.player.Player) GuardianPlayerEntry(com.ichorpowered.guardian.entry.GuardianPlayerEntry) Optional(java.util.Optional) PotionEffectCapture(com.ichorpowered.guardian.common.capture.player.PotionEffectCapture) CaptureContainer(com.ichorpowered.guardianapi.detection.capture.CaptureContainer) Summary(com.ichorpowered.guardianapi.detection.report.Summary) GuardianSequenceBuilder(com.ichorpowered.guardian.sequence.GuardianSequenceBuilder) GuardianCaptureRegistry(com.ichorpowered.guardian.sequence.capture.GuardianCaptureRegistry) Nonnull(javax.annotation.Nonnull)

Aggregations

SequenceBlueprint (com.abilityapi.sequenceapi.SequenceBlueprint)4 SequenceContext (com.abilityapi.sequenceapi.SequenceContext)4 ConditionType (com.abilityapi.sequenceapi.action.condition.ConditionType)4 Sets (com.google.common.collect.Sets)4 GuardianPlayerEntry (com.ichorpowered.guardian.entry.GuardianPlayerEntry)4 GuardianSequence (com.ichorpowered.guardian.sequence.GuardianSequence)4 GuardianSequenceBuilder (com.ichorpowered.guardian.sequence.GuardianSequenceBuilder)4 SequenceReport (com.ichorpowered.guardian.sequence.SequenceReport)4 GuardianCaptureRegistry (com.ichorpowered.guardian.sequence.capture.GuardianCaptureRegistry)4 CommonContextKeys (com.ichorpowered.guardian.sequence.context.CommonContextKeys)4 GuardianValue (com.ichorpowered.guardian.util.item.mutable.GuardianValue)4 ContentKeys (com.ichorpowered.guardianapi.content.ContentKeys)4 Detection (com.ichorpowered.guardianapi.detection.Detection)4 CaptureContainer (com.ichorpowered.guardianapi.detection.capture.CaptureContainer)4 Check (com.ichorpowered.guardianapi.detection.check.Check)4 Summary (com.ichorpowered.guardianapi.detection.report.Summary)4 Origin (com.ichorpowered.guardianapi.event.origin.Origin)4 Collections (java.util.Collections)4 Optional (java.util.Optional)4 Set (java.util.Set)4