Compare commits
29
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
72b8616ffe | ||
|
|
f82cce32f6 | ||
|
|
474ae7dd27 | ||
|
|
d85c1d267b | ||
|
|
6ce2bcb9e9 | ||
|
|
48eff610c3 | ||
|
|
677dd044ff | ||
|
|
87f30eea37 | ||
|
|
370da407ce | ||
|
|
1ef4b4eec9 | ||
|
|
954eb8b51c | ||
|
|
84ceaa29dc | ||
|
|
6974d61b9d | ||
|
|
d9a3a890c8 | ||
|
|
c4495d995a | ||
|
|
9bd5c2db0b | ||
|
|
2518b23f8b | ||
|
|
bd2ceeeed4 | ||
|
|
a6d082b355 | ||
|
|
3fedd558d6 | ||
|
|
0f3bf60549 | ||
|
|
deb2628f77 | ||
|
|
2de0f49af9 | ||
|
|
39a53db067 | ||
|
|
9bfc7d7d9b | ||
|
|
7c93eda985 | ||
|
|
1e7a858aa0 | ||
|
|
11fba1b6bd | ||
|
|
330a9782bc |
No files matched your search
+1
-1
@@ -60,7 +60,7 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation("com.github.retrooper:packetevents-spigot:2.5.1-SNAPSHOT")
|
||||
implementation("com.github.retrooper:packetevents-spigot:2.6.1-SNAPSHOT")
|
||||
implementation("co.aikar:acf-paper:0.5.1-SNAPSHOT")
|
||||
implementation("club.minnced:discord-webhooks:0.8.0") // Newer versions include kotlin-stdlib, which leads to incompatibility with plugins that use Kotlin
|
||||
implementation("it.unimi.dsi:fastutil:8.5.13")
|
||||
|
||||
@@ -23,7 +23,8 @@ public class BadPacketsE extends Check implements PacketCheck {
|
||||
noReminderTicks = 0;
|
||||
} else if (WrapperPlayClientPlayerFlying.isFlying(event.getPacketType())) {
|
||||
noReminderTicks++;
|
||||
} else if (event.getPacketType() == PacketType.Play.Client.STEER_VEHICLE) {
|
||||
} else if (event.getPacketType() == PacketType.Play.Client.STEER_VEHICLE ||
|
||||
event.getPacketType() == PacketType.Play.Client.VEHICLE_MOVE) {
|
||||
noReminderTicks = 0; // Exempt vehicles
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,9 @@ public class BadPacketsR extends Check implements PacketCheck {
|
||||
if ((event.getPacketType() == PacketType.Play.Client.PLAYER_POSITION_AND_ROTATION ||
|
||||
event.getPacketType() == PacketType.Play.Client.PLAYER_POSITION) && !player.compensatedEntities.getSelf().inVehicle()) {
|
||||
positions++;
|
||||
} else if (event.getPacketType() == PacketType.Play.Client.STEER_VEHICLE && player.compensatedEntities.getSelf().inVehicle()) {
|
||||
} else if ((event.getPacketType() == PacketType.Play.Client.STEER_VEHICLE ||
|
||||
event.getPacketType() == PacketType.Play.Client.VEHICLE_MOVE)
|
||||
&& player.compensatedEntities.getSelf().inVehicle()) {
|
||||
positions++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package ac.grim.grimac.checks.impl.badpackets;
|
||||
|
||||
import ac.grim.grimac.GrimAPI;
|
||||
import ac.grim.grimac.checks.Check;
|
||||
import ac.grim.grimac.checks.CheckData;
|
||||
import ac.grim.grimac.checks.type.PacketCheck;
|
||||
@@ -8,22 +9,48 @@ import com.github.retrooper.packetevents.event.PacketReceiveEvent;
|
||||
import com.github.retrooper.packetevents.protocol.item.type.ItemTypes;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.protocol.player.DiggingAction;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.WrappedBlockState;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.type.StateType;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.type.StateTypes;
|
||||
import com.github.retrooper.packetevents.util.Vector3d;
|
||||
import com.github.retrooper.packetevents.util.Vector3i;
|
||||
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerDigging;
|
||||
|
||||
@CheckData(name = "BadPacketsX", experimental = true)
|
||||
@CheckData(name = "BadPacketsX")
|
||||
public class BadPacketsX extends Check implements PacketCheck {
|
||||
public BadPacketsX(GrimPlayer player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
private int lastTick;
|
||||
private boolean didLastFlag;
|
||||
private Vector3i lastBreakLoc;
|
||||
private StateType lastBlockType;
|
||||
|
||||
public final boolean noFireHitbox = player.getClientVersion().isOlderThanOrEquals(ClientVersion.V_1_15_2);
|
||||
|
||||
public final void handle(PacketReceiveEvent event, WrapperPlayClientPlayerDigging dig, StateType block) {
|
||||
if (dig.getAction() != DiggingAction.START_DIGGING && dig.getAction() != DiggingAction.FINISHED_DIGGING)
|
||||
return;
|
||||
|
||||
// Fixes false from breaking kelp underwater
|
||||
// The client sends two start digging packets to the server both in the same tick. BadPacketsX gets called twice, doesn't false the first time, but falses the second
|
||||
// One ends up breaking the kelp, the other ends up doing nothing besides falsing this check because we think they're trying to mine water
|
||||
// I am explicitly making this patch as narrow and specific as possible to potentially discover other blocks that exhibit similar behaviour
|
||||
int newTick = GrimAPI.INSTANCE.getTickManager().currentTick;
|
||||
if (lastTick == newTick
|
||||
&& lastBreakLoc.equals(dig.getBlockPosition())
|
||||
&& !didLastFlag
|
||||
&& lastBlockType.getHardness() == 0.0F
|
||||
&& lastBlockType.getBlastResistance() == 0.0F
|
||||
&& block == StateTypes.WATER
|
||||
) {
|
||||
return;
|
||||
}
|
||||
lastTick = newTick;
|
||||
lastBreakLoc = dig.getBlockPosition();
|
||||
lastBlockType = block;
|
||||
|
||||
// the block does not have a hitbox
|
||||
boolean invalid = (block == StateTypes.LIGHT && !(player.getInventory().getHeldItem().is(ItemTypes.LIGHT) || player.getInventory().getOffHand().is(ItemTypes.LIGHT)))
|
||||
|| block.isAir()
|
||||
@@ -36,8 +63,11 @@ public class BadPacketsX extends Check implements PacketCheck {
|
||||
|| block.getHardness() == -1.0f && dig.getAction() == DiggingAction.FINISHED_DIGGING;
|
||||
|
||||
if (invalid && flagAndAlert("block=" + block.getName() + ", type=" + dig.getAction()) && shouldModifyPackets()) {
|
||||
didLastFlag = true;
|
||||
event.setCancelled(true);
|
||||
player.onPacketCancel();
|
||||
} else {
|
||||
didLastFlag = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,8 @@ package ac.grim.grimac.commands;
|
||||
import ac.grim.grimac.GrimAPI;
|
||||
import ac.grim.grimac.utils.anticheat.MessageUtil;
|
||||
import co.aikar.commands.BaseCommand;
|
||||
import co.aikar.commands.BukkitCommandCompletionContext;
|
||||
import co.aikar.commands.CommandCompletions.CommandCompletionHandler;
|
||||
import co.aikar.commands.annotation.CommandAlias;
|
||||
import co.aikar.commands.annotation.CommandCompletion;
|
||||
import co.aikar.commands.annotation.CommandPermission;
|
||||
@@ -10,16 +12,21 @@ import co.aikar.commands.annotation.Subcommand;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@CommandAlias("grim|grimac")
|
||||
public class GrimStopSpectating extends BaseCommand {
|
||||
public static final CommandCompletionHandler<BukkitCommandCompletionContext> completionHandler = context -> context.getSender().hasPermission("grim.spectate.stophere") ? List.of("here") : List.of();
|
||||
|
||||
@Subcommand("stopspectating")
|
||||
@CommandPermission("grim.spectate")
|
||||
@CommandCompletion("here")
|
||||
@CommandCompletion("@stopspectating")
|
||||
public void onStopSpectate(CommandSender sender, String[] args) {
|
||||
String string = args.length > 0 ? args[0] : null;
|
||||
if (!(sender instanceof Player player)) return;
|
||||
if (!(sender instanceof Player)) return;
|
||||
Player player = (Player) sender;
|
||||
if (GrimAPI.INSTANCE.getSpectateManager().isSpectating(player.getUniqueId())) {
|
||||
boolean teleportBack = string == null || !string.equalsIgnoreCase("here");
|
||||
boolean teleportBack = string == null || !string.equalsIgnoreCase("here") || !sender.hasPermission("grim.spectate.stophere");
|
||||
GrimAPI.INSTANCE.getSpectateManager().disable(player, teleportBack);
|
||||
} else {
|
||||
String message = GrimAPI.INSTANCE.getConfigManager().getConfig().getStringElse("cannot-spectate-return", "%prefix% &cYou can only do this after spectating a player.");
|
||||
|
||||
@@ -98,6 +98,10 @@ public class PacketEntityReplication extends Check implements PacketCheck {
|
||||
WrapperPlayServerSpawnPlayer packetOutEntity = new WrapperPlayServerSpawnPlayer(event);
|
||||
addEntity(packetOutEntity.getEntityId(), packetOutEntity.getUUID(), EntityTypes.PLAYER, packetOutEntity.getPosition(), packetOutEntity.getYaw(), packetOutEntity.getPitch(), packetOutEntity.getEntityMetadata(), 0);
|
||||
}
|
||||
if (event.getPacketType() == PacketType.Play.Server.SPAWN_PAINTING) {
|
||||
WrapperPlayServerSpawnPainting packetOutEntity = new WrapperPlayServerSpawnPainting(event);
|
||||
addEntity(packetOutEntity.getEntityId(), packetOutEntity.getUUID(), EntityTypes.PAINTING, packetOutEntity.getPosition().toVector3d(), packetOutEntity.getDirection().getHorizontalIndex(), 0f, null, packetOutEntity.getType().isPresent() ? packetOutEntity.getType().get().getId() : -1);
|
||||
}
|
||||
|
||||
if (event.getPacketType() == PacketType.Play.Server.ENTITY_RELATIVE_MOVE) {
|
||||
WrapperPlayServerEntityRelativeMove move = new WrapperPlayServerEntityRelativeMove(event);
|
||||
|
||||
@@ -22,7 +22,7 @@ public class PacketPlayerSteer extends PacketListenerAbstract {
|
||||
|
||||
@Override
|
||||
public void onPacketReceive(PacketReceiveEvent event) {
|
||||
|
||||
//TODO: add support for 1.21.2 with new vehicle move packet
|
||||
if (event.getPacketType() == PacketType.Play.Client.STEER_VEHICLE) {
|
||||
WrapperPlayClientSteerVehicle steer = new WrapperPlayClientSteerVehicle(event);
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ import com.github.retrooper.packetevents.util.Vector3i;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerMultiBlockChange;
|
||||
import io.github.retrooper.packetevents.util.folia.FoliaScheduler;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
|
||||
@@ -35,19 +36,20 @@ public class ResyncWorldUtil {
|
||||
|| !player.compensatedWorld.isChunkLoaded(maxBlockX >> 4, minBlockZ >> 4) || !player.compensatedWorld.isChunkLoaded(maxBlockX >> 4, maxBlockZ >> 4))
|
||||
return;
|
||||
|
||||
if (player.bukkitPlayer == null) return;
|
||||
World world = player.bukkitPlayer.getWorld();
|
||||
|
||||
// Takes 0.15ms or so to complete. Not bad IMO. Unsure how I could improve this other than sending packets async.
|
||||
// But that's on PacketEvents.
|
||||
FoliaScheduler.getRegionScheduler().execute(GrimAPI.INSTANCE.getPlugin(), player.bukkitPlayer.getWorld(),
|
||||
FoliaScheduler.getRegionScheduler().execute(GrimAPI.INSTANCE.getPlugin(), world,
|
||||
minBlockX >> 4, minBlockZ >> 4, () -> {
|
||||
boolean flat = PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_13);
|
||||
|
||||
if (player.bukkitPlayer == null) return;
|
||||
// Player hasn't spawned, don't spam packets
|
||||
if (!player.getSetbackTeleportUtil().hasAcceptedSpawnTeleport) return;
|
||||
|
||||
// Check the 4 corners of the BB for loaded chunks, don't freeze main thread to load chunks.
|
||||
if (!player.bukkitPlayer.getWorld().isChunkLoaded(minBlockX >> 4, minBlockZ >> 4) || !player.bukkitPlayer.getWorld().isChunkLoaded(minBlockX >> 4, maxBlockZ >> 4)
|
||||
|| !player.bukkitPlayer.getWorld().isChunkLoaded(maxBlockX >> 4, minBlockZ >> 4) || !player.bukkitPlayer.getWorld().isChunkLoaded(maxBlockX >> 4, maxBlockZ >> 4))
|
||||
if (!world.isChunkLoaded(minBlockX >> 4, minBlockZ >> 4) || !world.isChunkLoaded(minBlockX >> 4, maxBlockZ >> 4)
|
||||
|| !world.isChunkLoaded(maxBlockX >> 4, minBlockZ >> 4) || !world.isChunkLoaded(maxBlockX >> 4, maxBlockZ >> 4))
|
||||
return;
|
||||
|
||||
// This is based on Tuinity's code, thanks leaf. Now merged into paper.
|
||||
@@ -76,7 +78,7 @@ public class ResyncWorldUtil {
|
||||
int minX = currChunkX == minChunkX ? minBlockX & 15 : 0; // coordinate in chunk
|
||||
int maxX = currChunkX == maxChunkX ? maxBlockX & 15 : 15; // coordinate in chunk
|
||||
|
||||
Chunk chunk = player.bukkitPlayer.getWorld().getChunkAt(currChunkX, currChunkZ);
|
||||
Chunk chunk = world.getChunkAt(currChunkX, currChunkZ);
|
||||
|
||||
for (int currChunkY = minChunkY; currChunkY <= maxChunkY; ++currChunkY) {
|
||||
int minY = currChunkY == minChunkY ? minBlockY & 15 : 0; // coordinate in chunk
|
||||
|
||||
@@ -2,13 +2,14 @@ package ac.grim.grimac.manager.init.start;
|
||||
|
||||
import ac.grim.grimac.GrimAPI;
|
||||
import ac.grim.grimac.manager.init.Initable;
|
||||
import io.github.retrooper.packetevents.bstats.bukkit.Metrics;
|
||||
|
||||
public class BStats implements Initable {
|
||||
@Override
|
||||
public void start() {
|
||||
int pluginId = 12820; // <-- Replace with the id of your plugin!
|
||||
try {
|
||||
new io.github.retrooper.packetevents.bstats.Metrics(GrimAPI.INSTANCE.getPlugin(), pluginId);
|
||||
new Metrics(GrimAPI.INSTANCE.getPlugin(), pluginId);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,5 +23,7 @@ public class CommandRegister implements Initable {
|
||||
commandManager.registerCommand(new GrimStopSpectating());
|
||||
commandManager.registerCommand(new GrimLog());
|
||||
commandManager.registerCommand(new GrimVerbose());
|
||||
|
||||
commandManager.getCommandCompletions().registerCompletion("stopspectating", GrimStopSpectating.completionHandler);
|
||||
}
|
||||
}
|
||||
@@ -347,7 +347,7 @@ public class MovementCheckRunner extends Check implements PositionCheck {
|
||||
player.packetStateData.lastRiptide = currentTime;
|
||||
}
|
||||
|
||||
SimpleCollisionBox steppingOnBB = GetBoundingBox.getCollisionBoxForPlayer(player, player.x, player.y, player.z).expand(0.03).offset(0, -1, 0);
|
||||
SimpleCollisionBox steppingOnBB = GetBoundingBox.getCollisionBoxForPlayer(player, player.x, player.y, player.z).expand(player.getMovementThreshold()).offset(0, -1, 0);
|
||||
Collisions.hasMaterial(player, steppingOnBB, (pair) -> {
|
||||
WrappedBlockState data = pair.first();
|
||||
if (data.getType() == StateTypes.SLIME_BLOCK && player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_8)) {
|
||||
@@ -411,8 +411,8 @@ public class MovementCheckRunner extends Check implements PositionCheck {
|
||||
player.uncertaintyHandler.lastUnderwaterFlyingHack.reset();
|
||||
}
|
||||
|
||||
boolean couldBeStuckSpeed = Collisions.checkStuckSpeed(player, 0.03);
|
||||
boolean couldLeaveStuckSpeed = player.isPointThree() && Collisions.checkStuckSpeed(player, -0.03);
|
||||
boolean couldBeStuckSpeed = Collisions.checkStuckSpeed(player, player.getMovementThreshold());
|
||||
boolean couldLeaveStuckSpeed = player.isPointThree() && Collisions.checkStuckSpeed(player, -player.getMovementThreshold());
|
||||
player.uncertaintyHandler.claimingLeftStuckSpeed = !player.compensatedEntities.getSelf().inVehicle() && player.stuckSpeedMultiplier.getX() < 1 && !couldLeaveStuckSpeed;
|
||||
|
||||
if (couldBeStuckSpeed) {
|
||||
|
||||
@@ -268,13 +268,14 @@ public class PlayerBaseTick {
|
||||
|
||||
|
||||
private void moveTowardsClosestSpace(double xPosition, double zPosition) {
|
||||
player.boundingBox = player.boundingBox.expand(0.03, 0, 0.03); // 0.03... thanks mojang!
|
||||
double movementThreshold = player.getMovementThreshold();
|
||||
player.boundingBox = player.boundingBox.expand(movementThreshold, 0, movementThreshold); // 0.03... thanks mojang!
|
||||
if (player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_14)) {
|
||||
moveTowardsClosestSpaceModern(xPosition, zPosition);
|
||||
} else {
|
||||
moveTowardsClosestSpaceLegacy(xPosition, zPosition);
|
||||
}
|
||||
player.boundingBox = player.boundingBox.expand(-0.03, 0, -0.03);
|
||||
player.boundingBox = player.boundingBox.expand(-movementThreshold, 0, -movementThreshold);
|
||||
}
|
||||
|
||||
// Mojang is incompetent and this will push the player out a lot when using elytras
|
||||
|
||||
@@ -127,12 +127,13 @@ public class PointThreeEstimator {
|
||||
|
||||
// Calculate head hitters. Take a shortcut by checking if the player doesn't intersect with this block, but does
|
||||
// when the player vertically moves upwards by 0.03! This is equivalent to the move method, but MUCH faster.
|
||||
SimpleCollisionBox slightlyExpanded = normalBox.copy().expand(0.03, 0, 0.03);
|
||||
if (!slightlyExpanded.isIntersected(data) && slightlyExpanded.offset(0, 0.03, 0).isIntersected(data)) {
|
||||
double movementThreshold = player.getMovementThreshold();
|
||||
SimpleCollisionBox slightlyExpanded = normalBox.copy().expand(movementThreshold, 0, movementThreshold);
|
||||
if (!slightlyExpanded.isIntersected(data) && slightlyExpanded.offset(0, movementThreshold, 0).isIntersected(data)) {
|
||||
headHitter = true;
|
||||
}
|
||||
|
||||
SimpleCollisionBox pointThreeBox = GetBoundingBox.getBoundingBoxFromPosAndSize(player, player.x, player.y - 0.03, player.z, 0.66f, 1.86f);
|
||||
SimpleCollisionBox pointThreeBox = GetBoundingBox.getBoundingBoxFromPosAndSize(player, player.x, player.y - movementThreshold, player.z, 0.66f, 1.86f);
|
||||
if ((Materials.isWater(player.getClientVersion(), state) || stateType == StateTypes.LAVA) &&
|
||||
pointThreeBox.isIntersected(new SimpleCollisionBox(x, y, z))) {
|
||||
|
||||
@@ -212,7 +213,8 @@ public class PointThreeEstimator {
|
||||
}
|
||||
|
||||
public void endOfTickTick() {
|
||||
SimpleCollisionBox pointThreeBox = GetBoundingBox.getBoundingBoxFromPosAndSize(player, player.x, player.y - 0.03, player.z, 0.66f, 1.86f);
|
||||
double movementThreshold = player.getMovementThreshold();
|
||||
SimpleCollisionBox pointThreeBox = GetBoundingBox.getBoundingBoxFromPosAndSize(player, player.x, player.y - movementThreshold, player.z, 0.66f, 1.86f);
|
||||
|
||||
// Determine the head hitter using the current Y position
|
||||
SimpleCollisionBox oldBB = player.boundingBox;
|
||||
@@ -222,7 +224,7 @@ public class PointThreeEstimator {
|
||||
for (float sizes : (player.skippedTickInActualMovement ? new float[]{0.6f, 1.5f, 1.8f} : new float[]{player.pose.height})) {
|
||||
// Try to limit collisions to be as small as possible, for maximum performance
|
||||
player.boundingBox = GetBoundingBox.getBoundingBoxFromPosAndSize(player, player.x, player.y + (sizes - 0.01f), player.z, 0.6f, 0.01f);
|
||||
headHitter = headHitter || Collisions.collide(player, 0, 0.03, 0).getY() != 0.03;
|
||||
headHitter = headHitter || Collisions.collide(player, 0, movementThreshold, 0).getY() != movementThreshold;
|
||||
}
|
||||
|
||||
player.boundingBox = oldBB;
|
||||
|
||||
-1
@@ -16,7 +16,6 @@ import com.github.retrooper.packetevents.protocol.world.states.enums.*;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.type.StateType;
|
||||
import com.github.retrooper.packetevents.protocol.world.states.type.StateTypes;
|
||||
|
||||
|
||||
public class DynamicHitboxFence extends DynamicConnecting implements HitBoxFactory {
|
||||
private static final CollisionBox[] MODERN_HITBOXES = makeShapes(2.0F, 2.0F, 24.0F, 0.0F, 24.0F, true, 1);
|
||||
|
||||
|
||||
@@ -20,8 +20,8 @@ public class ComplexCollisionBox implements CollisionBox {
|
||||
|
||||
public ComplexCollisionBox(int maxIndex, SimpleCollisionBox... boxes) {
|
||||
this.boxes = new SimpleCollisionBox[maxIndex];
|
||||
System.arraycopy(boxes, 0, this.boxes, 0, Math.min(maxIndex, boxes.length));
|
||||
currentLength = boxes.length;
|
||||
currentLength = Math.min(maxIndex, boxes.length);
|
||||
System.arraycopy(boxes, 0, this.boxes, 0, this.currentLength);
|
||||
}
|
||||
|
||||
public boolean add(SimpleCollisionBox collisionBox) {
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package ac.grim.grimac.utils.data.packetentity;
|
||||
|
||||
import ac.grim.grimac.player.GrimPlayer;
|
||||
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
|
||||
import com.github.retrooper.packetevents.protocol.world.Direction;
|
||||
import com.github.retrooper.packetevents.protocol.world.PaintingType;
|
||||
import lombok.Getter;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@Getter
|
||||
public class PacketEntityPainting extends PacketEntity {
|
||||
|
||||
private final @Nullable PaintingType paintingType;
|
||||
private final Direction direction;
|
||||
|
||||
public PacketEntityPainting(GrimPlayer player, UUID uuid, double x, double y, double z, @Nullable PaintingType paintingType, Direction direction) {
|
||||
super(player, uuid, EntityTypes.PAINTING, x, y, z);
|
||||
this.paintingType = paintingType;
|
||||
this.direction = direction;
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,8 @@ import com.github.retrooper.packetevents.protocol.player.UserProfile;
|
||||
import com.github.retrooper.packetevents.protocol.potion.PotionType;
|
||||
import com.github.retrooper.packetevents.protocol.potion.PotionTypes;
|
||||
import com.github.retrooper.packetevents.protocol.world.BlockFace;
|
||||
import com.github.retrooper.packetevents.protocol.world.Direction;
|
||||
import com.github.retrooper.packetevents.protocol.world.PaintingType;
|
||||
import com.github.retrooper.packetevents.resources.ResourceLocation;
|
||||
import com.github.retrooper.packetevents.util.Vector3d;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerUpdateAttributes;
|
||||
@@ -168,22 +170,22 @@ public class CompensatedEntities {
|
||||
packetEntity = new PacketEntityHorse(player, uuid, entityType, position.getX(), position.getY(), position.getZ(), xRot);
|
||||
} else if (entityType == EntityTypes.SLIME || entityType == EntityTypes.MAGMA_CUBE || entityType == EntityTypes.PHANTOM) {
|
||||
packetEntity = new PacketEntitySizeable(player, uuid, entityType, position.getX(), position.getY(), position.getZ());
|
||||
} else if (EntityTypes.PIG.equals(entityType)) {
|
||||
packetEntity = new PacketEntityRideable(player, uuid, entityType, position.getX(), position.getY(), position.getZ());
|
||||
} else if (EntityTypes.SHULKER.equals(entityType)) {
|
||||
packetEntity = new PacketEntityShulker(player, uuid, entityType, position.getX(), position.getY(), position.getZ());
|
||||
} else if (EntityTypes.STRIDER.equals(entityType)) {
|
||||
packetEntity = new PacketEntityStrider(player, uuid, entityType, position.getX(), position.getY(), position.getZ());
|
||||
} else if (EntityTypes.isTypeInstanceOf(entityType, EntityTypes.BOAT) || EntityTypes.CHICKEN.equals(entityType)) {
|
||||
packetEntity = new PacketEntityTrackXRot(player, uuid, entityType, position.getX(), position.getY(), position.getZ(), xRot);
|
||||
} else if (EntityTypes.FISHING_BOBBER.equals(entityType)) {
|
||||
packetEntity = new PacketEntityHook(player, uuid, entityType, position.getX(), position.getY(), position.getZ(), data);
|
||||
} else if (EntityTypes.ENDER_DRAGON.equals(entityType)) {
|
||||
packetEntity = new PacketEntityEnderDragon(player, uuid, entityID, position.getX(), position.getY(), position.getZ());
|
||||
} else if (entityType == EntityTypes.PAINTING) {
|
||||
packetEntity = new PacketEntityPainting(player, uuid, position.x, position.y, position.z, data == -1 ? null : PaintingType.getById(data), Direction.getByHorizontalIndex((int) xRot));
|
||||
} else {
|
||||
if (EntityTypes.PIG.equals(entityType)) {
|
||||
packetEntity = new PacketEntityRideable(player, uuid, entityType, position.getX(), position.getY(), position.getZ());
|
||||
} else if (EntityTypes.SHULKER.equals(entityType)) {
|
||||
packetEntity = new PacketEntityShulker(player, uuid, entityType, position.getX(), position.getY(), position.getZ());
|
||||
} else if (EntityTypes.STRIDER.equals(entityType)) {
|
||||
packetEntity = new PacketEntityStrider(player, uuid, entityType, position.getX(), position.getY(), position.getZ());
|
||||
} else if (EntityTypes.isTypeInstanceOf(entityType, EntityTypes.BOAT) || EntityTypes.CHICKEN.equals(entityType)) {
|
||||
packetEntity = new PacketEntityTrackXRot(player, uuid, entityType, position.getX(), position.getY(), position.getZ(), xRot);
|
||||
} else if (EntityTypes.FISHING_BOBBER.equals(entityType)) {
|
||||
packetEntity = new PacketEntityHook(player, uuid, entityType, position.getX(), position.getY(), position.getZ(), data);
|
||||
} else if (EntityTypes.ENDER_DRAGON.equals(entityType)) {
|
||||
packetEntity = new PacketEntityEnderDragon(player, uuid, entityID, position.getX(), position.getY(), position.getZ());
|
||||
} else {
|
||||
packetEntity = new PacketEntity(player, uuid, entityType, position.getX(), position.getY(), position.getZ());
|
||||
}
|
||||
packetEntity = new PacketEntity(player, uuid, entityType, position.getX(), position.getY(), position.getZ());
|
||||
}
|
||||
|
||||
entityMap.put(entityID, packetEntity);
|
||||
|
||||
@@ -61,13 +61,14 @@ public class Collisions {
|
||||
SimpleCollisionBox oldBB = player.boundingBox;
|
||||
player.boundingBox = GetBoundingBox.getBoundingBoxFromPosAndSize(player, x, y, z, 0.6f, 0.06f);
|
||||
|
||||
double posXZ = Collisions.collide(player, 0.03, -0.03, 0.03).getY();
|
||||
double negXNegZ = Collisions.collide(player, -0.03, -0.03, -0.03).getY();
|
||||
double posXNegZ = Collisions.collide(player, 0.03, -0.03, -0.03).getY();
|
||||
double posZNegX = Collisions.collide(player, -0.03, -0.03, 0.03).getY();
|
||||
double movementThreshold = player.getMovementThreshold();
|
||||
double posXZ = Collisions.collide(player, movementThreshold, -movementThreshold, movementThreshold).getY();
|
||||
double negXNegZ = Collisions.collide(player, -movementThreshold, -movementThreshold, -movementThreshold).getY();
|
||||
double posXNegZ = Collisions.collide(player, movementThreshold, -movementThreshold, -movementThreshold).getY();
|
||||
double posZNegX = Collisions.collide(player, -movementThreshold, -movementThreshold, movementThreshold).getY();
|
||||
|
||||
player.boundingBox = oldBB;
|
||||
return negXNegZ != -0.03 || posXNegZ != -0.03 || posXZ != -0.03 || posZNegX != -0.03;
|
||||
return negXNegZ != -movementThreshold || posXNegZ != -movementThreshold || posXZ != -movementThreshold || posZNegX != -movementThreshold;
|
||||
}
|
||||
|
||||
// Call this when there isn't uncertainty on the Y axis
|
||||
|
||||
@@ -176,14 +176,14 @@ public class ReachUtils {
|
||||
}
|
||||
|
||||
public static double getMinReachToBox(GrimPlayer player, SimpleCollisionBox targetBox) {
|
||||
boolean giveMovementThresholdLenience = player.packetStateData.didLastMovementIncludePosition || player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_9);
|
||||
boolean giveMovementThresholdLenience = !player.packetStateData.didLastMovementIncludePosition || player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_9);
|
||||
if (player.getClientVersion().isOlderThanOrEquals(ClientVersion.V_1_8)) targetBox.expand(0.1);
|
||||
|
||||
double lowest = Double.MAX_VALUE;
|
||||
|
||||
if (giveMovementThresholdLenience) targetBox.expand(player.getMovementThreshold());
|
||||
final double[] possibleEyeHeights = player.getPossibleEyeHeights();
|
||||
for (double eyes : possibleEyeHeights) {
|
||||
if (giveMovementThresholdLenience) targetBox.expand(player.getMovementThreshold());
|
||||
Vector from = new Vector(player.x, player.y + eyes, player.z);
|
||||
Vector closestPoint = VectorUtils.cutBoxToVector(from, targetBox);
|
||||
lowest = Math.min(lowest, closestPoint.distance(from));
|
||||
|
||||
@@ -0,0 +1,198 @@
|
||||
# GrimACのメイン設定
|
||||
# ソースコード: https://github.com/MWHunter/Grim
|
||||
# Copyright 2024 DefineOutside and contributors, Licensed under GPLv3.
|
||||
# 改変されたバイナリやGrimのコードをコピーしたプラグインは、私的なものとするか、
|
||||
# 購入者に追加料金なしで完全なソースコードを公開する必要があります
|
||||
|
||||
# "セットバック"は、Grimによってプレイヤーの違反が検知された際、プレイヤーを元の位置/状態に戻すことを意味します。
|
||||
|
||||
alerts:
|
||||
# アラートを、プレイヤーに送信するだけでなくコンソールにも送信するかどうか。
|
||||
print-to-console: true
|
||||
# これは、プロキシに接続された他のサーバー間でアラートが共有される方法を制御します。
|
||||
# Velocityを使用している場合は、Velocityの設定で 'bungee-plugin-message-channel' を有効にする必要があります。
|
||||
proxy:
|
||||
# プロキシに接続された他のサーバーにアラートを送信するかどうか。
|
||||
send: false
|
||||
# プロキシに接続された他のサーバーからのアラートを受信するかどうか。
|
||||
receive: false
|
||||
|
||||
verbose:
|
||||
print-to-console: false
|
||||
|
||||
client-brand:
|
||||
# プレイヤーのクライアントブランドが以下の正規表現のいずれかと一致する場合、オペレータにはそのプレイヤーの情報が送信されません。
|
||||
ignored-clients:
|
||||
- "^vanilla$"
|
||||
- "^fabric$"
|
||||
- "^lunarclient:v\\d+\\.\\d+\\.\\d+-\\d{4}$"
|
||||
- "^Feather Fabric$"
|
||||
|
||||
spectators:
|
||||
# 'grim.spectator' パーミッションを持つプレイヤーを、実際にスペクテイター状態でなくても非表示にするかどうか。
|
||||
hide-regardless: false
|
||||
# スペクテイター状態のプレイヤーを指定したワールドでのみ非表示にする。(空欄にするとすべてのワールドで有効)
|
||||
allowed-worlds:
|
||||
- ""
|
||||
|
||||
# プレイヤーがタイムアウトでKickされるまでの時間を設定します。 | デフォルト= 60(秒)
|
||||
max-transaction-time: 60
|
||||
|
||||
# 重複した移動パケットをキャンセルしますか?
|
||||
# 1.21でこの問題は修正されました。重複パケットの問題は、Mojangが「バケツの同期ズレ」を修正しようとしたことに起因するものでした。 https://bugs.mojang.com/browse/MC-12363
|
||||
# この設定は、V1.17-1.20.5クライアントが、V1.8サーバーに接続している際にのみ適用されます。
|
||||
cancel-duplicate-packet: true
|
||||
|
||||
# 重複パケットの回転を無視するかどうか。
|
||||
ignore-duplicate-packet-rotation: false
|
||||
|
||||
Simulation:
|
||||
# プレイヤーが違反をしていない場合、違反の度合いをどれだけ減らすかの倍率。
|
||||
# デフォルト設定のグラフ(x軸 = 秒, y軸 = 1/1000ブロック): https://www.desmos.com/calculator/d4ufgxrxer
|
||||
setback-decay-multiplier: 0.999
|
||||
# プレイヤーの動きが、シミュレーションからどれだけズレた場合に違反とみなすか。
|
||||
# シミュレーションされた動きからのズレをブロック単位で設定します。
|
||||
# OptifineのFastMath(計算の最適化)に対応するために計算テーブルを切り替え、0.001に下げるとFastMathによる誤検知を軽減します。
|
||||
# ただし、この補正がうまく機能しない場合、Grimがプレイヤーを不正と判断する可能性があります...
|
||||
threshold: 0.001
|
||||
# プレイヤーを即座にセットバックする前に、シミュレーションされた動きとプレイヤーの実際の動きの間にどれだけの違反が必要かを指定します。
|
||||
# -1で無効化できます。
|
||||
immediate-setback-threshold: 0.1
|
||||
# 全ティックでのシミュレーションとの累積ズレがこの値を超えたらリセットを開始します。
|
||||
# -1で無効化できます。
|
||||
max-advantage: 1
|
||||
# デフォルト設定では、50秒経過すると、プレイヤーのアドバンテージが4ブロックから1ブロックに減少します。
|
||||
# これは、プレイヤーが違反を蓄積しすぎて、違反を解消できなくなるのを防ぐためです。
|
||||
# デフォルトのアドバンテージの上限 (x軸 = 秒, y軸 = 1/1000ブロック): https://www.desmos.com/calculator/4lovswdarj
|
||||
max-ceiling: 4
|
||||
|
||||
# プレイヤーが移動中にブロックに入ったかどうかをチェックします。
|
||||
Phase:
|
||||
setbackvl: 1 # 1ブロック以上のズレがある場合に違反と判断します。
|
||||
decay: 0.005
|
||||
|
||||
AirLiquidPlace:
|
||||
cancelvl: 0
|
||||
|
||||
FabricatedPlace:
|
||||
cancelvl: 5
|
||||
|
||||
FarPlace:
|
||||
cancelvl: 5
|
||||
|
||||
PositionPlace:
|
||||
cancelvl: 5
|
||||
|
||||
RotationPlace:
|
||||
cancelvl: 5
|
||||
|
||||
# 予測に基づく「NoSlow」チェック
|
||||
# Grimは、バグのあるネットコードを考慮しており、右クリックやオフハンドボタンを連打しても誤検知が起こりにくくなっています。
|
||||
# 他のアンチチートよりも安定していますが、もし誤検知があれば報告してください。ネットコードの問題を多数修正しています。
|
||||
NoSlowA:
|
||||
# どれだけのズレが「チート」として扱われるか
|
||||
# デフォルトで他のズレ基準よりも低めに設定されています
|
||||
# NoSlow(速度低下なし)の状態では、0.03〜0.2の範囲で一貫してフラグが立ちます
|
||||
threshold: 0.001
|
||||
# NoSlowによるアドバンテージを無効化するため、最初の項目で即座にセットバックさせます
|
||||
setbackvl: 5
|
||||
# プレイヤーがアイテム使用時に速度低下が発生する場合、この値によりアドバンテージの累積が減少します
|
||||
decay: 0.05
|
||||
|
||||
Knockback:
|
||||
# プレイヤーが違反していない場合、総アドバンテージにどれだけの倍率を掛けるか
|
||||
setback-decay-multiplier: 0.999
|
||||
# プレイヤーの速度からどれだけズレたら違反とみなすか
|
||||
# 許容速度からのズレをブロック単位で測定します
|
||||
threshold: 0.001
|
||||
# プレイヤーが即座にセットバックされる前に、1ティックで発生しなければならない違反のしきい値
|
||||
# -1で無効化できます
|
||||
immediate-setback-threshold: 0.1
|
||||
# 全ティックでの累積アドバンテージがこの値を超えたらセットバックを開始します
|
||||
# -1で無効化できます
|
||||
max-advantage: 1
|
||||
# 違反が過剰に蓄積し、リセットが難しくなるのを防ぐための上限です
|
||||
max-ceiling: 4
|
||||
|
||||
Explosion:
|
||||
threshold: 0.001
|
||||
setbackvl: 3
|
||||
|
||||
TimerA:
|
||||
setbackvl: 10
|
||||
# プレイヤーがネットワーク遅延やラグの影響で操作がサーバーの予測より遅れている場合、
|
||||
# その遅れ分を後で使用できるように蓄積するためのミリ秒数を設定します。
|
||||
# この値を高く設定しすぎると、1.8版の高速使用、高速回復、高速弓などの不正な動作をバイパスできる可能性があるため、
|
||||
# 120ミリ秒がバランスの良い設定とされています。
|
||||
drift: 120
|
||||
# タイマーバランスの制限を開始し、不正利用を防止するためのPingのしきい値
|
||||
# 正当なプレイヤーであっても、このPingのしきい値を超えるとセットバックが発生する場合があります
|
||||
# -1で無効化
|
||||
ping-abuse-limit-threshold: 1000
|
||||
|
||||
NegativeTimer:
|
||||
# プレイヤーが移動中にどれだけミリ秒の遅延が発生した場合にフラグを立て始めるかを指定します
|
||||
# ここで指定した遅延量(ミリ秒)を超えると、違反として検知される可能性があります
|
||||
drift: 1200
|
||||
|
||||
# TimerAと同じチェック方法ですが、乗り物操作に適用されます
|
||||
TimerVehicle:
|
||||
# 目標タイマー値は1.005です
|
||||
setbackvl: 10
|
||||
|
||||
EntityControl:
|
||||
setbackvl: 25
|
||||
|
||||
Reach:
|
||||
# ヒットボックスをどれだけ拡大するかを設定します。0.0005に設定することで3.0005以上のリーチを検出できます
|
||||
#
|
||||
# プロトコルの変更や制限により、1.9〜1.18.1(1.18.2を除く)や
|
||||
# 一部のクライアント/サーバーの組み合わせでは、強制的に0.03の拡大が適用される場合があります。
|
||||
# このチェックは1.7/1.8クライアントが1.8サーバーに接続した際に最も効果的です。
|
||||
threshold: 0.0005
|
||||
# 不可能なヒット(距離的に届かない攻撃)をキャンセルするか
|
||||
# 3.00〜3.03のリーチによるヒットが通る場合がありますが、パケット順序の制限によりフラグが立つこともあります
|
||||
block-impossible-hits: true
|
||||
# チート検出の可能性を高めるため、各ティックの終わりに追加のパケットを送信します
|
||||
# これはサーバーの接続リストに挿入され、サーバーがフラッシュする直前に送信されます
|
||||
# 有効にすると全プレイヤーの帯域幅使用量が増加しますが、サーバーのパフォーマンスは低下しません
|
||||
# 有効にすることでさらに多くのチーターを検出できますが、
|
||||
# 無効のままでもチーターを検出でき、誤検知も発生しません
|
||||
# PvP特化の1.8サーバーでない限り、この追加パケットの有効化は推奨されません
|
||||
enable-post-packet: false
|
||||
|
||||
exploit:
|
||||
# エリトラでダッシュジャンプを行うと非常に高い速度を得られるエクスプロイト(意図しない挙動)があります。
|
||||
# この設定をfalseにすると、そのエクスプロイトを防ぎます
|
||||
# Mojangのネットコードにより、エリトラの動作は開始がクライアント側、終了がサーバー側で処理されるためにズレが生じています。
|
||||
# エリトラは水平摩擦0.99を持ち、水平速度0.2が常に追加されると非常に高速度になります。
|
||||
allow-sprint-jumping-when-using-elytra: true
|
||||
|
||||
# このオプションは、ゴーストブロックが発生したときにプレイヤーを再同期させることで、
|
||||
# ゴーストブロックへのブロック設置をできるだけ制限します
|
||||
allow-building-on-ghostblocks: true
|
||||
|
||||
# 上記の設定に基づき、ゴーストブロックのチェック距離を定義します
|
||||
# 設定可能な範囲は2から4です
|
||||
distance-to-check-if-ghostblocks: 2
|
||||
|
||||
# Nettyに参加時にプラグインが注入された場合の互換性問題をデバッグするためにログを有効にします
|
||||
debug-pipeline-on-join: false
|
||||
|
||||
# 実験的なチェックを有効にします
|
||||
experimental-checks: false
|
||||
|
||||
# Grimは "Timer" のような違反パケットをキャンセルすることがありますが、1秒間にキャンセルされたパケット数がXを超えた場合、
|
||||
# プレイヤーを強制的にキックしますか?これは、いくつかのパケットリミッターがGrimによってキャンセルされたパケットをカウントしないためです。
|
||||
packet-spam-threshold: 100
|
||||
|
||||
# Grimは、飛行状態を解除されたプレイヤーがXミリ秒以上のPingを持つことを許可しません
|
||||
# これは、現在Grimが飛行中のプレイヤーをチェックしていないためです
|
||||
# 無効にするには、-1を設定してください
|
||||
max-ping-out-of-flying: 1000
|
||||
|
||||
# プレイヤーから、ロケット花火による加速効果を削除する際の最大ピン値
|
||||
# これにより、レイテンシの高いプレイヤーが1つのロケット花火による加速でエリトラを永久に使用するのを防ぎます。
|
||||
max-ping-firework-boost: 1000
|
||||
|
||||
config-version: 9
|
||||
@@ -0,0 +1,15 @@
|
||||
# このファイルは、アラートをDiscordに送信するための設定ファイルです。
|
||||
# webhookの取得方法は、以下を参照してください
|
||||
# https://support.discord.com/hc/ja/articles/228383668-Webhooks-%E3%81%AE%E4%BD%BF%E3%81%84%E6%96%B9
|
||||
enabled: false
|
||||
webhook: ""
|
||||
embed-title: "**Grim アラート**"
|
||||
embed-color: "#00FFFF"
|
||||
violation-content:
|
||||
- "**プレイヤー**: %player%"
|
||||
- "**違反項目**: %check%"
|
||||
- "**違反回数**: %violations%"
|
||||
- "**クライアントバージョン**: %version%"
|
||||
- "**ブランド**: %brand%"
|
||||
- "**Ping**: %ping%"
|
||||
- "**TPS**: %tps%"
|
||||
@@ -0,0 +1,53 @@
|
||||
# 16進数コードも使用できます。フォーマットは #FFFFFF または #ffffff です。
|
||||
|
||||
# \u00BB は » (二重 >>)です。ANSI と UTF-8 はこれを異なる方法で解釈します... 場合によっては ? と表示されることがあります。
|
||||
prefix: "&bGrim &8\u00BB"
|
||||
|
||||
alerts-enabled: "%prefix% &fアラートが有効になりました"
|
||||
alerts-disabled: "%prefix% &fアラートが無効になりました"
|
||||
client-brand-format: "%prefix% &f%player% が %brand% を使用して参加しました"
|
||||
console-specify-target: "%prefix% &cコンソールでターゲットを指定する必要があります!"
|
||||
player-not-found: "%prefix% &cプレイヤーはチェックから免除されているか、オフラインです!"
|
||||
player-not-this-server: "%prefix% &cプレイヤーはこのサーバーにいません!"
|
||||
spectate-return: "\n%prefix% &f以前の場所に戻るにはここをクリック\n"
|
||||
cannot-spectate-return: "%prefix% &c観戦しているプレイヤー以外ではこの操作はできません"
|
||||
cannot-run-on-self: "%prefix% &c自分に対してこのコマンドは使用できません!"
|
||||
upload-log: "%prefix% &fデバッグをアップロードしました: %url%"
|
||||
upload-log-start: "%prefix% &fログをアップロード中... しばらくお待ちください"
|
||||
upload-log-not-found: "%prefix% &cそのログが見つかりません"
|
||||
upload-log-upload-failure: "%prefix% &cログのアップロード中に問題が発生しました。詳細はコンソールを確認してください"
|
||||
|
||||
# 使用可能なプレースホルダー:
|
||||
# %prefix%
|
||||
# %player%
|
||||
# %check_name%
|
||||
# %description%
|
||||
# %experimental%
|
||||
# %vl% - 違反回数
|
||||
# %verbose% - チェックからの追加情報(全てのチェックが情報を追加するわけではありません)
|
||||
alerts-format: "%prefix% &f%player% が &b%check_name%%experimental% &fに失敗しました (x&c%vl%&f) &7%verbose%"
|
||||
alerts-format-proxy: "%prefix% &f[&cプロキシ&f] &f%player% が &b%check_name%%experimental% &fに失敗しました (x&c%vl%&f) &7%verbose%"
|
||||
experimental-symbol: "*"
|
||||
|
||||
profile:
|
||||
- "&7======================"
|
||||
- "%prefix% &b%player% のプロファイル"
|
||||
- "&bPing: &f%ping%"
|
||||
- "&bバージョン: &f%version%"
|
||||
- "&bクライアントブランド: &f%brand%"
|
||||
- "&b水平感度: &f%h_sensitivity%%"
|
||||
- "&b垂直感度: &f%v_sensitivity%%"
|
||||
- "&bFastMath 有効: &f%fast_math%"
|
||||
- "&7======================"
|
||||
help:
|
||||
- "&7======================"
|
||||
- "/grim alerts &f- &7アラートを切り替えます"
|
||||
- "/grim profile <player> &f- &7プレイヤー情報を表示します"
|
||||
- "/grim help &f- &7このヘルプメッセージを表示します"
|
||||
- "/grim debug <player> &f- &7開発者用の予測出力を表示します"
|
||||
- "/grim perf &f- &7開発者用のパフォーマンス (ms/予測)"
|
||||
- "/grim reload &f- &7設定をリロードします"
|
||||
- "/grim spectate <player> &f- &7プレイヤーを観戦します"
|
||||
- "/grim verbose &f- &7全てのフラグをバッファなしで表示します"
|
||||
- "/grim log [0-255] &f- &7予測フラグのデバッグログをアップロードします"
|
||||
- "&7======================"
|
||||
@@ -0,0 +1,94 @@
|
||||
# %check_name% – チェックの名前
|
||||
# %description% - チェックの説明
|
||||
# %vl% - 違反回数
|
||||
# %verbose% - 追加情報
|
||||
# %player% - プレイヤー名
|
||||
# [alert] - アラート通知を行う特別なコマンド
|
||||
# [webhook] - DiscordのWebhookに通知する特別なコマンド
|
||||
# [proxy] - プロキシに接続された他のサーバーに通知する特別なコマンド(BungeeCord/Velocity用)
|
||||
処罰:
|
||||
Simulation:
|
||||
# 何秒後に違反をリセットしますか?
|
||||
remove-violations-after: 300
|
||||
# このセクションでは、指定した名前と一致するすべてのチェックに対して処罰を設定します
|
||||
# 一部のチェックを除外するには、名前の前に「!」を付けます
|
||||
# 例: !BadPacketsN
|
||||
checks:
|
||||
- "Simulation"
|
||||
- "GroundSpoof"
|
||||
- "Timer"
|
||||
- "NoFall"
|
||||
# しきい値:間隔 コマンド
|
||||
#
|
||||
# 例: 100回の違反で「incorrect movement!」と表示しプレイヤーをキックする場合
|
||||
# commands:
|
||||
# - "100:0 kick %player% incorrect movement!"
|
||||
# 0は一度だけ実行されることを意味します
|
||||
# - "100:50 say %player% is cheating"
|
||||
# 100回違反が発生した際に実行し、その後100回以降は50回ごとに実行されます
|
||||
#
|
||||
commands:
|
||||
- "100:40 [alert]"
|
||||
- "100:100 [webhook]"
|
||||
- "100:100 [proxy]"
|
||||
Knockback:
|
||||
remove-violations-after: 300
|
||||
checks:
|
||||
- "Knockback"
|
||||
- "Explosion"
|
||||
commands:
|
||||
- "5:5 [alert]"
|
||||
- "20:20 [webhook]"
|
||||
- "20:20 [proxy]"
|
||||
Post:
|
||||
remove-violations-after: 300
|
||||
checks:
|
||||
- "Post"
|
||||
commands:
|
||||
- "20:20 [alert]"
|
||||
- "40:40 [webhook]"
|
||||
- "40:40 [proxy]"
|
||||
BadPackets:
|
||||
remove-violations-after: 300
|
||||
checks:
|
||||
- "BadPackets"
|
||||
- "Crash"
|
||||
commands:
|
||||
- "20:20 [alert]"
|
||||
- "40:40 [webhook]"
|
||||
- "40:40 [proxy]"
|
||||
Reach:
|
||||
remove-violations-after: 300
|
||||
checks:
|
||||
- "Reach"
|
||||
commands:
|
||||
- "5:5 [alert]"
|
||||
- "5:5 [webhook]"
|
||||
- "5:5 [proxy]"
|
||||
Misc:
|
||||
remove-violations-after: 300
|
||||
checks:
|
||||
- "EntityControl"
|
||||
- "NoSlow"
|
||||
- "Place"
|
||||
- "Baritone"
|
||||
- "FastBreak"
|
||||
- "TransactionOrder"
|
||||
commands:
|
||||
- "10:5 [alert]"
|
||||
- "20:10 [webhook]"
|
||||
- "20:10 [proxy]"
|
||||
Combat:
|
||||
remove-violations-after: 300
|
||||
checks:
|
||||
- "Killaura"
|
||||
- "Aim"
|
||||
commands:
|
||||
- "20:40 [alert]"
|
||||
# バージョン2.2.10時点では、AutoClickerのチェックはまだなく、これはプレースホルダーです。Grimは将来的にAutoClickerのチェックを追加予定です。
|
||||
Autoclicker:
|
||||
remove-violations-after: 300
|
||||
checks:
|
||||
- "Autoclicker"
|
||||
commands:
|
||||
- "20:40 [alert]"
|
||||
Reference in new issue
Block a user