├── .github ├── ISSUE_TEMPLATE │ ├── config.yml │ └── feature.yml └── workflows │ └── release.yml ├── testlibs.versions.toml ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── common └── src │ └── main │ ├── java │ └── ac │ │ └── grim │ │ └── grimac │ │ ├── manager │ │ ├── init │ │ │ ├── Initable.java │ │ │ ├── ReloadableInitable.java │ │ │ ├── load │ │ │ │ └── LoadableInitable.java │ │ │ ├── stop │ │ │ │ ├── StoppableInitable.java │ │ │ │ └── TerminatePacketEvents.java │ │ │ └── start │ │ │ │ ├── StartableInitable.java │ │ │ │ ├── ViaBackwardsManager.java │ │ │ │ ├── PacketLimiter.java │ │ │ │ ├── AbstractTickEndEvent.java │ │ │ │ ├── ExemptOnlinePlayersOnReload.java │ │ │ │ ├── TickRunner.java │ │ │ │ └── TAB.java │ │ ├── tick │ │ │ ├── Tickable.java │ │ │ └── impl │ │ │ │ ├── ResetTick.java │ │ │ │ ├── TickInventory.java │ │ │ │ ├── ClearRecentlyUpdatedBlocks.java │ │ │ │ └── ClientVersionSetter.java │ │ ├── player │ │ │ └── features │ │ │ │ ├── types │ │ │ │ ├── GrimFeature.java │ │ │ │ ├── ExemptElytraFeature.java │ │ │ │ ├── ForceStuckSpeedFeature.java │ │ │ │ ├── ForceSlowMovementFeature.java │ │ │ │ └── ExperimentalChecksFeature.java │ │ │ │ └── FeatureBuilder.java │ │ ├── violationdatabase │ │ │ ├── ViolationDatabase.java │ │ │ ├── NoOpViolationDatabase.java │ │ │ ├── postgresql │ │ │ │ └── PostgresqlDialect.java │ │ │ ├── mysql │ │ │ │ └── MySQLDialect.java │ │ │ └── sqlite │ │ │ │ └── SQLiteDialect.java │ │ └── LastInstanceManager.java │ │ ├── utils │ │ ├── data │ │ │ ├── HeadRotation.java │ │ │ ├── packetentity │ │ │ │ ├── dragon │ │ │ │ │ ├── DragonPart.java │ │ │ │ │ └── PacketEntityEnderDragonPart.java │ │ │ │ ├── PacketEntityStrider.java │ │ │ │ ├── PacketEntityUnHittable.java │ │ │ │ ├── PacketEntityHook.java │ │ │ │ ├── PacketEntityShulker.java │ │ │ │ ├── PacketEntityArmorStand.java │ │ │ │ ├── PacketEntityPainting.java │ │ │ │ ├── PacketEntityGuardian.java │ │ │ │ ├── PacketEntityCamel.java │ │ │ │ ├── PacketEntityRideable.java │ │ │ │ ├── PacketEntitySizeable.java │ │ │ │ └── PacketEntityTrackXRot.java │ │ │ ├── BlockPlaceSnapshot.java │ │ │ ├── TeleportAcceptData.java │ │ │ ├── MainSupportingBlockData.java │ │ │ ├── CooldownData.java │ │ │ ├── KnownInput.java │ │ │ ├── BlockPrediction.java │ │ │ ├── RotationData.java │ │ │ ├── TrackerData.java │ │ │ ├── HitData.java │ │ │ ├── LastInstance.java │ │ │ ├── Pair.java │ │ │ ├── VelocityData.java │ │ │ ├── SetBackData.java │ │ │ └── VehicleData.java │ │ ├── enums │ │ │ ├── FluidTag.java │ │ │ ├── ThreadType.java │ │ │ ├── BoatEntityStatus.java │ │ │ └── Pose.java │ │ ├── inventory │ │ │ ├── ClickAction.java │ │ │ ├── slot │ │ │ │ ├── ResultSlot.java │ │ │ │ └── EquipmentSlot.java │ │ │ ├── inventory │ │ │ │ └── NotImplementedMenu.java │ │ │ └── InventoryStorage.java │ │ ├── anticheat │ │ │ ├── Constants.java │ │ │ └── update │ │ │ │ ├── VehiclePositionUpdate.java │ │ │ │ ├── PredictionComplete.java │ │ │ │ ├── PositionUpdate.java │ │ │ │ └── RotationUpdate.java │ │ ├── common │ │ │ ├── ConfigReloadObserver.java │ │ │ └── PropertiesUtil.java │ │ ├── blockplace │ │ │ └── BlockPlaceFactory.java │ │ ├── lists │ │ │ ├── ListWrapper.java │ │ │ └── EvictingQueue.java │ │ ├── collisions │ │ │ ├── datatypes │ │ │ │ ├── CollisionFactory.java │ │ │ │ ├── HitBoxFactory.java │ │ │ │ ├── HexOffsetCollisionBox.java │ │ │ │ ├── CollisionBox.java │ │ │ │ ├── HexCollisionBox.java │ │ │ │ └── NoCollisionBox.java │ │ │ └── blocks │ │ │ │ └── PistonBaseCollision.java │ │ ├── chunks │ │ │ └── Column.java │ │ ├── item │ │ │ ├── AlwaysUseItem.java │ │ │ ├── UnsupportedItem.java │ │ │ ├── LegacyItem.java │ │ │ ├── ItemBehaviourRegistry.java │ │ │ └── TridentItem.java │ │ ├── nmsutil │ │ │ ├── WatchableIndexUtil.java │ │ │ ├── CheckIfChunksLoaded.java │ │ │ └── FluidFallingAdjustedMovement.java │ │ ├── viaversion │ │ │ └── ViaVersionUtil.java │ │ ├── payload │ │ │ ├── PayloadItemName.java │ │ │ ├── PayloadBookEdit.java │ │ │ └── Payload.java │ │ ├── math │ │ │ ├── VanillaMath.java │ │ │ └── LegacyFastMath.java │ │ ├── reflection │ │ │ └── GeyserUtil.java │ │ ├── change │ │ │ └── BlockModification.java │ │ └── webhook │ │ │ └── JsonSerializable.java │ │ ├── platform │ │ └── api │ │ │ ├── world │ │ │ ├── PlatformChunk.java │ │ │ └── PlatformWorld.java │ │ │ ├── PlatformPlugin.java │ │ │ ├── player │ │ │ ├── OfflinePlatformPlayer.java │ │ │ ├── PlatformInventory.java │ │ │ └── PlatformPlayerFactory.java │ │ │ ├── manager │ │ │ ├── MessagePlaceHolderManager.java │ │ │ ├── PlatformPluginManager.java │ │ │ ├── ItemResetHandler.java │ │ │ └── CommandAdapter.java │ │ │ ├── PlatformServer.java │ │ │ ├── command │ │ │ ├── PlayerSelector.java │ │ │ └── AbstractPlayerSelectorParser.java │ │ │ ├── Platform.java │ │ │ ├── entity │ │ │ └── GrimEntity.java │ │ │ ├── scheduler │ │ │ └── TaskHandle.java │ │ │ └── permissions │ │ │ └── PermissionDefaultValue.java │ │ ├── command │ │ ├── BuildableCommand.java │ │ ├── SenderRequirement.java │ │ ├── handler │ │ │ └── GrimCommandFailureHandler.java │ │ ├── requirements │ │ │ └── PlayerSenderRequirement.java │ │ └── commands │ │ │ ├── GrimVerbose.java │ │ │ ├── GrimBrands.java │ │ │ └── GrimHelp.java │ │ ├── predictionengine │ │ ├── blockeffects │ │ │ ├── BlockEffectsResolver.java │ │ │ └── BlockStepVisitor.java │ │ ├── movementtick │ │ │ ├── MovementTickerPig.java │ │ │ └── MovementTickerCamel.java │ │ └── predictions │ │ │ └── rideable │ │ │ ├── PredictionEngineRideableLava.java │ │ │ ├── PredictionEngineRideableWater.java │ │ │ ├── PredictionEngineRideableNormal.java │ │ │ └── PredictionEngineRideableWaterLegacy.java │ │ ├── checks │ │ ├── type │ │ │ ├── PostPredictionCheck.java │ │ │ ├── VehicleCheck.java │ │ │ ├── RotationCheck.java │ │ │ ├── PositionCheck.java │ │ │ ├── BlockBreakCheck.java │ │ │ └── PacketCheck.java │ │ ├── impl │ │ │ ├── vehicle │ │ │ │ ├── VehicleC.java │ │ │ │ └── VehicleB.java │ │ │ ├── combat │ │ │ │ └── Hitboxes.java │ │ │ ├── misc │ │ │ │ └── TransactionOrder.java │ │ │ ├── badpackets │ │ │ │ ├── BadPacketsN.java │ │ │ │ ├── BadPacketsW.java │ │ │ │ ├── BadPacketsZ.java │ │ │ │ ├── BadPacketsS.java │ │ │ │ ├── BadPacketsK.java │ │ │ │ ├── BadPacketsB.java │ │ │ │ ├── BadPacketsI.java │ │ │ │ ├── BadPacketsY.java │ │ │ │ └── BadPacketsA.java │ │ │ ├── movement │ │ │ │ ├── PredictionRunner.java │ │ │ │ └── VehiclePredictionRunner.java │ │ │ ├── flight │ │ │ │ └── FlightA.java │ │ │ ├── scaffolding │ │ │ │ ├── InvalidPlaceA.java │ │ │ │ └── InvalidPlaceB.java │ │ │ ├── sprint │ │ │ │ ├── SprintF.java │ │ │ │ └── SprintG.java │ │ │ ├── multiactions │ │ │ │ └── MultiActionsD.java │ │ │ ├── aim │ │ │ │ └── AimDuplicateLook.java │ │ │ ├── crash │ │ │ │ ├── CrashB.java │ │ │ │ └── CrashE.java │ │ │ ├── timer │ │ │ │ └── VehicleTimer.java │ │ │ └── breaking │ │ │ │ └── InvalidBreak.java │ │ ├── debug │ │ │ └── AbstractDebugHandler.java │ │ ├── GrimProcessor.java │ │ └── CheckData.java │ │ └── events │ │ ├── ResolutionFailureHandler.java │ │ └── GrimExtensionResolver.java │ └── resources │ ├── grimac.properties │ └── discord │ ├── en.yml │ ├── de.yml │ ├── zh.yml │ ├── nl.yml │ ├── it.yml │ ├── tr.yml │ ├── pt.yml │ ├── fr.yml │ ├── ru.yml │ ├── ja.yml │ └── es.yml ├── .deepsource.toml ├── gradle.properties ├── fabric ├── src │ └── main │ │ ├── java │ │ └── ac │ │ │ └── grim │ │ │ └── grimac │ │ │ └── platform │ │ │ └── fabric │ │ │ ├── utils │ │ │ ├── metrics │ │ │ │ ├── Metrics.java │ │ │ │ └── CustomChart.java │ │ │ ├── message │ │ │ │ ├── IFabricMessageUtil.java │ │ │ │ └── JULoggerFactory.java │ │ │ ├── convert │ │ │ │ └── IFabricConversionUtil.java │ │ │ └── thread │ │ │ │ └── FabricFutureUtil.java │ │ │ ├── manager │ │ │ ├── FabricMessagePlaceHolderManager.java │ │ │ ├── FabricPlatformPluginManager.java │ │ │ └── FabricItemResetHandler.java │ │ │ ├── mixins │ │ │ ├── ServerPlayerMixin.java │ │ │ └── LevelChunkMixin.java │ │ │ ├── scheduler │ │ │ └── FabricTaskHandle.java │ │ │ ├── initables │ │ │ ├── FabricBStats.java │ │ │ └── FabricTickEndEvent.java │ │ │ ├── player │ │ │ └── FabricOfflinePlatformPlayer.java │ │ │ └── FabricPlatformPlugin.java │ │ └── resources │ │ ├── grimac.mixins.json │ │ ├── grimac.accesswidener │ │ └── fabric.mod.json ├── mc1161 │ ├── src │ │ └── main │ │ │ ├── resources │ │ │ ├── grimac.accesswidener │ │ │ └── fabric.mod.json │ │ │ └── java │ │ │ └── ac │ │ │ └── grim │ │ │ └── grimac │ │ │ └── platform │ │ │ └── fabric │ │ │ └── mc1161 │ │ │ ├── util │ │ │ └── convert │ │ │ │ └── Fabric1161MessageUtil.java │ │ │ └── Fabric1140PlatformServer.java │ └── build.gradle.kts ├── mc1171 │ ├── src │ │ └── main │ │ │ ├── resources │ │ │ ├── grimac.accesswidener │ │ │ └── fabric.mod.json │ │ │ └── java │ │ │ └── ac │ │ │ └── grim │ │ │ └── grimac │ │ │ └── platform │ │ │ └── fabric │ │ │ └── mc1171 │ │ │ ├── entity │ │ │ └── Fabric1170GrimEntity.java │ │ │ ├── Fabric1171PlatformServer.java │ │ │ └── player │ │ │ └── Fabric1170PlatformPlayer.java │ └── build.gradle.kts ├── mc1194 │ ├── src │ │ └── main │ │ │ ├── resources │ │ │ ├── grimac.accesswidener │ │ │ └── fabric.mod.json │ │ │ └── java │ │ │ └── ac │ │ │ └── grim │ │ │ └── grimac │ │ │ └── platform │ │ │ └── fabric │ │ │ └── mc1194 │ │ │ ├── convert │ │ │ └── Fabric1190MessageUtil.java │ │ │ ├── Fabric1190PlatformServer.java │ │ │ └── player │ │ │ └── Fabric1193PlatformInventory.java │ └── build.gradle.kts ├── mc1205 │ ├── src │ │ └── main │ │ │ ├── resources │ │ │ ├── grimac.accesswidener │ │ │ └── fabric.mod.json │ │ │ └── java │ │ │ └── ac │ │ │ └── grim │ │ │ └── grimac │ │ │ └── platform │ │ │ └── fabric │ │ │ └── mc1205 │ │ │ ├── convert │ │ │ └── Fabric1200MessageUtil.java │ │ │ ├── player │ │ │ └── Fabric1202PlatformPlayer.java │ │ │ └── Fabric1203PlatformServer.java │ └── build.gradle.kts ├── mc1216 │ ├── src │ │ └── main │ │ │ ├── resources │ │ │ ├── grimac.accesswidener │ │ │ └── fabric.mod.json │ │ │ └── java │ │ │ └── ac │ │ │ └── grim │ │ │ └── grimac │ │ │ └── platform │ │ │ └── fabric │ │ │ └── mc1216 │ │ │ ├── player │ │ │ └── Fabric1215PlatformInventory.java │ │ │ ├── command │ │ │ └── Fabric1212PlayerSelectorAdapter.java │ │ │ └── convert │ │ │ └── Fabric1216ConversionUtil.java │ └── build.gradle.kts └── gradle.properties ├── SECURITY.md ├── .editorconfig ├── bukkit └── src │ └── main │ └── java │ └── ac │ └── grim │ └── grimac │ └── platform │ └── bukkit │ ├── initables │ ├── BukkitBStats.java │ └── BukkitEventManager.java │ ├── scheduler │ ├── folia │ │ ├── FoliaPlatformScheduler.java │ │ └── FoliaTaskHandle.java │ └── bukkit │ │ ├── BukkitPlatformScheduler.java │ │ └── BukkitTaskHandle.java │ ├── BukkitPlatformPlugin.java │ ├── player │ └── BukkitOfflinePlatformPlayer.java │ ├── manager │ ├── BukkitMessagePlaceHolderManager.java │ └── BukkitPlatformPluginManager.java │ ├── utils │ └── anticheat │ │ └── MultiLibUtil.java │ ├── command │ ├── BukkitPlayerSelectorParser.java │ └── BukkitPlayerSelectorAdapter.java │ └── BukkitPlatformServer.java └── .gitignore /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | -------------------------------------------------------------------------------- /testlibs.versions.toml: -------------------------------------------------------------------------------- 1 | [versions] 2 | 3 | 4 | [libraries] 5 | 6 | 7 | [bundles] 8 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GrimAnticheat/Grim/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/manager/init/Initable.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.manager.init; 2 | 3 | public interface Initable { 4 | } 5 | -------------------------------------------------------------------------------- /.deepsource.toml: -------------------------------------------------------------------------------- 1 | version = 1 2 | 3 | [[analyzers]] 4 | name = "java" 5 | enabled = true 6 | 7 | [analyzers.meta] 8 | runtime_version = "17" 9 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx3072M -XX:MaxMetaspaceSize=768m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 2 | org.gradle.parallel=true 3 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/manager/tick/Tickable.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.manager.tick; 2 | 3 | public interface Tickable { 4 | void tick(); 5 | } 6 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/data/HeadRotation.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.data; 2 | 3 | public record HeadRotation(float yaw, float pitch) {} 4 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/enums/FluidTag.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.enums; 2 | 3 | public enum FluidTag { 4 | LAVA, 5 | WATER 6 | } 7 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/enums/ThreadType.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.enums; 2 | 3 | public enum ThreadType { 4 | SYNC, ASYNC, NETTY, UNKNOWN 5 | } 6 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/inventory/ClickAction.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.inventory; 2 | 3 | public enum ClickAction { 4 | PRIMARY, 5 | SECONDARY 6 | } 7 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/manager/init/ReloadableInitable.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.manager.init; 2 | 3 | public interface ReloadableInitable { 4 | void reload(); 5 | } 6 | -------------------------------------------------------------------------------- /fabric/src/main/java/ac/grim/grimac/platform/fabric/utils/metrics/Metrics.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.fabric.utils.metrics; 2 | 3 | public interface Metrics { 4 | 5 | void shutdown(); 6 | } 7 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/platform/api/world/PlatformChunk.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.api.world; 2 | 3 | public interface PlatformChunk { 4 | int getBlockID(int x, int y, int z); 5 | } 6 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/platform/api/PlatformPlugin.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.api; 2 | 3 | public interface PlatformPlugin { 4 | boolean isEnabled(); 5 | 6 | String getName(); 7 | 8 | String getVersion(); 9 | } 10 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/data/packetentity/dragon/DragonPart.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.data.packetentity.dragon; 2 | 3 | public enum DragonPart { 4 | HEAD, 5 | NECK, 6 | BODY, 7 | TAIL, 8 | WING 9 | } 10 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/manager/init/load/LoadableInitable.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.manager.init.load; 2 | 3 | import ac.grim.grimac.manager.init.Initable; 4 | 5 | public interface LoadableInitable extends Initable { 6 | void load(); 7 | } 8 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/manager/init/stop/StoppableInitable.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.manager.init.stop; 2 | 3 | import ac.grim.grimac.manager.init.Initable; 4 | 5 | public interface StoppableInitable extends Initable { 6 | void stop(); 7 | } 8 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/enums/BoatEntityStatus.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.enums; 2 | 3 | public enum BoatEntityStatus { 4 | IN_WATER, 5 | UNDER_WATER, 6 | UNDER_FLOWING_WATER, 7 | ON_LAND, 8 | IN_AIR 9 | } 10 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/manager/init/start/StartableInitable.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.manager.init.start; 2 | 3 | import ac.grim.grimac.manager.init.Initable; 4 | 5 | public interface StartableInitable extends Initable { 6 | void start(); 7 | } 8 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/data/BlockPlaceSnapshot.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.data; 2 | 3 | import com.github.retrooper.packetevents.wrapper.PacketWrapper; 4 | 5 | public record BlockPlaceSnapshot(PacketWrapper wrapper, boolean sneaking) {} 6 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/anticheat/Constants.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.anticheat; 2 | 3 | import lombok.experimental.UtilityClass; 4 | 5 | @UtilityClass 6 | public class Constants { 7 | public static final int BSTATS_PLUGIN_ID = 12820; 8 | } 9 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/common/ConfigReloadObserver.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.common; 2 | 3 | 4 | import ac.grim.grimac.api.config.ConfigManager; 5 | 6 | public interface ConfigReloadObserver { 7 | 8 | void onReload(ConfigManager config); 9 | 10 | } 11 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/command/BuildableCommand.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.command; 2 | 3 | import ac.grim.grimac.platform.api.sender.Sender; 4 | import org.incendo.cloud.CommandManager; 5 | 6 | public interface BuildableCommand { 7 | void register(CommandManager manager); 8 | } 9 | -------------------------------------------------------------------------------- /fabric/mc1161/src/main/resources/grimac.accesswidener: -------------------------------------------------------------------------------- 1 | accessWidener v2 named 2 | accessible field net/minecraft/server/level/ServerLevel serverLevelData Lnet/minecraft/world/level/storage/ServerLevelData; 3 | accessible field net/minecraft/commands/CommandSourceStack source Lnet/minecraft/commands/CommandSource; 4 | -------------------------------------------------------------------------------- /fabric/mc1171/src/main/resources/grimac.accesswidener: -------------------------------------------------------------------------------- 1 | accessWidener v2 named 2 | accessible field net/minecraft/server/level/ServerLevel serverLevelData Lnet/minecraft/world/level/storage/ServerLevelData; 3 | accessible field net/minecraft/commands/CommandSourceStack source Lnet/minecraft/commands/CommandSource; 4 | -------------------------------------------------------------------------------- /fabric/mc1194/src/main/resources/grimac.accesswidener: -------------------------------------------------------------------------------- 1 | accessWidener v2 named 2 | accessible field net/minecraft/server/level/ServerLevel serverLevelData Lnet/minecraft/world/level/storage/ServerLevelData; 3 | accessible field net/minecraft/commands/CommandSourceStack source Lnet/minecraft/commands/CommandSource; 4 | -------------------------------------------------------------------------------- /fabric/mc1205/src/main/resources/grimac.accesswidener: -------------------------------------------------------------------------------- 1 | accessWidener v2 named 2 | accessible field net/minecraft/server/level/ServerLevel serverLevelData Lnet/minecraft/world/level/storage/ServerLevelData; 3 | accessible field net/minecraft/commands/CommandSourceStack source Lnet/minecraft/commands/CommandSource; 4 | -------------------------------------------------------------------------------- /fabric/mc1216/src/main/resources/grimac.accesswidener: -------------------------------------------------------------------------------- 1 | accessWidener v2 named 2 | accessible field net/minecraft/server/level/ServerLevel serverLevelData Lnet/minecraft/world/level/storage/ServerLevelData; 3 | accessible field net/minecraft/commands/CommandSourceStack source Lnet/minecraft/commands/CommandSource; 4 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/anticheat/update/VehiclePositionUpdate.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.anticheat.update; 2 | 3 | import com.github.retrooper.packetevents.util.Vector3d; 4 | 5 | public record VehiclePositionUpdate(Vector3d from, Vector3d to, float xRot, float yRot, boolean isTeleport) {} 6 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.0-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /common/src/main/resources/grimac.properties: -------------------------------------------------------------------------------- 1 | timestamp=${timestamp} 2 | git.commit=${git_commit} 3 | git.branch=${git_branch} 4 | git.org=${git_org} 5 | git.repo=${git_repo} 6 | build.version=${version} 7 | build.shade_pe=${build_shade_pe} 8 | build.relocate=${build_relocate} 9 | build.release=${build_release} 10 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/platform/api/player/OfflinePlatformPlayer.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.api.player; 2 | 3 | import ac.grim.grimac.api.GrimIdentity; 4 | 5 | public interface OfflinePlatformPlayer extends GrimIdentity { 6 | 7 | boolean isOnline(); 8 | 9 | String getName(); 10 | } 11 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/predictionengine/blockeffects/BlockEffectsResolver.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.predictionengine.blockeffects; 2 | 3 | import ac.grim.grimac.player.GrimPlayer; 4 | 5 | public interface BlockEffectsResolver { 6 | 7 | void applyEffectsFromBlocks(GrimPlayer player); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature.yml: -------------------------------------------------------------------------------- 1 | name: Feature suggestion 2 | description: Suggest a feature 3 | labels: ["enhancement"] 4 | body: 5 | - type: textarea 6 | attributes: 7 | label: Feature description 8 | description: Describe the feature and why it should be added. 9 | validations: 10 | required: true 11 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/manager/init/start/ViaBackwardsManager.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.manager.init.start; 2 | 3 | public class ViaBackwardsManager implements StartableInitable { 4 | @Override 5 | public void start() { 6 | System.setProperty("com.viaversion.handlePingsAsInvAcknowledgements", "true"); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/blockplace/BlockPlaceFactory.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.blockplace; 2 | 3 | import ac.grim.grimac.player.GrimPlayer; 4 | import ac.grim.grimac.utils.anticheat.update.BlockPlace; 5 | 6 | public interface BlockPlaceFactory { 7 | void applyBlockPlaceToWorld(GrimPlayer player, BlockPlace place); 8 | } 9 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | Vulnerability must be reproducible on the latest grim commit. 6 | 7 | ## Reporting a Vulnerability 8 | 9 | If there's a major bypass that would affect gameplay if reported publicly then join Grim's discord [here](https://discord.com/invite/kqQAhTmkUF) and reach out to staff. 10 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/predictionengine/blockeffects/BlockStepVisitor.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.predictionengine.blockeffects; 2 | 3 | import com.github.retrooper.packetevents.util.Vector3i; 4 | 5 | @FunctionalInterface 6 | public interface BlockStepVisitor { 7 | 8 | boolean visit(Vector3i blockPos, int index); 9 | 10 | } 11 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/data/TeleportAcceptData.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.data; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | 6 | @Getter 7 | @Setter 8 | public class TeleportAcceptData { 9 | private boolean isTeleport; 10 | private SetBackData setback; 11 | private TeleportData teleportData; 12 | } 13 | -------------------------------------------------------------------------------- /fabric/gradle.properties: -------------------------------------------------------------------------------- 1 | # Done to increase the memory available to gradle. 2 | org.gradle.jvmargs=-Xmx2G 3 | org.gradle.parallel=true 4 | # Fabric Properties 5 | # check these on https://fabricmc.net/develop 6 | minecraft_version=1.16.1 7 | yarn_mappings=1.16.1+build.21 8 | loader_version=0.16.13 9 | 10 | # Fabric API 11 | fabric_version=0.42.0+1.16 12 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/checks/type/PostPredictionCheck.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.checks.type; 2 | 3 | import ac.grim.grimac.utils.anticheat.update.PredictionComplete; 4 | 5 | public interface PostPredictionCheck extends PacketCheck { 6 | 7 | default void onPredictionComplete(final PredictionComplete predictionComplete) { 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/checks/type/VehicleCheck.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.checks.type; 2 | 3 | import ac.grim.grimac.api.AbstractCheck; 4 | import ac.grim.grimac.utils.anticheat.update.VehiclePositionUpdate; 5 | 6 | public interface VehicleCheck extends AbstractCheck { 7 | 8 | void process(final VehiclePositionUpdate vehicleUpdate); 9 | } 10 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/checks/type/RotationCheck.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.checks.type; 2 | 3 | import ac.grim.grimac.api.AbstractCheck; 4 | import ac.grim.grimac.utils.anticheat.update.RotationUpdate; 5 | 6 | public interface RotationCheck extends AbstractCheck { 7 | 8 | default void process(final RotationUpdate rotationUpdate) { 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /fabric/mc1171/build.gradle.kts: -------------------------------------------------------------------------------- 1 | dependencies { 2 | minecraft("com.mojang:minecraft:1.17.1") 3 | mappings(loom.officialMojangMappings()) 4 | compileOnly(project(":fabric:mc1161", configuration = "namedElements")) 5 | 6 | modImplementation(fabricApi.module("fabric-lifecycle-events-v1", "0.46.1+1.17")) 7 | modImplementation("me.lucko:fabric-permissions-api:0.3.1") 8 | } 9 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/checks/type/PositionCheck.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.checks.type; 2 | 3 | import ac.grim.grimac.api.AbstractCheck; 4 | import ac.grim.grimac.utils.anticheat.update.PositionUpdate; 5 | 6 | public interface PositionCheck extends AbstractCheck { 7 | 8 | default void onPositionUpdate(final PositionUpdate positionUpdate) { 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /fabric/src/main/resources/grimac.mixins.json: -------------------------------------------------------------------------------- 1 | { 2 | "required": true, 3 | "minVersion": "0.8", 4 | "package": "ac.grim.grimac.platform.fabric.mixins", 5 | "compatibilityLevel": "JAVA_17", 6 | "mixins": [ 7 | "LevelChunkMixin", 8 | "LevelMixin", 9 | "ServerPlayerMixin" 10 | ], 11 | "injectors": { 12 | "defaultRequire": 1 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/checks/impl/vehicle/VehicleC.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.checks.impl.vehicle; 2 | 3 | import ac.grim.grimac.checks.Check; 4 | import ac.grim.grimac.checks.CheckData; 5 | import ac.grim.grimac.player.GrimPlayer; 6 | 7 | @CheckData(name = "VehicleC") 8 | public class VehicleC extends Check { 9 | public VehicleC(GrimPlayer player) { 10 | super(player); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/checks/type/BlockBreakCheck.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.checks.type; 2 | 3 | import ac.grim.grimac.utils.anticheat.update.BlockBreak; 4 | 5 | public interface BlockBreakCheck extends PostPredictionCheck { 6 | default void onBlockBreak(final BlockBreak blockBreak) { 7 | } 8 | 9 | default void onPostFlyingBlockBreak(final BlockBreak blockBreak) { 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /fabric/mc1161/build.gradle.kts: -------------------------------------------------------------------------------- 1 | dependencies { 2 | minecraft("com.mojang:minecraft:1.16.1") 3 | mappings(loom.officialMojangMappings()) 4 | 5 | modImplementation(fabricApi.module("fabric-lifecycle-events-v1", "0.42.0+1.16")) 6 | modImplementation("me.lucko:fabric-permissions-api:0.1-SNAPSHOT") 7 | } 8 | 9 | loom { 10 | accessWidenerPath = file("src/main/resources/grimac.accesswidener") 11 | } 12 | -------------------------------------------------------------------------------- /common/src/main/resources/discord/en.yml: -------------------------------------------------------------------------------- 1 | enabled: false 2 | webhook: "" 3 | embed-title: "**Grim Alert**" 4 | embed-color: "#00FFFF" 5 | include-timestamp: true 6 | violation-content: 7 | - "**Player**: %player%" 8 | - "**Check**: %check%" 9 | - "**Violations**: %violations%" 10 | - "**Client Version**: %version%" 11 | - "**Brand**: %brand%" 12 | - "**Ping**: %ping%" 13 | - "**TPS**: %tps%" 14 | -------------------------------------------------------------------------------- /common/src/main/resources/discord/de.yml: -------------------------------------------------------------------------------- 1 | enabled: false 2 | webhook: "" 3 | embed-title: "**Grim Warnung**" 4 | embed-color: "#00FFFF" 5 | include-timestamp: true 6 | violation-content: 7 | - "**Spieler**: %player%" 8 | - "**Überprüfung**: %check%" 9 | - "**Verstöße**: %violations%" 10 | - "**Client-Version**: %version%" 11 | - "**Marke**: %brand%" 12 | - "**Ping**: %ping%" 13 | - "**TPS**: %tps%" 14 | -------------------------------------------------------------------------------- /common/src/main/resources/discord/zh.yml: -------------------------------------------------------------------------------- 1 | # 是否启用discord webhook 2 | enabled: false 3 | webhook: "" 4 | embed-title: "**Grim Alert**" 5 | embed-color: "#00FFFF" 6 | include-timestamp: true 7 | violation-content: 8 | - "**玩家名**: %player%" 9 | - "**检查**: %check%" 10 | - "**违规率**: %violations%" 11 | - "**游戏版本**: %version%" 12 | - "**客户端品牌**: %brand%" 13 | - "**延迟**: %ping%" 14 | - "**服务器卡顿程度**: %tps%" 15 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/checks/impl/combat/Hitboxes.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.checks.impl.combat; 2 | 3 | import ac.grim.grimac.checks.Check; 4 | import ac.grim.grimac.checks.CheckData; 5 | import ac.grim.grimac.player.GrimPlayer; 6 | 7 | @CheckData(name = "Hitboxes", setback = 10) 8 | public class Hitboxes extends Check { 9 | public Hitboxes(GrimPlayer player) { 10 | super(player); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /common/src/main/resources/discord/nl.yml: -------------------------------------------------------------------------------- 1 | enabled: false 2 | webhook: "" 3 | embed-title: "**Grim Alert**" 4 | embed-color: "#00FFFF" 5 | include-timestamp: true 6 | violation-content: 7 | - "**Speler**: %player%" 8 | - "**Controleer**: %check%" 9 | - "**Overtredingen**: %violations%" 10 | - "**Client-versie**: %version%" 11 | - "**Client-merk**: %brand%" 12 | - "**Ping**: %ping%" 13 | - "**TPS**: %tps%" 14 | -------------------------------------------------------------------------------- /common/src/main/resources/discord/it.yml: -------------------------------------------------------------------------------- 1 | enabled: false 2 | webhook: "" 3 | embed-title: "**Grim Alert**" 4 | embed-color: "#00FFFF" 5 | include-timestamp: true 6 | violation-content: 7 | - "**Giocatore**: %player%" 8 | - "**Cheats Rilevati**: %check%" 9 | - "**Violazioni**: %violations%" 10 | - "**Versione Client**: %version%" 11 | - "**Client**: %brand%" 12 | - "**Ping**: %ping%" 13 | - "**TPS**: %tps%" 14 | -------------------------------------------------------------------------------- /common/src/main/resources/discord/tr.yml: -------------------------------------------------------------------------------- 1 | enabled: false 2 | webhook: "" 3 | embed-title: "**Grim Alert**" 4 | embed-color: "#00FFFF" 5 | include-timestamp: true 6 | violation-content: 7 | - "**Oyuncu**: %player%" 8 | - "**Kontrol**: %check%" 9 | - "**İhlaller**: %violations%" 10 | - "**Client Versiyonu**: %version%" 11 | - "**Kullanılan Client**: %brand%" 12 | - "**Gecikme**: %ping%" 13 | - "**TPS**: %tps%" 14 | -------------------------------------------------------------------------------- /common/src/main/resources/discord/pt.yml: -------------------------------------------------------------------------------- 1 | enabled: false 2 | webhook: "" 3 | embed-title: "**Grim Alert**" 4 | embed-color: "#00FFFF" 5 | include-timestamp: true 6 | violation-content: 7 | - "**Jogador**: %player%" 8 | - "**Verificação**: %check%" 9 | - "**Violações**: %violations%" 10 | - "**Versão do Cliente**: %version%" 11 | - "**Nome do Cliente**: %brand%" 12 | - "**Ping**: %ping%" 13 | - "**TPS**: %tps%" 14 | -------------------------------------------------------------------------------- /fabric/src/main/java/ac/grim/grimac/platform/fabric/utils/message/IFabricMessageUtil.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.fabric.utils.message; 2 | 3 | import net.minecraft.commands.CommandSourceStack; 4 | import net.minecraft.network.chat.Component; 5 | 6 | public interface IFabricMessageUtil { 7 | Component textLiteral(String message); 8 | void sendMessage(CommandSourceStack target, Component message, boolean overlay); 9 | } 10 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/checks/impl/misc/TransactionOrder.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.checks.impl.misc; 2 | 3 | import ac.grim.grimac.checks.Check; 4 | import ac.grim.grimac.checks.CheckData; 5 | import ac.grim.grimac.player.GrimPlayer; 6 | 7 | @CheckData(name = "TransactionOrder") 8 | public class TransactionOrder extends Check { 9 | public TransactionOrder(GrimPlayer player) { 10 | super(player); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /common/src/main/resources/discord/fr.yml: -------------------------------------------------------------------------------- 1 | enabled: false 2 | webhook: "" 3 | embed-title: "**Grim Alert**" 4 | embed-color: "#00FFFF" 5 | include-timestamp: true 6 | violation-content: 7 | - "**Joueur**: %player%" 8 | - "**Vérification**: %check%" 9 | - "**Violations**: %violations%" 10 | - "**Version du client**: %version%" 11 | - "**Nature du client**: %brand%" 12 | - "**Latence**: %ping%" 13 | - "**TPS**: %tps%" 14 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/checks/impl/badpackets/BadPacketsN.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.checks.impl.badpackets; 2 | 3 | import ac.grim.grimac.checks.Check; 4 | import ac.grim.grimac.checks.CheckData; 5 | import ac.grim.grimac.player.GrimPlayer; 6 | 7 | @CheckData(name = "BadPacketsN", setback = 0) 8 | public class BadPacketsN extends Check { 9 | public BadPacketsN(final GrimPlayer player) { 10 | super(player); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/platform/api/manager/MessagePlaceHolderManager.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.api.manager; 2 | 3 | import ac.grim.grimac.platform.api.player.PlatformPlayer; 4 | import org.jetbrains.annotations.NotNull; 5 | import org.jetbrains.annotations.Nullable; 6 | 7 | public interface MessagePlaceHolderManager { 8 | @NotNull 9 | String replacePlaceholders(@Nullable PlatformPlayer player, @NotNull String string); 10 | } 11 | -------------------------------------------------------------------------------- /common/src/main/resources/discord/ru.yml: -------------------------------------------------------------------------------- 1 | # Включать ли веб-крючок discord 2 | enabled: false 3 | webhook: "" 4 | embed-title: "**Grim Alert**" 5 | embed-color: "#00FFFF" 6 | include-timestamp: true 7 | violation-content: 8 | - "**Игрок**: %player%" 9 | - "**Проверка**: %check%" 10 | - "**Нарушения**: %violations%" 11 | - "**Версия Клиента**: %version%" 12 | - "**Бренд**: %brand%" 13 | - "**Пинг**: %ping%" 14 | - "**ТПС**: %tps%" 15 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/command/SenderRequirement.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.command; 2 | 3 | import ac.grim.grimac.platform.api.sender.Sender; 4 | import net.kyori.adventure.text.Component; 5 | import org.incendo.cloud.processors.requirements.Requirement; 6 | import org.jetbrains.annotations.NotNull; 7 | 8 | public interface SenderRequirement extends Requirement { 9 | @NotNull Component errorMessage(Sender sender); 10 | } 11 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/platform/api/PlatformServer.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.api; 2 | 3 | import ac.grim.grimac.platform.api.sender.Sender; 4 | 5 | public interface PlatformServer { 6 | 7 | String getPlatformImplementationString(); 8 | 9 | void dispatchCommand(Sender sender, String command); 10 | 11 | Sender getConsoleSender(); 12 | 13 | void registerOutgoingPluginChannel(String name); 14 | 15 | double getTPS(); 16 | } 17 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/platform/api/command/PlayerSelector.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.api.command; 2 | 3 | import ac.grim.grimac.platform.api.sender.Sender; 4 | 5 | import java.util.Collection; 6 | 7 | public interface PlayerSelector { 8 | boolean isSingle(); 9 | 10 | Sender getSinglePlayer(); // Throws an exception if not a single selection 11 | 12 | Collection getPlayers(); 13 | 14 | String inputString(); 15 | } 16 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/manager/init/stop/TerminatePacketEvents.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.manager.init.stop; 2 | 3 | import ac.grim.grimac.utils.anticheat.LogUtil; 4 | import com.github.retrooper.packetevents.PacketEvents; 5 | 6 | public class TerminatePacketEvents implements StoppableInitable { 7 | @Override 8 | public void stop() { 9 | LogUtil.info("Terminating PacketEvents..."); 10 | PacketEvents.getAPI().terminate(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/lists/ListWrapper.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.lists; 2 | 3 | import lombok.Getter; 4 | import lombok.RequiredArgsConstructor; 5 | 6 | import java.util.List; 7 | 8 | // https://github.com/ThomasOM/Pledge/blob/master/src/main/java/dev/thomazz/pledge/util/collection/ListWrapper.java 9 | @Getter 10 | @RequiredArgsConstructor 11 | public abstract class ListWrapper implements List { 12 | protected final List base; 13 | } 14 | -------------------------------------------------------------------------------- /fabric/src/main/java/ac/grim/grimac/platform/fabric/utils/convert/IFabricConversionUtil.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.fabric.utils.convert; 2 | 3 | import com.github.retrooper.packetevents.protocol.item.ItemStack; 4 | import net.kyori.adventure.text.Component; 5 | 6 | public interface IFabricConversionUtil { 7 | ItemStack fromFabricItemStack(net.minecraft.world.item.ItemStack fabricStack); 8 | net.minecraft.network.chat.Component toNativeText(Component component); 9 | } 10 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/checks/debug/AbstractDebugHandler.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.checks.debug; 2 | 3 | import ac.grim.grimac.checks.Check; 4 | import ac.grim.grimac.player.GrimPlayer; 5 | 6 | public abstract class AbstractDebugHandler extends Check { 7 | public AbstractDebugHandler(GrimPlayer player) { 8 | super(player); 9 | } 10 | 11 | public abstract void toggleListener(GrimPlayer player); 12 | 13 | public abstract boolean toggleConsoleOutput(); 14 | } 15 | -------------------------------------------------------------------------------- /fabric/mc1194/src/main/java/ac/grim/grimac/platform/fabric/mc1194/convert/Fabric1190MessageUtil.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.fabric.mc1194.convert; 2 | 3 | import ac.grim.grimac.platform.fabric.mc1161.util.convert.Fabric1161MessageUtil; 4 | import net.minecraft.network.chat.Component; 5 | 6 | public class Fabric1190MessageUtil extends Fabric1161MessageUtil { 7 | @Override 8 | public Component textLiteral(String message) { 9 | return Component.literal(message); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/checks/impl/badpackets/BadPacketsW.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.checks.impl.badpackets; 2 | 3 | import ac.grim.grimac.checks.Check; 4 | import ac.grim.grimac.checks.CheckData; 5 | import ac.grim.grimac.player.GrimPlayer; 6 | 7 | @CheckData(name = "BadPacketsW", description = "Interacted with non-existent entity", experimental = true) 8 | public class BadPacketsW extends Check { 9 | public BadPacketsW(GrimPlayer player) { 10 | super(player); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/collisions/datatypes/CollisionFactory.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.collisions.datatypes; 2 | 3 | import ac.grim.grimac.player.GrimPlayer; 4 | import com.github.retrooper.packetevents.protocol.player.ClientVersion; 5 | import com.github.retrooper.packetevents.protocol.world.states.WrappedBlockState; 6 | 7 | public interface CollisionFactory { 8 | CollisionBox fetch(GrimPlayer player, ClientVersion version, WrappedBlockState block, int x, int y, int z); 9 | } 10 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/data/MainSupportingBlockData.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.data; 2 | 3 | import com.github.retrooper.packetevents.util.Vector3i; 4 | import org.jetbrains.annotations.Contract; 5 | import org.jetbrains.annotations.Nullable; 6 | 7 | public record MainSupportingBlockData(@Nullable Vector3i blockPos, boolean onGround) { 8 | @Contract(pure = true) 9 | public boolean lastOnGroundAndNoBlock() { 10 | return blockPos == null && onGround; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/checks/type/PacketCheck.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.checks.type; 2 | 3 | import ac.grim.grimac.api.AbstractCheck; 4 | import com.github.retrooper.packetevents.event.PacketReceiveEvent; 5 | import com.github.retrooper.packetevents.event.PacketSendEvent; 6 | 7 | public interface PacketCheck extends AbstractCheck { 8 | default void onPacketReceive(final PacketReceiveEvent event) { 9 | } 10 | 11 | default void onPacketSend(final PacketSendEvent event) { 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/data/CooldownData.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.data; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | import lombok.Setter; 6 | import org.jetbrains.annotations.Contract; 7 | 8 | @AllArgsConstructor 9 | @Getter 10 | @Setter 11 | public final class CooldownData { 12 | private int ticksRemaining; 13 | private final int transaction; 14 | 15 | @Contract(mutates = "this") 16 | public void tick() { 17 | ticksRemaining--; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/platform/api/manager/PlatformPluginManager.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.api.manager; 2 | 3 | import ac.grim.grimac.platform.api.PlatformPlugin; 4 | 5 | public interface PlatformPluginManager { 6 | 7 | PlatformPlugin[] getPlugins(); 8 | 9 | PlatformPlugin getPlugin(String pluginName); 10 | 11 | default boolean isPluginEnabled(String pluginName) { 12 | PlatformPlugin plugin = getPlugin(pluginName); 13 | return plugin != null && plugin.isEnabled(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /fabric/mc1194/build.gradle.kts: -------------------------------------------------------------------------------- 1 | dependencies { 2 | minecraft("com.mojang:minecraft:1.19.4") 3 | mappings(loom.officialMojangMappings()) 4 | compileOnly(project(":fabric:mc1161", configuration = "namedElements")) 5 | compileOnly(project(":fabric:mc1171", configuration = "namedElements")) 6 | 7 | modImplementation(fabricApi.module("fabric-lifecycle-events-v1", "0.87.2+1.19.4")) 8 | modImplementation("me.lucko:fabric-permissions-api:0.3.1") 9 | } 10 | 11 | tasks.compileJava { 12 | options.release.set(17) 13 | } 14 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/events/ResolutionFailureHandler.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.events; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | 5 | @FunctionalInterface 6 | public interface ResolutionFailureHandler { 7 | /** 8 | * Creates a runtime exception to be thrown when resolution fails. 9 | * 10 | * @param failedContext The object that could not be resolved. 11 | * @return The exception to be thrown. 12 | */ 13 | RuntimeException createExceptionFor(@NotNull Object failedContext); 14 | } 15 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/manager/tick/impl/ResetTick.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.manager.tick.impl; 2 | 3 | import ac.grim.grimac.GrimAPI; 4 | import ac.grim.grimac.manager.tick.Tickable; 5 | import ac.grim.grimac.player.GrimPlayer; 6 | 7 | public class ResetTick implements Tickable { 8 | @Override 9 | public void tick() { 10 | for (GrimPlayer player : GrimAPI.INSTANCE.getPlayerDataManager().getEntries()) { 11 | player.checkManager.getEntityReplication().tickStartTick(); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /fabric/mc1205/build.gradle.kts: -------------------------------------------------------------------------------- 1 | dependencies { 2 | minecraft("com.mojang:minecraft:1.20.5") 3 | mappings(loom.officialMojangMappings()) 4 | compileOnly(project(":fabric:mc1161", configuration = "namedElements")) 5 | compileOnly(project(":fabric:mc1171", configuration = "namedElements")) 6 | compileOnly(project(":fabric:mc1194", configuration = "namedElements")) 7 | 8 | modImplementation(fabricApi.module("fabric-lifecycle-events-v1", "0.97.8+1.20.5")) 9 | modImplementation("me.lucko:fabric-permissions-api:0.3.1") 10 | } 11 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/manager/tick/impl/TickInventory.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.manager.tick.impl; 2 | 3 | import ac.grim.grimac.GrimAPI; 4 | import ac.grim.grimac.manager.tick.Tickable; 5 | import ac.grim.grimac.player.GrimPlayer; 6 | 7 | public class TickInventory implements Tickable { 8 | @Override 9 | public void tick() { 10 | for (GrimPlayer player : GrimAPI.INSTANCE.getPlayerDataManager().getEntries()) { 11 | player.inventory.inventory.getInventoryStorage().tickWithBukkit(); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_size = 4 6 | indent_style = space 7 | insert_final_newline = true 8 | max_line_length = 100 9 | tab_width = 4 10 | end_of_line = crlf 11 | trim_trailing_whitespace = true 12 | 13 | # intellij specific configuration 14 | ij_continuation_indent_size = 8 15 | ij_formatter_off_tag = @formatter:off 16 | ij_formatter_on_tag = @formatter:on 17 | ij_formatter_tags_enabled = false 18 | ij_smart_tabs = false 19 | ij_wrap_on_typing = false 20 | 21 | [.github/ISSUE_TEMPLATE/*.yml] 22 | indent_size = 2 23 | -------------------------------------------------------------------------------- /fabric/src/main/resources/grimac.accesswidener: -------------------------------------------------------------------------------- 1 | accessWidener v2 named 2 | accessible field net/minecraft/server/level/ServerLevel serverLevelData Lnet/minecraft/world/level/storage/ServerLevelData; 3 | accessible field net/minecraft/commands/CommandSourceStack source Lnet/minecraft/commands/CommandSource; 4 | accessible field net/minecraft/world/entity/player/Player inventory Lnet/minecraft/world/entity/player/Inventory; 5 | accessible field net/minecraft/world/entity/Entity level Lnet/minecraft/world/level/Level; # Required in newer versions, even though public in older ones 6 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/manager/player/features/types/GrimFeature.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.manager.player.features.types; 2 | 3 | import ac.grim.grimac.api.config.ConfigManager; 4 | import ac.grim.grimac.api.feature.FeatureState; 5 | import ac.grim.grimac.player.GrimPlayer; 6 | 7 | public interface GrimFeature { 8 | String getName(); 9 | 10 | void setState(GrimPlayer player, ConfigManager config, FeatureState state); 11 | 12 | boolean isEnabled(GrimPlayer player); 13 | 14 | boolean isEnabledInConfig(GrimPlayer player, ConfigManager config); 15 | } 16 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/data/KnownInput.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.data; 2 | 3 | import org.jetbrains.annotations.Contract; 4 | 5 | public record KnownInput(boolean forward, boolean backward, boolean left, boolean right, 6 | boolean jump, boolean shift, boolean sprint) { 7 | public static final KnownInput DEFAULT = new KnownInput(false, false, false, false, false, false, false); 8 | 9 | @Contract(pure = true) 10 | public boolean moving() { 11 | return forward || backward || left || right || jump; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /common/src/main/resources/discord/ja.yml: -------------------------------------------------------------------------------- 1 | # このファイルは、アラートをDiscordに送信するための設定ファイルです。 2 | # webhookの取得方法は、以下を参照してください 3 | # https://support.discord.com/hc/ja/articles/228383668-Webhooks-%E3%81%AE%E4%BD%BF%E3%81%84%E6%96%B9 4 | enabled: false 5 | webhook: "" 6 | embed-title: "**Grim アラート**" 7 | embed-color: "#00FFFF" 8 | include-timestamp: true 9 | violation-content: 10 | - "**プレイヤー**: %player%" 11 | - "**違反項目**: %check%" 12 | - "**違反回数**: %violations%" 13 | - "**クライアントバージョン**: %version%" 14 | - "**ブランド**: %brand%" 15 | - "**Ping**: %ping%" 16 | - "**TPS**: %tps%" 17 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/data/packetentity/PacketEntityStrider.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.data.packetentity; 2 | 3 | import ac.grim.grimac.player.GrimPlayer; 4 | import com.github.retrooper.packetevents.protocol.entity.type.EntityType; 5 | 6 | import java.util.UUID; 7 | 8 | public class PacketEntityStrider extends PacketEntityRideable { 9 | public boolean isShaking = false; 10 | 11 | public PacketEntityStrider(GrimPlayer player, UUID uuid, EntityType type, double x, double y, double z) { 12 | super(player, uuid, type, x, y, z); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /fabric/mc1205/src/main/java/ac/grim/grimac/platform/fabric/mc1205/convert/Fabric1200MessageUtil.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.fabric.mc1205.convert; 2 | 3 | import ac.grim.grimac.platform.fabric.mc1194.convert.Fabric1190MessageUtil; 4 | import net.minecraft.commands.CommandSourceStack; 5 | import net.minecraft.network.chat.Component; 6 | 7 | public class Fabric1200MessageUtil extends Fabric1190MessageUtil { 8 | @Override 9 | public void sendMessage(CommandSourceStack target, Component message, boolean overlay) { 10 | target.sendSuccess(() -> message, overlay); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/anticheat/update/PredictionComplete.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.anticheat.update; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | 6 | @Getter 7 | @Setter 8 | public class PredictionComplete { 9 | private double offset; 10 | private PositionUpdate data; 11 | private boolean checked; 12 | private int identifier; 13 | 14 | public PredictionComplete(double offset, PositionUpdate update, boolean checked) { 15 | this.offset = offset; 16 | this.data = update; 17 | this.checked = checked; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/chunks/Column.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.chunks; 2 | 3 | 4 | import com.github.retrooper.packetevents.protocol.world.chunk.BaseChunk; 5 | 6 | public record Column(int x, int z, BaseChunk[] chunks, int transaction) { 7 | 8 | // This ability was removed in 1.17 because of the extended world height 9 | // Therefore, the size of the chunks are ALWAYS 16! 10 | public void mergeChunks(BaseChunk[] toMerge) { 11 | for (int i = 0; i < 16; i++) { 12 | if (toMerge[i] != null) chunks[i] = toMerge[i]; 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/data/BlockPrediction.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.data; 2 | 3 | import com.github.retrooper.packetevents.util.Vector3d; 4 | import com.github.retrooper.packetevents.util.Vector3i; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Getter; 7 | import lombok.Setter; 8 | 9 | import java.util.List; 10 | 11 | @AllArgsConstructor 12 | @Getter 13 | @Setter 14 | public final class BlockPrediction { 15 | private List forBlockUpdate; 16 | private Vector3i blockPosition; 17 | private int originalBlockId; 18 | private final Vector3d playerPosition; 19 | } 20 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/platform/api/player/PlatformInventory.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.api.player; 2 | 3 | import com.github.retrooper.packetevents.protocol.item.ItemStack; 4 | 5 | public interface PlatformInventory { 6 | ItemStack getItemInHand(); 7 | 8 | ItemStack getItemInOffHand(); 9 | 10 | ItemStack getStack(int bukkitSlot, int vanillaSlot); 11 | 12 | ItemStack getHelmet(); 13 | 14 | ItemStack getChestplate(); 15 | 16 | ItemStack getLeggings(); 17 | 18 | ItemStack getBoots(); 19 | 20 | ItemStack[] getContents(); 21 | 22 | String getOpenInventoryKey(); 23 | } 24 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/platform/api/world/PlatformWorld.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.api.world; 2 | 3 | import com.github.retrooper.packetevents.protocol.world.states.WrappedBlockState; 4 | import org.jetbrains.annotations.Nullable; 5 | 6 | import java.util.UUID; 7 | 8 | public interface PlatformWorld { 9 | boolean isChunkLoaded(int chunkX, int chunkZ); 10 | 11 | WrappedBlockState getBlockAt(int x, int y, int z); 12 | 13 | String getName(); 14 | 15 | @Nullable UUID getUID(); 16 | 17 | PlatformChunk getChunkAt(int currChunkX, int currChunkZ); 18 | 19 | boolean isLoaded(); 20 | } 21 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/collisions/datatypes/HitBoxFactory.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.collisions.datatypes; 2 | 3 | import ac.grim.grimac.player.GrimPlayer; 4 | import com.github.retrooper.packetevents.protocol.player.ClientVersion; 5 | import com.github.retrooper.packetevents.protocol.world.states.WrappedBlockState; 6 | import com.github.retrooper.packetevents.protocol.world.states.type.StateType; 7 | 8 | public interface HitBoxFactory { 9 | CollisionBox fetch(GrimPlayer player, StateType heldItem, ClientVersion version, WrappedBlockState block, boolean isTargetBlock, int x, int y, int z); 10 | } 11 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/data/packetentity/PacketEntityUnHittable.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.data.packetentity; 2 | 3 | import ac.grim.grimac.player.GrimPlayer; 4 | import com.github.retrooper.packetevents.protocol.entity.type.EntityType; 5 | import java.util.UUID; 6 | 7 | public class PacketEntityUnHittable extends PacketEntity { 8 | 9 | public PacketEntityUnHittable(GrimPlayer player, UUID uuid, EntityType type, double x, double y, double z) { 10 | super(player, uuid, type, x, y, z); 11 | } 12 | 13 | @Override 14 | public boolean canHit() { 15 | return false; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/data/packetentity/PacketEntityHook.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.data.packetentity; 2 | 3 | import ac.grim.grimac.player.GrimPlayer; 4 | import com.github.retrooper.packetevents.protocol.entity.type.EntityType; 5 | 6 | import java.util.UUID; 7 | 8 | public class PacketEntityHook extends PacketEntityUnHittable { 9 | public int owner; 10 | public int attached = -1; 11 | 12 | public PacketEntityHook(GrimPlayer player, UUID uuid, EntityType type, double x, double y, double z, int owner) { 13 | super(player, uuid, type, x, y, z); 14 | this.owner = owner; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /fabric/src/main/java/ac/grim/grimac/platform/fabric/utils/message/JULoggerFactory.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.fabric.utils.message; 2 | 3 | import java.util.logging.Logger; 4 | 5 | public class JULoggerFactory { 6 | public static Logger createLogger(String name) { 7 | try { 8 | return new Slf4jBackedJULogger(name); 9 | } catch (NoClassDefFoundError | Exception ignored) { 10 | } 11 | try { 12 | return new Log4jBackedJULogger(name); 13 | } catch (NoClassDefFoundError | Exception ignored) { 14 | } 15 | 16 | return Logger.getLogger(name); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/checks/GrimProcessor.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.checks; 2 | 3 | import ac.grim.grimac.GrimAPI; 4 | import ac.grim.grimac.api.AbstractProcessor; 5 | import ac.grim.grimac.api.config.ConfigReloadable; 6 | import ac.grim.grimac.utils.common.ConfigReloadObserver; 7 | 8 | public abstract class GrimProcessor implements AbstractProcessor, ConfigReloadable, ConfigReloadObserver { 9 | 10 | // Not everything has to be a check for it to process packets & be configurable 11 | 12 | @Override 13 | public void reload() { 14 | reload(GrimAPI.INSTANCE.getConfigManager().getConfig()); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/manager/violationdatabase/ViolationDatabase.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.manager.violationdatabase; 2 | 3 | import ac.grim.grimac.player.GrimPlayer; 4 | 5 | import java.sql.SQLException; 6 | import java.util.List; 7 | import java.util.UUID; 8 | 9 | public interface ViolationDatabase { 10 | 11 | void connect() throws SQLException; 12 | 13 | void logAlert(GrimPlayer player, String grimVersion, String verbose, String checkName, int vls); 14 | 15 | int getLogCount(UUID player); 16 | 17 | List getViolations(UUID player, int page, int limit); 18 | 19 | void disconnect(); 20 | 21 | } 22 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/collisions/datatypes/HexOffsetCollisionBox.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.collisions.datatypes; 2 | 3 | import com.github.retrooper.packetevents.protocol.world.states.type.StateType; 4 | 5 | // Exists for the same reason as HexCollisionBox but for offset blocks; read comments there if unsure 6 | public class HexOffsetCollisionBox extends OffsetCollisionBox { 7 | public HexOffsetCollisionBox(StateType block, double minX, double minY, double minZ, double maxX, double maxY, double maxZ) { 8 | super(block, minX / 16d, minY / 16d, minZ / 16d, maxX / 16d, maxY / 16d, maxZ / 16d); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/data/packetentity/PacketEntityShulker.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.data.packetentity; 2 | 3 | import ac.grim.grimac.player.GrimPlayer; 4 | import com.github.retrooper.packetevents.protocol.entity.type.EntityType; 5 | import com.github.retrooper.packetevents.protocol.world.BlockFace; 6 | 7 | import java.util.UUID; 8 | 9 | public class PacketEntityShulker extends PacketEntity { 10 | public BlockFace facing = BlockFace.DOWN; 11 | 12 | public PacketEntityShulker(GrimPlayer player, UUID uuid, EntityType type, double x, double y, double z) { 13 | super(player, uuid, type, x, y, z); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ac/grim/grimac/platform/bukkit/initables/BukkitBStats.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.bukkit.initables; 2 | 3 | import ac.grim.grimac.manager.init.start.StartableInitable; 4 | import ac.grim.grimac.platform.bukkit.GrimACBukkitLoaderPlugin; 5 | import ac.grim.grimac.utils.anticheat.Constants; 6 | import io.github.retrooper.packetevents.bstats.bukkit.Metrics; 7 | 8 | public class BukkitBStats implements StartableInitable { 9 | @Override 10 | public void start() { 11 | try { 12 | new Metrics(GrimACBukkitLoaderPlugin.LOADER, Constants.BSTATS_PLUGIN_ID); 13 | } catch (Exception ignored) {} 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/manager/tick/impl/ClearRecentlyUpdatedBlocks.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.manager.tick.impl; 2 | 3 | import ac.grim.grimac.GrimAPI; 4 | import ac.grim.grimac.manager.tick.Tickable; 5 | import ac.grim.grimac.player.GrimPlayer; 6 | 7 | public class ClearRecentlyUpdatedBlocks implements Tickable { 8 | 9 | private static final int maxTickAge = 2; 10 | 11 | @Override 12 | public void tick() { 13 | for (GrimPlayer player : GrimAPI.INSTANCE.getPlayerDataManager().getEntries()) { 14 | player.blockHistory.cleanup(GrimAPI.INSTANCE.getTickManager().currentTick - maxTickAge); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/platform/api/Platform.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.api; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Getter; 5 | import org.jetbrains.annotations.Nullable; 6 | 7 | @AllArgsConstructor 8 | public enum Platform { 9 | 10 | FABRIC("fabric"), 11 | BUKKIT("bukkit"), 12 | FOLIA("folia"); 13 | 14 | @Getter private final String name; 15 | 16 | public static @Nullable Platform getByName(String name) { 17 | for (Platform platform : values()) { 18 | if (platform.getName().equalsIgnoreCase(name)) return platform; 19 | } 20 | return null; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/platform/api/player/PlatformPlayerFactory.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.api.player; 2 | 3 | import java.util.Collection; 4 | import java.util.UUID; 5 | 6 | public interface PlatformPlayerFactory { 7 | OfflinePlatformPlayer getOfflineFromUUID(UUID uuid); 8 | 9 | OfflinePlatformPlayer getOfflineFromName(String name); 10 | 11 | PlatformPlayer getFromName(String name); 12 | 13 | PlatformPlayer getFromUUID(UUID uuid); 14 | 15 | PlatformPlayer getFromNativePlayerType(Object playerObject); 16 | 17 | void invalidatePlayer(UUID uuid); 18 | 19 | Collection getOnlinePlayers(); 20 | } 21 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/data/RotationData.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.data; 2 | 3 | import lombok.EqualsAndHashCode; 4 | import lombok.Getter; 5 | import lombok.RequiredArgsConstructor; 6 | import lombok.ToString; 7 | import org.jetbrains.annotations.Contract; 8 | 9 | @Getter 10 | @RequiredArgsConstructor 11 | @EqualsAndHashCode 12 | @ToString 13 | public final class RotationData { 14 | private final float yaw; 15 | private final float pitch; 16 | private final int transaction; 17 | private boolean isAccepted; 18 | 19 | @Contract(mutates = "this") 20 | public void accept() { 21 | this.isAccepted = true; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/item/AlwaysUseItem.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.item; 2 | 3 | import ac.grim.grimac.player.GrimPlayer; 4 | import ac.grim.grimac.utils.latency.CompensatedWorld; 5 | import com.github.retrooper.packetevents.protocol.item.ItemStack; 6 | import com.github.retrooper.packetevents.protocol.player.InteractionHand; 7 | 8 | public class AlwaysUseItem extends ItemBehaviour { 9 | 10 | public static final AlwaysUseItem INSTANCE = new AlwaysUseItem(); 11 | 12 | @Override 13 | public boolean canUse(ItemStack item, CompensatedWorld world, GrimPlayer player, InteractionHand hand) { 14 | return true; 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/item/UnsupportedItem.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.item; 2 | 3 | import ac.grim.grimac.player.GrimPlayer; 4 | import ac.grim.grimac.utils.latency.CompensatedWorld; 5 | import com.github.retrooper.packetevents.protocol.item.ItemStack; 6 | import com.github.retrooper.packetevents.protocol.player.InteractionHand; 7 | 8 | public class UnsupportedItem extends ItemBehaviour { 9 | 10 | public static final UnsupportedItem INSTANCE = new UnsupportedItem(); 11 | 12 | @Override 13 | public boolean canUse(ItemStack item, CompensatedWorld world, GrimPlayer player, InteractionHand hand) { 14 | return false; 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/anticheat/update/PositionUpdate.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.anticheat.update; 2 | 3 | import ac.grim.grimac.utils.data.SetBackData; 4 | import ac.grim.grimac.utils.data.TeleportData; 5 | import com.github.retrooper.packetevents.util.Vector3d; 6 | import lombok.AllArgsConstructor; 7 | import lombok.Getter; 8 | import lombok.Setter; 9 | 10 | @AllArgsConstructor 11 | @Getter 12 | @Setter 13 | public final class PositionUpdate { 14 | private final Vector3d from, to; 15 | private final boolean onGround; 16 | private final SetBackData setback; 17 | private final TeleportData teleportData; 18 | private boolean isTeleport; 19 | } 20 | -------------------------------------------------------------------------------- /fabric/mc1171/src/main/java/ac/grim/grimac/platform/fabric/mc1171/entity/Fabric1170GrimEntity.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.fabric.mc1171.entity; 2 | 3 | import ac.grim.grimac.platform.fabric.mc1161.entity.Fabric1161GrimEntity; 4 | import net.minecraft.world.entity.Entity; 5 | import net.minecraft.world.entity.LivingEntity; 6 | 7 | public class Fabric1170GrimEntity extends Fabric1161GrimEntity { 8 | 9 | public Fabric1170GrimEntity(Entity entity) { 10 | super(entity); 11 | } 12 | 13 | @Override 14 | public boolean isDead() { 15 | return this.entity instanceof LivingEntity living ? living.isDeadOrDying() : this.entity.isRemoved(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /fabric/src/main/java/ac/grim/grimac/platform/fabric/utils/thread/FabricFutureUtil.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.fabric.utils.thread; 2 | 3 | import ac.grim.grimac.GrimAPI; 4 | 5 | import java.util.concurrent.CompletableFuture; 6 | import java.util.function.Supplier; 7 | 8 | public class FabricFutureUtil { 9 | public static CompletableFuture supplySync(Supplier entityTeleportSupplier) { 10 | CompletableFuture ret = new CompletableFuture<>(); 11 | GrimAPI.INSTANCE.getScheduler().getGlobalRegionScheduler().run(GrimAPI.INSTANCE.getGrimPlugin(), 12 | () -> ret.complete(entityTeleportSupplier.get())); 13 | return ret; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/nmsutil/WatchableIndexUtil.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.nmsutil; 2 | 3 | import com.github.retrooper.packetevents.protocol.entity.data.EntityData; 4 | import lombok.experimental.UtilityClass; 5 | import org.jetbrains.annotations.NotNull; 6 | import org.jetbrains.annotations.Nullable; 7 | 8 | import java.util.List; 9 | 10 | @UtilityClass 11 | public class WatchableIndexUtil { 12 | public static @Nullable EntityData getIndex(@NotNull List> objects, int index) { 13 | for (EntityData object : objects) { 14 | if (object.getIndex() == index) return object; 15 | } 16 | 17 | return null; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /fabric/mc1171/src/main/resources/fabric.mod.json: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": 1, 3 | "id": "grimac-mc1171", 4 | "version": "${version}", 5 | "name": "GrimAC for 1.17+ built against 1.17.1", 6 | "description": "Libre simulation anticheat designed for 1.21 with 1.8-1.21 support, powered by PacketEvents 2.0.", 7 | "authors": [ 8 | "GrimAC" 9 | ], 10 | "license": "GPLv3", 11 | "environment": "server", 12 | "entrypoints": { 13 | "grimMainLoad": [ 14 | "ac.grim.grimac.platform.fabric.mc1171.GrimACFabric1170LoaderPlugin" 15 | ] 16 | }, 17 | "accessWidener": "grimac.accesswidener", 18 | "depends": { 19 | "minecraft": ">=1.17", 20 | "fabric-lifecycle-events-v1": "*" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /fabric/mc1194/src/main/resources/fabric.mod.json: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": 1, 3 | "id": "grimac-mc1194", 4 | "version": "${version}", 5 | "name": "GrimAC for 1.19+ built against 1.19.4", 6 | "description": "Libre simulation anticheat designed for 1.21 with 1.8-1.21 support, powered by PacketEvents 2.0.", 7 | "authors": [ 8 | "GrimAC" 9 | ], 10 | "license": "GPLv3", 11 | "environment": "server", 12 | "entrypoints": { 13 | "grimMainLoad": [ 14 | "ac.grim.grimac.platform.fabric.mc1194.GrimACFabric1190LoaderPlugin" 15 | ] 16 | }, 17 | "accessWidener": "grimac.accesswidener", 18 | "depends": { 19 | "minecraft": ">=1.19", 20 | "fabric-lifecycle-events-v1": "*" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /fabric/mc1205/src/main/resources/fabric.mod.json: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": 1, 3 | "id": "grimac-mc1205", 4 | "version": "${version}", 5 | "name": "GrimAC for 1.20+ built against 1.20.5", 6 | "description": "Libre simulation anticheat designed for 1.21 with 1.8-1.21 support, powered by PacketEvents 2.0.", 7 | "authors": [ 8 | "GrimAC" 9 | ], 10 | "license": "GPLv3", 11 | "environment": "server", 12 | "entrypoints": { 13 | "grimMainLoad": [ 14 | "ac.grim.grimac.platform.fabric.mc1205.GrimACFabric1200LoaderPlugin" 15 | ] 16 | }, 17 | "accessWidener": "grimac.accesswidener", 18 | "depends": { 19 | "minecraft": ">=1.20", 20 | "fabric-lifecycle-events-v1": "*" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ac/grim/grimac/platform/bukkit/initables/BukkitEventManager.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.bukkit.initables; 2 | 3 | import ac.grim.grimac.manager.init.start.StartableInitable; 4 | import ac.grim.grimac.platform.bukkit.GrimACBukkitLoaderPlugin; 5 | import ac.grim.grimac.platform.bukkit.events.PistonEvent; 6 | import ac.grim.grimac.utils.anticheat.LogUtil; 7 | import org.bukkit.Bukkit; 8 | 9 | public class BukkitEventManager implements StartableInitable { 10 | public void start() { 11 | LogUtil.info("Registering singular bukkit event... (PistonEvent)"); 12 | 13 | Bukkit.getPluginManager().registerEvents(new PistonEvent(), GrimACBukkitLoaderPlugin.LOADER); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /fabric/mc1216/src/main/resources/fabric.mod.json: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": 1, 3 | "id": "grimac-mc1215", 4 | "version": "${version}", 5 | "name": "GrimAC for 1.21.2+ built against 1.21.5", 6 | "description": "Libre simulation anticheat designed for 1.21 with 1.8-1.21 support, powered by PacketEvents 2.0.", 7 | "authors": [ 8 | "GrimAC" 9 | ], 10 | "license": "GPLv3", 11 | "environment": "server", 12 | "entrypoints": { 13 | "grimMainLoad": [ 14 | "ac.grim.grimac.platform.fabric.mc1216.GrimACFabric1212LoaderPlugin" 15 | ] 16 | }, 17 | "accessWidener": "grimac.accesswidener", 18 | "depends": { 19 | "minecraft": ">=1.21.2", 20 | "fabric-lifecycle-events-v1": "*" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/data/packetentity/PacketEntityArmorStand.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.data.packetentity; 2 | 3 | import ac.grim.grimac.player.GrimPlayer; 4 | import com.github.retrooper.packetevents.protocol.entity.type.EntityType; 5 | 6 | import java.util.UUID; 7 | 8 | public class PacketEntityArmorStand extends PacketEntity { 9 | 10 | public boolean isMarker = false; 11 | 12 | public PacketEntityArmorStand(GrimPlayer player, UUID uuid, EntityType type, double x, double y, double z, int extraData) { 13 | super(player, uuid, type, x, y, z); 14 | } 15 | 16 | @Override 17 | public boolean canHit() { 18 | return !isMarker && super.canHit(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/manager/init/start/PacketLimiter.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.manager.init.start; 2 | 3 | import ac.grim.grimac.GrimAPI; 4 | import ac.grim.grimac.player.GrimPlayer; 5 | 6 | public class PacketLimiter implements StartableInitable { 7 | @Override 8 | public void start() { 9 | GrimAPI.INSTANCE.getScheduler().getAsyncScheduler().runAtFixedRate(GrimAPI.INSTANCE.getGrimPlugin(), () -> { 10 | for (GrimPlayer player : GrimAPI.INSTANCE.getPlayerDataManager().getEntries()) { 11 | // Avoid concurrent reading on an integer as it's results are unknown 12 | player.cancelledPackets.set(0); 13 | } 14 | }, 1, 20); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/inventory/slot/ResultSlot.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.inventory.slot; 2 | 3 | import ac.grim.grimac.player.GrimPlayer; 4 | import ac.grim.grimac.utils.inventory.InventoryStorage; 5 | import com.github.retrooper.packetevents.protocol.item.ItemStack; 6 | 7 | public class ResultSlot extends Slot { 8 | 9 | public ResultSlot(InventoryStorage container, int slot) { 10 | super(container, slot); 11 | } 12 | 13 | @Override 14 | public boolean mayPlace(ItemStack itemStack) { 15 | return false; 16 | } 17 | 18 | @Override 19 | public void onTake(GrimPlayer player, ItemStack itemStack) { 20 | // Resync the player's inventory 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /fabric/mc1161/src/main/resources/fabric.mod.json: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": 1, 3 | "id": "grimac-mc1161", 4 | "version": "${version}", 5 | "name": "GrimAC for 1.16.1", 6 | "description": "Libre simulation anticheat designed for 1.21 with 1.8-1.21 support, powered by PacketEvents 2.0.", 7 | "authors": [ 8 | "GrimAC" 9 | ], 10 | "license": "GPLv3", 11 | "environment": "server", 12 | "entrypoints": { 13 | "grimMainLoad": [ 14 | "ac.grim.grimac.platform.fabric.mc1161.GrimACFabric1161LoaderPlugin" 15 | ] 16 | }, 17 | "accessWidener": "grimac.accesswidener", 18 | "depends": { 19 | "fabricloader": "\u003e\u003d0.16", 20 | "minecraft": ">=1.16.1", 21 | "fabric-resource-loader-v0": "*" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /fabric/src/main/java/ac/grim/grimac/platform/fabric/manager/FabricMessagePlaceHolderManager.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.fabric.manager; 2 | 3 | import ac.grim.grimac.platform.api.manager.MessagePlaceHolderManager; 4 | import ac.grim.grimac.platform.api.player.PlatformPlayer; 5 | import org.jetbrains.annotations.NotNull; 6 | import org.jetbrains.annotations.Nullable; 7 | 8 | public class FabricMessagePlaceHolderManager implements MessagePlaceHolderManager { 9 | 10 | // PlaceHolderAPI doesn't exist on Fabric and no chosen replacement for the platform yet 11 | @Override 12 | public @NotNull String replacePlaceholders(@Nullable PlatformPlayer player, @NotNull String string) { 13 | return string; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/checks/CheckData.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.checks; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | @Retention(RetentionPolicy.RUNTIME) 9 | @Target(ElementType.TYPE) 10 | public @interface CheckData { 11 | String name() default "UNKNOWN"; 12 | 13 | String alternativeName() default "UNKNOWN"; 14 | 15 | String configName() default "DEFAULT"; 16 | 17 | String description() default "No description provided"; 18 | 19 | double decay() default 0.05; 20 | 21 | double setback() default 25; 22 | 23 | boolean experimental() default false; 24 | 25 | } 26 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/command/handler/GrimCommandFailureHandler.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.command.handler; 2 | 3 | import ac.grim.grimac.command.SenderRequirement; 4 | import ac.grim.grimac.platform.api.sender.Sender; 5 | import org.incendo.cloud.context.CommandContext; 6 | import org.incendo.cloud.processors.requirements.RequirementFailureHandler; 7 | import org.jetbrains.annotations.NotNull; 8 | 9 | public class GrimCommandFailureHandler implements RequirementFailureHandler { 10 | @Override 11 | public void handleFailure(@NotNull CommandContext context, @NotNull SenderRequirement requirement) { 12 | context.sender().sendMessage(requirement.errorMessage(context.sender())); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/item/LegacyItem.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.item; 2 | 3 | import ac.grim.grimac.player.GrimPlayer; 4 | import ac.grim.grimac.utils.latency.CompensatedWorld; 5 | import com.github.retrooper.packetevents.protocol.item.ItemStack; 6 | import com.github.retrooper.packetevents.protocol.player.InteractionHand; 7 | 8 | public class LegacyItem extends ItemBehaviour { 9 | 10 | public static final LegacyItem INSTANCE = new LegacyItem(); 11 | 12 | @Override 13 | public boolean canUse(ItemStack item, CompensatedWorld world, GrimPlayer player, InteractionHand hand) { 14 | return false; // move legacy code that is responsible for handling item use from PacketPlayerDigging here?? 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /fabric/mc1171/src/main/java/ac/grim/grimac/platform/fabric/mc1171/Fabric1171PlatformServer.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.fabric.mc1171; 2 | 3 | import ac.grim.grimac.platform.fabric.GrimACFabricLoaderPlugin; 4 | import ac.grim.grimac.platform.fabric.mc1161.Fabric1140PlatformServer; 5 | import com.mojang.authlib.GameProfile; 6 | import org.jetbrains.annotations.Nullable; 7 | 8 | import java.util.Optional; 9 | 10 | public class Fabric1171PlatformServer extends Fabric1140PlatformServer { 11 | @Override 12 | public @Nullable GameProfile getProfileByName(String name) { 13 | Optional gameProfile = GrimACFabricLoaderPlugin.FABRIC_SERVER.getProfileCache().get(name); 14 | return gameProfile.orElse(null); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /fabric/mc1216/build.gradle.kts: -------------------------------------------------------------------------------- 1 | dependencies { 2 | minecraft("com.mojang:minecraft:1.21.6") 3 | mappings(loom.officialMojangMappings()) 4 | compileOnly(project(":fabric:mc1161", configuration = "namedElements")) 5 | compileOnly(project(":fabric:mc1171", configuration = "namedElements")) 6 | compileOnly(project(":fabric:mc1194", configuration = "namedElements")) 7 | compileOnly(project(":fabric:mc1205", configuration = "namedElements")) 8 | 9 | modImplementation(fabricApi.module("fabric-lifecycle-events-v1", "0.128.1+1.21.6")) 10 | modImplementation("me.lucko:fabric-permissions-api:0.6.1") 11 | include("me.lucko:fabric-permissions-api:0.6.1") 12 | } 13 | 14 | 15 | tasks.compileJava { 16 | options.release.set(21) 17 | } 18 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/data/packetentity/PacketEntityPainting.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.data.packetentity; 2 | 3 | import ac.grim.grimac.player.GrimPlayer; 4 | import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes; 5 | import com.github.retrooper.packetevents.protocol.world.Direction; 6 | import lombok.Getter; 7 | 8 | import java.util.UUID; 9 | 10 | @Getter 11 | public class PacketEntityPainting extends PacketEntity { 12 | 13 | private final Direction direction; 14 | 15 | public PacketEntityPainting(GrimPlayer player, UUID uuid, double x, double y, double z, Direction direction) { 16 | super(player, uuid, EntityTypes.PAINTING, x, y, z); 17 | this.direction = direction; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /fabric/mc1205/src/main/java/ac/grim/grimac/platform/fabric/mc1205/player/Fabric1202PlatformPlayer.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.fabric.mc1205.player; 2 | 3 | import ac.grim.grimac.platform.fabric.GrimACFabricLoaderPlugin; 4 | import ac.grim.grimac.platform.fabric.mc1171.player.Fabric1170PlatformPlayer; 5 | import net.minecraft.server.level.ServerPlayer; 6 | 7 | public class Fabric1202PlatformPlayer extends Fabric1170PlatformPlayer { 8 | public Fabric1202PlatformPlayer(ServerPlayer player) { 9 | super(player); 10 | } 11 | 12 | @Override 13 | public void kickPlayer(String textReason) { 14 | fabricPlayer.connection.disconnect(GrimACFabricLoaderPlugin.LOADER.getFabricMessageUtils().textLiteral(textReason)); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/checks/impl/movement/PredictionRunner.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.checks.impl.movement; 2 | 3 | import ac.grim.grimac.checks.Check; 4 | import ac.grim.grimac.checks.type.PositionCheck; 5 | import ac.grim.grimac.player.GrimPlayer; 6 | import ac.grim.grimac.utils.anticheat.update.PositionUpdate; 7 | 8 | public class PredictionRunner extends Check implements PositionCheck { 9 | public PredictionRunner(GrimPlayer playerData) { 10 | super(playerData); 11 | } 12 | 13 | @Override 14 | public void onPositionUpdate(final PositionUpdate positionUpdate) { 15 | if (!player.inVehicle()) { 16 | player.movementCheckRunner.processAndCheckMovementPacket(positionUpdate); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/manager/init/start/AbstractTickEndEvent.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.manager.init.start; 2 | 3 | import ac.grim.grimac.GrimAPI; 4 | import ac.grim.grimac.player.GrimPlayer; 5 | 6 | // Intended for future events we inject all platforms at the end of a tick 7 | public abstract class AbstractTickEndEvent implements StartableInitable { 8 | 9 | @Override 10 | public void start() { 11 | 12 | } 13 | 14 | protected void onEndOfTick(GrimPlayer player) { 15 | player.checkManager.getEntityReplication().onEndOfTickEvent(); 16 | } 17 | 18 | protected boolean shouldInjectEndTick() { 19 | return GrimAPI.INSTANCE.getConfigManager().getConfig().getBooleanElse("Reach.enable-post-packet", false); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ac/grim/grimac/platform/bukkit/scheduler/folia/FoliaPlatformScheduler.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.bukkit.scheduler.folia; 2 | 3 | import ac.grim.grimac.platform.api.scheduler.PlatformScheduler; 4 | import lombok.Getter; 5 | import org.jetbrains.annotations.NotNull; 6 | 7 | @Getter 8 | public class FoliaPlatformScheduler implements PlatformScheduler { 9 | private final @NotNull FoliaAsyncScheduler asyncScheduler = new FoliaAsyncScheduler(); 10 | private final @NotNull FoliaGlobalRegionScheduler globalRegionScheduler = new FoliaGlobalRegionScheduler(); 11 | private final @NotNull FoliaEntityScheduler entityScheduler = new FoliaEntityScheduler(); 12 | private final @NotNull FoliaRegionScheduler regionScheduler = new FoliaRegionScheduler(); 13 | } 14 | -------------------------------------------------------------------------------- /fabric/mc1161/src/main/java/ac/grim/grimac/platform/fabric/mc1161/util/convert/Fabric1161MessageUtil.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.fabric.mc1161.util.convert; 2 | 3 | import ac.grim.grimac.platform.fabric.utils.message.IFabricMessageUtil; 4 | import net.minecraft.commands.CommandSourceStack; 5 | import net.minecraft.network.chat.Component; 6 | import net.minecraft.network.chat.TextComponent; 7 | 8 | public class Fabric1161MessageUtil implements IFabricMessageUtil { 9 | @Override 10 | public Component textLiteral(String message) { 11 | return new TextComponent(message); 12 | } 13 | 14 | @Override 15 | public void sendMessage(CommandSourceStack target, Component message, boolean overlay) { 16 | target.sendSuccess(message, overlay); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/viaversion/ViaVersionUtil.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.viaversion; 2 | 3 | import ac.grim.grimac.utils.anticheat.LogUtil; 4 | import ac.grim.grimac.utils.reflection.ReflectionUtils; 5 | import lombok.experimental.UtilityClass; 6 | 7 | @UtilityClass 8 | public class ViaVersionUtil { 9 | public static final boolean isAvailable = ReflectionUtils.hasClass("com.viaversion.viaversion.api.Via"); 10 | 11 | static { 12 | if (!isAvailable && ReflectionUtils.hasClass("us.myles.ViaVersion.api.Via")) { 13 | LogUtil.error("Using unsupported ViaVersion 4.0 API, update ViaVersion to 5.0"); 14 | } 15 | } 16 | 17 | public static void injectHooks() { 18 | if (isAvailable) ViaVersionHooks.load(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ac/grim/grimac/platform/bukkit/scheduler/bukkit/BukkitPlatformScheduler.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.bukkit.scheduler.bukkit; 2 | 3 | import ac.grim.grimac.platform.api.scheduler.PlatformScheduler; 4 | import lombok.Getter; 5 | import org.jetbrains.annotations.NotNull; 6 | 7 | @Getter 8 | public class BukkitPlatformScheduler implements PlatformScheduler { 9 | private final @NotNull BukkitAsyncScheduler asyncScheduler = new BukkitAsyncScheduler(); 10 | private final @NotNull BukkitGlobalRegionScheduler globalRegionScheduler = new BukkitGlobalRegionScheduler(); 11 | private final @NotNull BukkitEntityScheduler entityScheduler = new BukkitEntityScheduler(); 12 | private final @NotNull BukkitRegionScheduler regionScheduler = new BukkitRegionScheduler(); 13 | } 14 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/payload/PayloadItemName.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.payload; 2 | 3 | import com.github.retrooper.packetevents.wrapper.PacketWrapper; 4 | import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientNameItem; 5 | import org.jetbrains.annotations.NotNull; 6 | 7 | /** 8 | * Payload wrapper for serverbound {@code MC|ItemName}, replaced by the {@link WrapperPlayClientNameItem NAME_ITEM} packet in 1.13 9 | */ 10 | public record PayloadItemName(@NotNull String itemName) implements Payload { 11 | public PayloadItemName(byte[] data) { 12 | this(Payload.wrapper(data).readString()); 13 | } 14 | 15 | @Override 16 | public void write(PacketWrapper wrapper) { 17 | wrapper.writeString(itemName); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /fabric/mc1171/src/main/java/ac/grim/grimac/platform/fabric/mc1171/player/Fabric1170PlatformPlayer.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.fabric.mc1171.player; 2 | 3 | import ac.grim.grimac.platform.fabric.mc1161.player.Fabric1161PlatformPlayer; 4 | import ac.grim.grimac.platform.fabric.utils.convert.FabricConversionUtil; 5 | import com.github.retrooper.packetevents.protocol.player.GameMode; 6 | import net.minecraft.server.level.ServerPlayer; 7 | 8 | public class Fabric1170PlatformPlayer extends Fabric1161PlatformPlayer { 9 | public Fabric1170PlatformPlayer(ServerPlayer player) { 10 | super(player); 11 | } 12 | 13 | @Override 14 | public void setGameMode(GameMode gameMode) { 15 | fabricPlayer.setGameMode(FabricConversionUtil.toFabricGameMode(gameMode)); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/inventory/inventory/NotImplementedMenu.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.inventory.inventory; 2 | 3 | import ac.grim.grimac.player.GrimPlayer; 4 | import ac.grim.grimac.utils.inventory.Inventory; 5 | import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientClickWindow; 6 | 7 | public class NotImplementedMenu extends AbstractContainerMenu { 8 | public NotImplementedMenu(GrimPlayer player, Inventory playerInventory) { 9 | super(player, playerInventory); 10 | player.inventory.isPacketInventoryActive = false; 11 | player.inventory.needResend = true; 12 | } 13 | 14 | @Override 15 | public void doClick(int button, int slotID, WrapperPlayClientClickWindow.WindowClickType clickType) { 16 | 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/lists/EvictingQueue.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.lists; 2 | 3 | import java.util.ArrayList; 4 | 5 | // https://stackoverflow.com/a/21047889 6 | // License: Originally CC By-SA 4.0 licensed as GPL 7 | public class EvictingQueue extends ArrayList { 8 | private final int maxSize; 9 | 10 | public EvictingQueue(int size) { 11 | this.maxSize = size; 12 | } 13 | 14 | public boolean add(K k) { 15 | boolean r = super.add(k); 16 | if (size() > maxSize) { 17 | removeRange(0, size() - maxSize); 18 | } 19 | return r; 20 | } 21 | 22 | public K getYoungest() { 23 | return get(size() - 1); 24 | } 25 | 26 | public K getOldest() { 27 | return get(0); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/math/VanillaMath.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.math; 2 | 3 | import lombok.experimental.UtilityClass; 4 | import org.jetbrains.annotations.Contract; 5 | 6 | @UtilityClass 7 | public class VanillaMath { 8 | private static final float[] SIN = new float[65536]; 9 | 10 | static { 11 | for (int i = 0; i < SIN.length; ++i) { 12 | SIN[i] = (float) StrictMath.sin(i * Math.PI * 2d / 65536d); 13 | } 14 | } 15 | 16 | @Contract(pure = true) 17 | public static float sin(float value) { 18 | return SIN[(int) (value * 10430.378f) & 0xFFFF]; 19 | } 20 | 21 | @Contract(pure = true) 22 | public static float cos(float value) { 23 | return SIN[(int) (value * 10430.378f + 16384.0f) & 0xFFFF]; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /fabric/mc1194/src/main/java/ac/grim/grimac/platform/fabric/mc1194/Fabric1190PlatformServer.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.fabric.mc1194; 2 | 3 | import ac.grim.grimac.platform.api.sender.Sender; 4 | import ac.grim.grimac.platform.fabric.GrimACFabricLoaderPlugin; 5 | import ac.grim.grimac.platform.fabric.mc1171.Fabric1171PlatformServer; 6 | import net.minecraft.commands.CommandSourceStack; 7 | 8 | public class Fabric1190PlatformServer extends Fabric1171PlatformServer { 9 | @Override 10 | public void dispatchCommand(Sender sender, String command) { 11 | CommandSourceStack commandSource = GrimACFabricLoaderPlugin.LOADER.getFabricSenderFactory().reverse(sender); 12 | GrimACFabricLoaderPlugin.FABRIC_SERVER.getCommands().performPrefixedCommand(commandSource, command); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /fabric/mc1194/src/main/java/ac/grim/grimac/platform/fabric/mc1194/player/Fabric1193PlatformInventory.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.fabric.mc1194.player; 2 | 3 | import ac.grim.grimac.platform.fabric.mc1161.player.Fabric1161PlatformInventory; 4 | import net.minecraft.core.registries.BuiltInRegistries; 5 | import net.minecraft.resources.ResourceLocation; 6 | import net.minecraft.server.level.ServerPlayer; 7 | import net.minecraft.world.inventory.MenuType; 8 | 9 | public class Fabric1193PlatformInventory extends Fabric1161PlatformInventory { 10 | public Fabric1193PlatformInventory(ServerPlayer player) { 11 | super(player); 12 | } 13 | 14 | @Override 15 | protected ResourceLocation getScreenID(MenuType type) { 16 | return BuiltInRegistries.MENU.getKey(type); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ac/grim/grimac/platform/bukkit/BukkitPlatformPlugin.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.bukkit; 2 | 3 | import ac.grim.grimac.platform.api.PlatformPlugin; 4 | import org.bukkit.plugin.Plugin; 5 | 6 | public class BukkitPlatformPlugin implements PlatformPlugin { 7 | private final Plugin plugin; 8 | 9 | public BukkitPlatformPlugin(Plugin plugin) { 10 | this.plugin = plugin; 11 | } 12 | 13 | @Override 14 | public boolean isEnabled() { 15 | return plugin.isEnabled(); 16 | } 17 | 18 | @Override 19 | public String getName() { 20 | return plugin.getName(); 21 | } 22 | 23 | @SuppressWarnings("deprecation") 24 | @Override 25 | public String getVersion() { 26 | return plugin.getDescription().getVersion(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/data/packetentity/PacketEntityGuardian.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.data.packetentity; 2 | 3 | import ac.grim.grimac.player.GrimPlayer; 4 | import com.github.retrooper.packetevents.protocol.entity.type.EntityType; 5 | 6 | import java.util.UUID; 7 | 8 | public class PacketEntityGuardian extends PacketEntity { 9 | // this is only actually stored as a field in legacy versions (1.8 - 1.10.2) 10 | // in newer versions Elder Guardians are separate entities, we use this field regardless for simplicity 11 | public boolean isElder; 12 | 13 | public PacketEntityGuardian(GrimPlayer player, UUID uuid, EntityType type, double x, double y, double z, boolean isElder) { 14 | super(player, uuid, type, x, y, z); 15 | this.isElder = isElder; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/data/packetentity/dragon/PacketEntityEnderDragonPart.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.data.packetentity.dragon; 2 | 3 | import ac.grim.grimac.player.GrimPlayer; 4 | import ac.grim.grimac.utils.data.packetentity.PacketEntity; 5 | import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes; 6 | 7 | public final class PacketEntityEnderDragonPart extends PacketEntity { 8 | public final DragonPart part; 9 | public final float width, height; 10 | 11 | public PacketEntityEnderDragonPart(GrimPlayer player, DragonPart part, double x, double y, double z, float width, float height) { 12 | super(player, null, EntityTypes.ENDER_DRAGON, x, y, z); 13 | this.part = part; 14 | this.width = width; 15 | this.height = height; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/manager/violationdatabase/NoOpViolationDatabase.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.manager.violationdatabase; 2 | 3 | import ac.grim.grimac.player.GrimPlayer; 4 | 5 | import java.util.List; 6 | import java.util.UUID; 7 | 8 | public final class NoOpViolationDatabase implements ViolationDatabase { 9 | public static final NoOpViolationDatabase INSTANCE = new NoOpViolationDatabase(); 10 | private NoOpViolationDatabase() {} 11 | 12 | @Override public void connect() { } 13 | @Override public void disconnect() {} 14 | @Override public void logAlert(GrimPlayer p, String grimVersion, String v, String c, int vl) {} 15 | @Override public int getLogCount(UUID player) { return 0; } 16 | @Override public List getViolations(UUID p, int page, int lim) { return List.of(); } 17 | } 18 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/data/TrackerData.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.data; 2 | 3 | import com.github.retrooper.packetevents.protocol.entity.type.EntityType; 4 | import lombok.Data; 5 | 6 | @Data 7 | public class TrackerData { 8 | private double x, y, z; 9 | private float xRot, yRot; 10 | private EntityType entityType; 11 | private int lastTransactionHung; 12 | private int legacyPointEightMountedUpon; 13 | 14 | public TrackerData(double x, double y, double z, float xRot, float yRot, EntityType entityType, int lastTransactionHung) { 15 | this.x = x; 16 | this.y = y; 17 | this.z = z; 18 | this.xRot = xRot; 19 | this.yRot = yRot; 20 | this.entityType = entityType; 21 | this.lastTransactionHung = lastTransactionHung; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/data/HitData.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.data; 2 | 3 | import ac.grim.grimac.utils.math.Vector3dm; 4 | import com.github.retrooper.packetevents.protocol.world.BlockFace; 5 | import com.github.retrooper.packetevents.protocol.world.states.WrappedBlockState; 6 | import com.github.retrooper.packetevents.util.Vector3d; 7 | import com.github.retrooper.packetevents.util.Vector3i; 8 | 9 | public record HitData( 10 | Vector3i position, 11 | Vector3dm blockHitLocation, 12 | BlockFace closestDirection, 13 | WrappedBlockState state 14 | ) { 15 | public Vector3d getRelativeBlockHitLocation() { 16 | return new Vector3d(blockHitLocation.getX() - position.getX(), blockHitLocation.getY() - position.getY(), blockHitLocation.getZ() - position.getZ()); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /common/src/main/resources/discord/es.yml: -------------------------------------------------------------------------------- 1 | # Configuraciones del webhook de Discord 2 | # Si tienes dudas en como usarlos, puedes consultar el artículo de soporte de Discord: https://support.discord.com/hc/es/articles/228383668 3 | 4 | # ¿Deberíamos usar webhooks? 5 | enabled: false 6 | 7 | # La URL del webhook. 8 | webhook: "" 9 | 10 | embed-title: "**Grim Alert**" 11 | 12 | # El color del embed que se mandara por este webhook. 13 | embed-color: "#00FFFF" 14 | 15 | include-timestamp: true 16 | 17 | # El contenido del embed que se mandara por este webhook. 18 | violation-content: 19 | - "**Jugador**: %player%" 20 | - "**Comprobación**: %check%" 21 | - "**Violaciones**: %violations%" 22 | - "**Version del cliente**: %version%" 23 | - "**Marca del cliente**: %brand%" 24 | - "**Latencia**: %ping%" 25 | - "**TPS**: %tps%" 26 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/data/packetentity/PacketEntityCamel.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.data.packetentity; 2 | 3 | import ac.grim.grimac.player.GrimPlayer; 4 | import com.github.retrooper.packetevents.protocol.attribute.Attributes; 5 | import com.github.retrooper.packetevents.protocol.entity.type.EntityType; 6 | 7 | import java.util.UUID; 8 | 9 | public class PacketEntityCamel extends PacketEntityHorse { 10 | 11 | public boolean dashing = false; 12 | 13 | public PacketEntityCamel(GrimPlayer player, UUID uuid, EntityType type, double x, double y, double z, float xRot) { 14 | super(player, uuid, type, x, y, z, xRot); 15 | 16 | setAttribute(Attributes.JUMP_STRENGTH, 0.42f); 17 | setAttribute(Attributes.MOVEMENT_SPEED, 0.09f); 18 | setAttribute(Attributes.STEP_HEIGHT, 1.5f); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/data/LastInstance.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.data; 2 | 3 | import ac.grim.grimac.player.GrimPlayer; 4 | 5 | public class LastInstance { 6 | private int lastInstance = 100; 7 | 8 | public LastInstance(GrimPlayer player) { 9 | player.lastInstanceManager.addInstance(this); 10 | } 11 | 12 | public boolean hasOccurredSince(int time) { 13 | return lastInstance <= time; 14 | } 15 | 16 | public void reset() { 17 | lastInstance = 0; 18 | } 19 | 20 | public void tick() { 21 | // Don't overflow (a VERY long timer attack or a player playing for days could cause this to overflow) 22 | // The CPU can predict this branch, so it's only a few cycles. 23 | if (lastInstance == Integer.MAX_VALUE) lastInstance = 100; 24 | lastInstance++; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/manager/tick/impl/ClientVersionSetter.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.manager.tick.impl; 2 | 3 | import ac.grim.grimac.GrimAPI; 4 | import ac.grim.grimac.manager.tick.Tickable; 5 | import ac.grim.grimac.player.GrimPlayer; 6 | import com.github.retrooper.packetevents.netty.channel.ChannelHelper; 7 | 8 | public class ClientVersionSetter implements Tickable { 9 | @Override 10 | public void tick() { 11 | for (GrimPlayer player : GrimAPI.INSTANCE.getPlayerDataManager().getEntries()) { 12 | // channel was somehow closed without us getting a disconnect event 13 | if (!ChannelHelper.isOpen(player.user.getChannel())) { 14 | GrimAPI.INSTANCE.getPlayerDataManager().onDisconnect(player.user); 15 | continue; 16 | } 17 | 18 | player.pollData(); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/platform/api/entity/GrimEntity.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.api.entity; 2 | 3 | import ac.grim.grimac.api.GrimIdentity; 4 | import ac.grim.grimac.platform.api.world.PlatformWorld; 5 | import ac.grim.grimac.utils.math.Location; 6 | import org.jetbrains.annotations.NotNull; 7 | 8 | import java.util.concurrent.CompletableFuture; 9 | 10 | public interface GrimEntity extends GrimIdentity { 11 | /** 12 | * Eject any passenger. 13 | * 14 | * @return True if there was a passenger. 15 | */ 16 | boolean eject(); 17 | 18 | CompletableFuture teleportAsync(Location location); 19 | 20 | @NotNull 21 | Object getNative(); 22 | 23 | boolean isDead(); 24 | 25 | PlatformWorld getWorld(); 26 | 27 | Location getLocation(); 28 | 29 | double distanceSquared(double x, double y, double z); 30 | } 31 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Publish Release 2 | 3 | on: 4 | release: 5 | types: [published] 6 | 7 | jobs: 8 | call-release-workflow: 9 | uses: ./.github/workflows/build-and-publish.yml 10 | with: 11 | runner: 'tenki-standard-autoscale' 12 | is-release-build: true 13 | release-version-type: release # Official releases are 'release' 14 | # Use the body of the GitHub Release as the changelog 15 | release-changelog: ${{ github.event.release.body }} 16 | run-build-scan: false 17 | publish-artifacts: true 18 | secrets: 19 | MODRINTH_ID: ${{ secrets.MODRINTH_ID }} 20 | MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }} 21 | BUILD_UPDATE_TOKEN: ${{ secrets.BUILD_UPDATE_TOKEN }} 22 | BUILD_UPDATE_URL: ${{ secrets.BUILD_UPDATE_URL }} 23 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/enums/Pose.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.enums; 2 | 3 | public enum Pose { 4 | STANDING(0.6f, 1.8f, 1.62f), 5 | FALL_FLYING(0.6f, 0.6f, 0.4f), 6 | SLEEPING(0.2f, 0.2f, 0.2f), 7 | SWIMMING(0.6f, 0.6f, 0.4f), 8 | SPIN_ATTACK(0.6f, 0.6f, 0.4f), 9 | CROUCHING(0.6f, 1.5f, 1.27f), 10 | DYING(0.2f, 0.2f, 0.2f), 11 | 12 | // Non-player poses 13 | NINE_CROUCHING(0.6f, 1.65f, 1.54f), // 1.9-1.13 clients have a slightly different crouching hitbox 14 | LONG_JUMPING(0.6f, 1.8f, 1.54f); // DUMMY (players can't have this pose) 15 | 16 | public final float width; 17 | public final float height; 18 | public final float eyeHeight; 19 | 20 | Pose(float width, float height, float eyeHeight) { 21 | this.width = width; 22 | this.height = height; 23 | this.eyeHeight = eyeHeight; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/payload/PayloadBookEdit.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.payload; 2 | 3 | import com.github.retrooper.packetevents.protocol.item.ItemStack; 4 | import com.github.retrooper.packetevents.wrapper.PacketWrapper; 5 | import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientEditBook; 6 | import org.jetbrains.annotations.NotNull; 7 | 8 | /** 9 | * Payload wrapper for serverbound {@code MC|BEdit} and {@code MC|BSign}, replaced by the {@link WrapperPlayClientEditBook EDIT_BOOK} packet in 1.13 10 | */ 11 | public record PayloadBookEdit(@NotNull ItemStack itemStack) implements Payload { 12 | public PayloadBookEdit(byte[] data) { 13 | this(Payload.wrapper(data).readItemStack()); 14 | } 15 | 16 | @Override 17 | public void write(PacketWrapper wrapper) { 18 | wrapper.writeItemStack(itemStack); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/predictionengine/movementtick/MovementTickerPig.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.predictionengine.movementtick; 2 | 3 | import ac.grim.grimac.player.GrimPlayer; 4 | import ac.grim.grimac.utils.data.packetentity.PacketEntityRideable; 5 | import ac.grim.grimac.utils.math.Vector3dm; 6 | import com.github.retrooper.packetevents.protocol.attribute.Attributes; 7 | 8 | public class MovementTickerPig extends MovementTickerRideable { 9 | public MovementTickerPig(GrimPlayer player) { 10 | super(player); 11 | this.movementInput = new Vector3dm(0, 0, 1); 12 | } 13 | 14 | @Override 15 | public float getSteeringSpeed() { // Vanilla multiples by 0.225f 16 | PacketEntityRideable pig = (PacketEntityRideable) player.compensatedEntities.self.getRiding(); 17 | return (float) pig.getAttributeValue(Attributes.MOVEMENT_SPEED) * 0.225f; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /fabric/src/main/java/ac/grim/grimac/platform/fabric/mixins/ServerPlayerMixin.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.fabric.mixins; 2 | 3 | import ac.grim.grimac.GrimAPI; 4 | import ac.grim.grimac.platform.fabric.player.FabricPlatformPlayerFactory; 5 | import net.minecraft.server.level.ServerPlayer; 6 | import org.spongepowered.asm.mixin.Mixin; 7 | import org.spongepowered.asm.mixin.injection.At; 8 | import org.spongepowered.asm.mixin.injection.Inject; 9 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 10 | 11 | @Mixin(ServerPlayer.class) 12 | abstract class ServerPlayerMixin { 13 | @Inject(method = "restoreFrom", at = @At("TAIL")) 14 | private void onRestoreFrom(ServerPlayer oldPlayer, boolean alive, CallbackInfo ci) { 15 | ((FabricPlatformPlayerFactory) GrimAPI.INSTANCE.getPlatformPlayerFactory()).replaceNativePlayer(oldPlayer.getUUID(), (ServerPlayer) (Object) this); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /fabric/src/main/java/ac/grim/grimac/platform/fabric/scheduler/FabricTaskHandle.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.fabric.scheduler; 2 | 3 | import ac.grim.grimac.platform.api.scheduler.TaskHandle; 4 | import lombok.Getter; 5 | 6 | public class FabricTaskHandle implements TaskHandle { 7 | private final Runnable cancellationTask; 8 | @Getter 9 | private boolean cancelled; 10 | @Getter 11 | private final boolean sync; 12 | 13 | public FabricTaskHandle(Runnable cancellationTask) { 14 | this.cancellationTask = cancellationTask; 15 | this.sync = false; 16 | } 17 | 18 | public FabricTaskHandle(Runnable cancellationTask, boolean sync) { 19 | this.cancellationTask = cancellationTask; 20 | this.sync = sync; 21 | } 22 | 23 | @Override 24 | public void cancel() { 25 | this.cancellationTask.run(); 26 | this.cancelled = true; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/reflection/GeyserUtil.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.reflection; 2 | 3 | import lombok.experimental.UtilityClass; 4 | import org.geysermc.api.Geyser; 5 | import org.geysermc.floodgate.api.FloodgateApi; 6 | 7 | import java.util.UUID; 8 | 9 | @UtilityClass 10 | public class GeyserUtil { 11 | // Floodgate is the authentication system for Geyser on servers that use Geyser as a proxy instead of installing it as a plugin directly on the server 12 | private static final boolean floodgate = ReflectionUtils.hasClass("org.geysermc.floodgate.api.FloodgateApi"); 13 | private static final boolean geyser = ReflectionUtils.hasClass("org.geysermc.api.Geyser"); 14 | 15 | public static boolean isBedrockPlayer(UUID uuid) { 16 | return floodgate && FloodgateApi.getInstance().isFloodgatePlayer(uuid) 17 | || geyser && Geyser.api().isBedrockPlayer(uuid); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /fabric/mc1216/src/main/java/ac/grim/grimac/platform/fabric/mc1216/player/Fabric1215PlatformInventory.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.fabric.mc1216.player; 2 | 3 | import ac.grim.grimac.platform.fabric.mc1194.player.Fabric1193PlatformInventory; 4 | import net.minecraft.core.registries.BuiltInRegistries; 5 | import net.minecraft.resources.ResourceLocation; 6 | import net.minecraft.server.level.ServerPlayer; 7 | import net.minecraft.world.inventory.MenuType; 8 | 9 | public class Fabric1215PlatformInventory extends Fabric1193PlatformInventory { 10 | public Fabric1215PlatformInventory(ServerPlayer player) { 11 | super(player); 12 | } 13 | 14 | @Override 15 | protected ResourceLocation getScreenID(MenuType type) { 16 | return BuiltInRegistries.MENU.getKey(type); 17 | } 18 | 19 | @Override 20 | protected boolean isPlayerCreative() { 21 | return fabricPlayer.isCreative(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /fabric/src/main/java/ac/grim/grimac/platform/fabric/initables/FabricBStats.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.fabric.initables; 2 | 3 | import ac.grim.grimac.GrimAPI; 4 | import ac.grim.grimac.manager.init.start.StartableInitable; 5 | import ac.grim.grimac.manager.init.stop.StoppableInitable; 6 | import ac.grim.grimac.platform.fabric.utils.metrics.MetricsFabric; 7 | import ac.grim.grimac.utils.anticheat.Constants; 8 | 9 | public class FabricBStats implements StartableInitable, StoppableInitable { 10 | 11 | private MetricsFabric metricsFabric; 12 | 13 | @Override 14 | public void start() { 15 | try { 16 | metricsFabric = new MetricsFabric(GrimAPI.INSTANCE.getGrimPlugin(), Constants.BSTATS_PLUGIN_ID); 17 | } catch (Exception ignored) {} 18 | } 19 | 20 | @Override 21 | public void stop() { 22 | if (metricsFabric != null) 23 | metricsFabric.shutdown(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/platform/api/manager/ItemResetHandler.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.api.manager; 2 | 3 | import ac.grim.grimac.platform.api.player.PlatformPlayer; 4 | import com.github.retrooper.packetevents.protocol.player.InteractionHand; 5 | import org.jetbrains.annotations.Contract; 6 | import org.jetbrains.annotations.Nullable; 7 | 8 | public interface ItemResetHandler { 9 | /** 10 | * clears any item usage the player may have, without triggering side effects (ie bow firing) 11 | */ 12 | void resetItemUsage(@Nullable PlatformPlayer player); 13 | /** 14 | * Returns the hand in which the player is using an item, or null if the player isn't using an item 15 | */ 16 | @Contract("null -> null") 17 | @Nullable InteractionHand getItemUsageHand(@Nullable PlatformPlayer player); 18 | @Contract("null -> false") 19 | boolean isUsingItem(@Nullable PlatformPlayer player); 20 | } 21 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/checks/impl/flight/FlightA.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.checks.impl.flight; 2 | 3 | import ac.grim.grimac.checks.Check; 4 | import ac.grim.grimac.checks.type.PacketCheck; 5 | import ac.grim.grimac.player.GrimPlayer; 6 | import com.github.retrooper.packetevents.event.PacketReceiveEvent; 7 | import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerFlying; 8 | 9 | // This check catches 100% of cheaters. 10 | public class FlightA extends Check implements PacketCheck { 11 | public FlightA(GrimPlayer player) { 12 | super(player); 13 | } 14 | 15 | @Override 16 | public void onPacketReceive(PacketReceiveEvent event) { 17 | // If the player sends a flying packet, but they aren't flying, then they are cheating. 18 | if (WrapperPlayClientPlayerFlying.isFlying(event.getPacketType()) && !player.isFlying) { 19 | flag(); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/data/packetentity/PacketEntityRideable.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.data.packetentity; 2 | 3 | import ac.grim.grimac.player.GrimPlayer; 4 | import ac.grim.grimac.utils.data.attribute.ValuedAttribute; 5 | import com.github.retrooper.packetevents.protocol.attribute.Attributes; 6 | import com.github.retrooper.packetevents.protocol.entity.type.EntityType; 7 | 8 | import java.util.UUID; 9 | 10 | public class PacketEntityRideable extends PacketEntity { 11 | 12 | public boolean hasSaddle = false; 13 | public int boostTimeMax = 0; 14 | public int currentBoostTime = 0; 15 | 16 | public PacketEntityRideable(GrimPlayer player, UUID uuid, EntityType type, double x, double y, double z) { 17 | super(player, uuid, type, x, y, z); 18 | setAttribute(Attributes.STEP_HEIGHT, 1.0f); 19 | trackAttribute(ValuedAttribute.ranged(Attributes.MOVEMENT_SPEED, 0.1f, 0, 1024)); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /fabric/mc1216/src/main/java/ac/grim/grimac/platform/fabric/mc1216/command/Fabric1212PlayerSelectorAdapter.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.fabric.mc1216.command; 2 | 3 | import ac.grim.grimac.platform.api.sender.Sender; 4 | import ac.grim.grimac.platform.fabric.GrimACFabricLoaderPlugin; 5 | import ac.grim.grimac.platform.fabric.mc1161.command.Fabric1161PlayerSelectorAdapter; 6 | import org.incendo.cloud.minecraft.modded.data.SinglePlayerSelector; 7 | 8 | public class Fabric1212PlayerSelectorAdapter extends Fabric1161PlayerSelectorAdapter { 9 | 10 | public Fabric1212PlayerSelectorAdapter(SinglePlayerSelector fabricSelector) { 11 | super(fabricSelector); 12 | } 13 | 14 | // 1.21.2 .getCommandSource() moves from entity to player 15 | @Override 16 | public Sender getSinglePlayer() { 17 | return GrimACFabricLoaderPlugin.LOADER.getFabricSenderFactory().map(fabricSelector.single().createCommandSourceStack()); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ac/grim/grimac/platform/bukkit/scheduler/bukkit/BukkitTaskHandle.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.bukkit.scheduler.bukkit; 2 | 3 | import ac.grim.grimac.platform.api.scheduler.TaskHandle; 4 | import org.bukkit.scheduler.BukkitTask; 5 | import org.jetbrains.annotations.Contract; 6 | import org.jetbrains.annotations.NotNull; 7 | 8 | import java.util.Objects; 9 | 10 | public class BukkitTaskHandle implements TaskHandle { 11 | 12 | private final @NotNull BukkitTask task; 13 | 14 | @Contract(pure = true) 15 | public BukkitTaskHandle(@NotNull BukkitTask task) { 16 | this.task = Objects.requireNonNull(task); 17 | } 18 | 19 | @Override 20 | public boolean isSync() { 21 | return task.isSync(); 22 | } 23 | 24 | @Override 25 | public boolean isCancelled() { 26 | return task.isCancelled(); 27 | } 28 | 29 | @Override 30 | public void cancel() { 31 | task.cancel(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /fabric/src/main/java/ac/grim/grimac/platform/fabric/mixins/LevelChunkMixin.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.fabric.mixins; 2 | 3 | import ac.grim.grimac.platform.api.world.PlatformChunk; 4 | import net.minecraft.core.BlockPos; 5 | import net.minecraft.world.level.block.Block; 6 | import net.minecraft.world.level.chunk.LevelChunk; 7 | import org.spongepowered.asm.mixin.Implements; 8 | import org.spongepowered.asm.mixin.Interface; 9 | import org.spongepowered.asm.mixin.Mixin; 10 | 11 | @Mixin(LevelChunk.class) 12 | @Implements(@Interface(iface = PlatformChunk.class, prefix = "grimac$")) 13 | abstract class LevelChunkMixin { 14 | public int grimac$getBlockID(int x, int y, int z) { 15 | LevelChunk chunk = (LevelChunk) (Object) this; 16 | return Block.getId(chunk.getBlockState(new BlockPos( 17 | chunk.getPos().getMinBlockX() + x, 18 | y, 19 | chunk.getPos().getMinBlockZ() + z 20 | ))); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/nmsutil/CheckIfChunksLoaded.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.nmsutil; 2 | 3 | import ac.grim.grimac.player.GrimPlayer; 4 | import lombok.experimental.UtilityClass; 5 | 6 | @UtilityClass 7 | public class CheckIfChunksLoaded { 8 | public static boolean areChunksUnloadedAt(GrimPlayer player, int minX, int minY, int minZ, int maxX, int maxY, int maxZ) { 9 | if (maxY < player.compensatedWorld.getMinHeight() || minY >= player.compensatedWorld.getMaxHeight()) { 10 | return true; 11 | } 12 | 13 | minX >>= 4; 14 | minZ >>= 4; 15 | maxX >>= 4; 16 | maxZ >>= 4; 17 | 18 | for (int i = minX; i <= maxX; ++i) { 19 | for (int j = minZ; j <= maxZ; ++j) { 20 | if (player.compensatedWorld.getChunk(i, j) == null) { 21 | return true; 22 | } 23 | } 24 | } 25 | 26 | return false; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/change/BlockModification.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.change; 2 | 3 | import com.github.retrooper.packetevents.protocol.world.states.WrappedBlockState; 4 | import com.github.retrooper.packetevents.util.Vector3i; 5 | import org.jetbrains.annotations.NotNull; 6 | 7 | public record BlockModification( 8 | WrappedBlockState oldBlockContents, 9 | WrappedBlockState newBlockContents, 10 | Vector3i location, 11 | int tick, 12 | Cause cause 13 | ) { 14 | @Override 15 | public @NotNull String toString() { 16 | return String.format( 17 | "BlockModification{location=%s, old=%s, new=%s, tick=%d, cause=%s}", 18 | location, oldBlockContents, newBlockContents, tick, cause 19 | ); 20 | } 21 | 22 | public enum Cause { 23 | START_DIGGING, 24 | APPLY_BLOCK_CHANGES, 25 | HANDLE_NETTY_SYNC_TRANSACTION, 26 | OTHER 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ac/grim/grimac/platform/bukkit/scheduler/folia/FoliaTaskHandle.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.bukkit.scheduler.folia; 2 | 3 | import ac.grim.grimac.platform.api.scheduler.TaskHandle; 4 | import io.papermc.paper.threadedregions.scheduler.ScheduledTask; 5 | import org.jetbrains.annotations.Contract; 6 | import org.jetbrains.annotations.NotNull; 7 | 8 | import java.util.Objects; 9 | 10 | public class FoliaTaskHandle implements TaskHandle { 11 | 12 | private final @NotNull ScheduledTask task; 13 | 14 | @Contract(pure = true) 15 | public FoliaTaskHandle(@NotNull ScheduledTask task) { 16 | this.task = Objects.requireNonNull(task); 17 | } 18 | 19 | @Override 20 | public boolean isSync() { 21 | return false; 22 | } 23 | 24 | @Override 25 | public boolean isCancelled() { 26 | return task.isCancelled(); 27 | } 28 | 29 | @Override 30 | public void cancel() { 31 | task.cancel(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /fabric/mc1216/src/main/java/ac/grim/grimac/platform/fabric/mc1216/convert/Fabric1216ConversionUtil.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.fabric.mc1216.convert; 2 | 3 | import com.mojang.serialization.JsonOps; 4 | import io.github.retrooper.packetevents.adventure.serializer.gson.GsonComponentSerializer; 5 | import net.kyori.adventure.text.Component; 6 | import net.minecraft.core.RegistryAccess; 7 | import net.minecraft.network.chat.ComponentSerialization; 8 | 9 | public class Fabric1216ConversionUtil extends ac.grim.grimac.platform.fabric.mc1205.convert.Fabric1205ConversionUtil { 10 | 11 | @Override 12 | public net.minecraft.network.chat.Component toNativeText(Component component) { 13 | return ComponentSerialization.CODEC.decode( 14 | RegistryAccess.EMPTY.createSerializationContext(JsonOps.INSTANCE), 15 | GsonComponentSerializer.gson().serializeToTree(component) 16 | ).getOrThrow(IllegalArgumentException::new).getFirst(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/data/Pair.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of packetevents - https://github.com/retrooper/packetevents 3 | * Copyright (C) 2021 retrooper and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package ac.grim.grimac.utils.data; 20 | 21 | public record Pair(A first, B second) {} 22 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/checks/impl/movement/VehiclePredictionRunner.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.checks.impl.movement; 2 | 3 | import ac.grim.grimac.checks.Check; 4 | import ac.grim.grimac.checks.type.VehicleCheck; 5 | import ac.grim.grimac.player.GrimPlayer; 6 | import ac.grim.grimac.utils.anticheat.update.PositionUpdate; 7 | import ac.grim.grimac.utils.anticheat.update.VehiclePositionUpdate; 8 | 9 | public class VehiclePredictionRunner extends Check implements VehicleCheck { 10 | public VehiclePredictionRunner(GrimPlayer playerData) { 11 | super(playerData); 12 | } 13 | 14 | @Override 15 | public void process(final VehiclePositionUpdate vehicleUpdate) { 16 | // Vehicle onGround = false always 17 | // We don't do vehicle setbacks because vehicle netcode sucks. 18 | player.movementCheckRunner.processAndCheckMovementPacket(new PositionUpdate(vehicleUpdate.from(), vehicleUpdate.to(), false, null, null, vehicleUpdate.isTeleport())); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/data/packetentity/PacketEntitySizeable.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.data.packetentity; 2 | 3 | import ac.grim.grimac.player.GrimPlayer; 4 | import com.github.retrooper.packetevents.protocol.entity.type.EntityType; 5 | 6 | import java.util.UUID; 7 | 8 | public class PacketEntitySizeable extends PacketEntity { 9 | // It appears in modern versions (oldest tested was 1.16.5) 10 | // that no entity metadata is sent for a slime when {Size: 0} (which actually corresponds to size = 1, the smallest slime in vanilla) 11 | 12 | // Previously to support entity metadata being sent after spawn, we assumed max size of vanilla slime 13 | // as the default size; I'm not sure if we still need to do this. Will change behaviour if issues reported 14 | public int size = 1; 15 | 16 | public PacketEntitySizeable(GrimPlayer player, UUID uuid, EntityType type, double x, double y, double z) { 17 | super(player, uuid, type, x, y, z); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /fabric/src/main/java/ac/grim/grimac/platform/fabric/player/FabricOfflinePlatformPlayer.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.fabric.player; 2 | 3 | import ac.grim.grimac.platform.api.player.OfflinePlatformPlayer; 4 | import ac.grim.grimac.platform.fabric.GrimACFabricLoaderPlugin; 5 | import lombok.Getter; 6 | import lombok.RequiredArgsConstructor; 7 | import org.jetbrains.annotations.NotNull; 8 | 9 | import java.util.UUID; 10 | 11 | @RequiredArgsConstructor 12 | @Getter 13 | public class FabricOfflinePlatformPlayer implements OfflinePlatformPlayer { 14 | private final @NotNull UUID uniqueId; 15 | private final @NotNull String name; 16 | 17 | @Override 18 | public boolean isOnline() { 19 | return GrimACFabricLoaderPlugin.FABRIC_SERVER.getPlayerList().getPlayer(uniqueId) != null; 20 | } 21 | 22 | @Override 23 | public boolean equals(Object o) { 24 | return o instanceof OfflinePlatformPlayer player && this.getUniqueId().equals(player.getUniqueId()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/manager/player/features/FeatureBuilder.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.manager.player.features; 2 | 3 | import ac.grim.grimac.manager.player.features.types.GrimFeature; 4 | import ac.grim.grimac.utils.anticheat.LogUtil; 5 | import com.google.common.collect.ImmutableMap; 6 | 7 | import java.util.regex.Pattern; 8 | 9 | public class FeatureBuilder { 10 | 11 | private static final Pattern VALID = Pattern.compile("[a-zA-Z0-9_]{1,64}"); 12 | private final ImmutableMap.Builder mapBuilder = ImmutableMap.builder(); 13 | 14 | public void register(T feature) { 15 | if (!VALID.matcher(feature.getName()).matches()) { 16 | LogUtil.error("Invalid feature name: " + feature.getName()); 17 | return; 18 | } 19 | mapBuilder.put(feature.getName(), feature); 20 | } 21 | 22 | public ImmutableMap buildMap() { 23 | return mapBuilder.build(); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/item/ItemBehaviourRegistry.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.item; 2 | 3 | import com.github.retrooper.packetevents.protocol.item.type.ItemType; 4 | import com.github.retrooper.packetevents.protocol.item.type.ItemTypes; 5 | import org.jetbrains.annotations.NotNull; 6 | 7 | import java.util.Map; 8 | 9 | public class ItemBehaviourRegistry { 10 | 11 | private static final Map ITEM_MAPPING = Map.of( 12 | ItemTypes.GOAT_HORN, AlwaysUseItem.INSTANCE, 13 | ItemTypes.SHIELD, AlwaysUseItem.INSTANCE, 14 | ItemTypes.SPYGLASS, AlwaysUseItem.INSTANCE, 15 | ItemTypes.CROSSBOW, UnsupportedItem.INSTANCE, 16 | ItemTypes.BOW, UnsupportedItem.INSTANCE, 17 | ItemTypes.TRIDENT, TridentItem.INSTANCE 18 | ); 19 | 20 | public static @NotNull ItemBehaviour getItemBehaviour(ItemType type) { 21 | return ITEM_MAPPING.getOrDefault(type, ItemBehaviour.INSTANCE); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/manager/init/start/ExemptOnlinePlayersOnReload.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.manager.init.start; 2 | 3 | import ac.grim.grimac.GrimAPI; 4 | import ac.grim.grimac.platform.api.player.PlatformPlayer; 5 | import com.github.retrooper.packetevents.PacketEvents; 6 | import com.github.retrooper.packetevents.protocol.player.User; 7 | 8 | public class ExemptOnlinePlayersOnReload implements StartableInitable { 9 | 10 | // Runs on plugin startup adding all online players to exempt list; will be empty unless reload 11 | // This essentially exists to stop you from shooting yourself in the foot by being stupid and using /reload 12 | @Override 13 | public void start() { 14 | for (PlatformPlayer player : GrimAPI.INSTANCE.getPlatformPlayerFactory().getOnlinePlayers()) { 15 | User user = PacketEvents.getAPI().getPlayerManager().getUser(player.getNative()); 16 | GrimAPI.INSTANCE.getPlayerDataManager().exemptUsers.add(user); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/manager/LastInstanceManager.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.manager; 2 | 3 | import ac.grim.grimac.checks.Check; 4 | import ac.grim.grimac.checks.type.PostPredictionCheck; 5 | import ac.grim.grimac.player.GrimPlayer; 6 | import ac.grim.grimac.utils.anticheat.update.PredictionComplete; 7 | import ac.grim.grimac.utils.data.LastInstance; 8 | 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | 12 | public class LastInstanceManager extends Check implements PostPredictionCheck { 13 | private final List instances = new ArrayList<>(); 14 | 15 | public LastInstanceManager(GrimPlayer player) { 16 | super(player); 17 | } 18 | 19 | public void addInstance(LastInstance instance) { 20 | instances.add(instance); 21 | } 22 | 23 | @Override 24 | public void onPredictionComplete(final PredictionComplete predictionComplete) { 25 | for (LastInstance instance : instances) { 26 | instance.tick(); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/platform/api/command/AbstractPlayerSelectorParser.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.api.command; 2 | 3 | import org.incendo.cloud.context.CommandContext; 4 | import org.incendo.cloud.parser.ParserDescriptor; 5 | 6 | import java.util.concurrent.CompletableFuture; 7 | 8 | public abstract class AbstractPlayerSelectorParser { 9 | 10 | public abstract ParserDescriptor descriptor(); 11 | 12 | protected abstract ParserDescriptor getPlatformSpecificDescriptor(); 13 | 14 | protected abstract CompletableFuture adaptToCommonSelector(CommandContext context, Object platformSpecificSelector); 15 | 16 | // Helper method to create the ParserDescriptor 17 | protected ParserDescriptor createDescriptor() { 18 | return ParserDescriptor.of( 19 | getPlatformSpecificDescriptor().parser().mapSuccess(this::adaptToCommonSelector), 20 | PlayerSelector.class 21 | ); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/data/packetentity/PacketEntityTrackXRot.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.data.packetentity; 2 | 3 | import ac.grim.grimac.player.GrimPlayer; 4 | import com.github.retrooper.packetevents.protocol.entity.type.EntityType; 5 | 6 | import java.util.UUID; 7 | 8 | // We use simple interpolation here to be "close enough" 9 | public class PacketEntityTrackXRot extends PacketEntity { 10 | public float packetYaw; 11 | public float interpYaw; 12 | public int steps = 0; 13 | 14 | public PacketEntityTrackXRot(GrimPlayer player, UUID uuid, EntityType type, double x, double y, double z, float xRot) { 15 | super(player, uuid, type, x, y, z); 16 | this.packetYaw = xRot; 17 | this.interpYaw = xRot; 18 | } 19 | 20 | @Override 21 | public void onMovement(boolean highBound) { 22 | super.onMovement(highBound); 23 | if (steps > 0) { 24 | interpYaw = interpYaw + ((packetYaw - interpYaw) / steps--); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/predictionengine/movementtick/MovementTickerCamel.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.predictionengine.movementtick; 2 | 3 | import ac.grim.grimac.player.GrimPlayer; 4 | import ac.grim.grimac.utils.data.packetentity.PacketEntityCamel; 5 | 6 | public class MovementTickerCamel extends MovementTickerHorse { 7 | 8 | public MovementTickerCamel(GrimPlayer player) { 9 | super(player); 10 | } 11 | 12 | @Override 13 | public float getExtraSpeed() { 14 | PacketEntityCamel camel = (PacketEntityCamel) player.compensatedEntities.self.getRiding(); 15 | 16 | // If jumping... speed wouldn't apply after this 17 | // This engine was not designed for this edge case 18 | final boolean wantsToJump = player.vehicleData.horseJump > 0.0F && !player.vehicleData.horseJumping && player.lastOnGround; 19 | if (wantsToJump) return 0; 20 | 21 | return player.isSprinting && player.vehicleData.camelDashCooldown <= 0 && !camel.dashing ? 0.1f : 0.0f; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/anticheat/update/RotationUpdate.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.anticheat.update; 2 | 3 | import ac.grim.grimac.checks.impl.aim.processor.AimProcessor; 4 | import ac.grim.grimac.utils.data.HeadRotation; 5 | import lombok.Getter; 6 | import lombok.Setter; 7 | 8 | @Getter 9 | @Setter 10 | public final class RotationUpdate { 11 | private HeadRotation from, to; 12 | private AimProcessor processor; 13 | private float deltaYRot, deltaXRot; 14 | private boolean isCinematic; 15 | private double sensitivityX, sensitivityY; 16 | 17 | public RotationUpdate(HeadRotation from, HeadRotation to, float deltaXRot, float deltaYRot) { 18 | this.from = from; 19 | this.to = to; 20 | this.deltaXRot = deltaXRot; 21 | this.deltaYRot = deltaYRot; 22 | } 23 | 24 | public float getDeltaXRotABS() { 25 | return Math.abs(deltaXRot); 26 | } 27 | 28 | public float getDeltaYRotABS() { 29 | return Math.abs(deltaYRot); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/command/requirements/PlayerSenderRequirement.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.command.requirements; 2 | 3 | import ac.grim.grimac.command.SenderRequirement; 4 | import ac.grim.grimac.platform.api.sender.Sender; 5 | import ac.grim.grimac.utils.anticheat.MessageUtil; 6 | import net.kyori.adventure.text.Component; 7 | import org.incendo.cloud.context.CommandContext; 8 | import org.jetbrains.annotations.NotNull; 9 | 10 | public final class PlayerSenderRequirement implements SenderRequirement { 11 | 12 | public static final PlayerSenderRequirement PLAYER_SENDER_REQUIREMENT = new PlayerSenderRequirement(); 13 | 14 | @Override 15 | public @NotNull Component errorMessage(Sender sender) { 16 | return MessageUtil.getParsedComponent(sender, "run-as-player", "%prefix% &cThis command can only be used by players!"); 17 | } 18 | 19 | @Override 20 | public boolean evaluateRequirement(@NotNull CommandContext commandContext) { 21 | return commandContext.sender().isPlayer(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/checks/impl/scaffolding/InvalidPlaceA.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.checks.impl.scaffolding; 2 | 3 | import ac.grim.grimac.checks.CheckData; 4 | import ac.grim.grimac.checks.type.BlockPlaceCheck; 5 | import ac.grim.grimac.player.GrimPlayer; 6 | import ac.grim.grimac.utils.anticheat.update.BlockPlace; 7 | import com.github.retrooper.packetevents.util.Vector3f; 8 | 9 | @CheckData(name = "InvalidPlaceA", description = "Sent invalid cursor position") 10 | public class InvalidPlaceA extends BlockPlaceCheck { 11 | public InvalidPlaceA(GrimPlayer player) { 12 | super(player); 13 | } 14 | 15 | @Override 16 | public void onBlockPlace(final BlockPlace place) { 17 | Vector3f cursor = place.cursor; 18 | if (cursor == null) return; 19 | if (!Float.isFinite(cursor.x) || !Float.isFinite(cursor.y) || !Float.isFinite(cursor.z)) { 20 | if (flagAndAlert() && shouldModifyPackets() && shouldCancel()) { 21 | place.resync(); 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/data/VelocityData.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.data; 2 | 3 | import ac.grim.grimac.utils.math.Vector3dm; 4 | 5 | public class VelocityData { 6 | public final Vector3dm vector; 7 | public final int entityID; 8 | public final int transaction; 9 | public double offset = Integer.MAX_VALUE; 10 | public final boolean isSetback; 11 | 12 | public VelocityData(int entityID, int transaction, boolean isSetback, Vector3dm vector) { 13 | this.entityID = entityID; 14 | this.vector = vector; 15 | this.transaction = transaction; 16 | this.isSetback = isSetback; 17 | } 18 | 19 | // First bread last tick -> Required this tick = don't require kb twice 20 | public VelocityData(int entityID, int transaction, Vector3dm vector, boolean isSetback, double offset) { 21 | this.entityID = entityID; 22 | this.vector = vector; 23 | this.transaction = transaction; 24 | this.isSetback = isSetback; 25 | this.offset = offset; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/nmsutil/FluidFallingAdjustedMovement.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.nmsutil; 2 | 3 | import ac.grim.grimac.player.GrimPlayer; 4 | import ac.grim.grimac.utils.math.Vector3dm; 5 | import com.github.retrooper.packetevents.protocol.player.ClientVersion; 6 | import lombok.experimental.UtilityClass; 7 | import org.jetbrains.annotations.NotNull; 8 | 9 | @UtilityClass 10 | public class FluidFallingAdjustedMovement { 11 | public static Vector3dm getFluidFallingAdjustedMovement(@NotNull GrimPlayer player, double gravity, boolean isFalling, Vector3dm velocity) { 12 | if (!player.hasGravity || player.isSprinting) return velocity; 13 | isFalling = player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_14) ? isFalling : velocity.getY() < 0; 14 | double newY = isFalling && Math.abs(velocity.getY() - 0.005) >= 0.003 && Math.abs(velocity.getY() - gravity / 16.0) < 0.003 ? -0.003 : velocity.getY() - gravity / 16.0; 15 | return new Vector3dm(velocity.getX(), newY, velocity.getZ()); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /fabric/mc1161/src/main/java/ac/grim/grimac/platform/fabric/mc1161/Fabric1140PlatformServer.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.fabric.mc1161; 2 | 3 | import ac.grim.grimac.platform.api.sender.Sender; 4 | import ac.grim.grimac.platform.fabric.AbstractFabricPlatformServer; 5 | import ac.grim.grimac.platform.fabric.GrimACFabricLoaderPlugin; 6 | import net.minecraft.commands.CommandSourceStack; 7 | 8 | public class Fabric1140PlatformServer extends AbstractFabricPlatformServer { 9 | 10 | @Override 11 | public void dispatchCommand(Sender sender, String command) { 12 | CommandSourceStack commandSource = GrimACFabricLoaderPlugin.LOADER.getFabricSenderFactory().reverse(sender); 13 | GrimACFabricLoaderPlugin.FABRIC_SERVER.getCommands().performCommand(commandSource, command); 14 | } 15 | 16 | // TODO (Cross-platform) implement proper bukkit equivalent for getting TPS over time 17 | @Override 18 | public double getTPS() { 19 | return Math.min(1000.0 / GrimACFabricLoaderPlugin.FABRIC_SERVER.getAverageTickTime(), 20.0); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /fabric/src/main/resources/fabric.mod.json: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": 1, 3 | "id": "grimac", 4 | "version": "${version}", 5 | "name": "GrimAC", 6 | "description": "Libre simulation anticheat designed for 1.21 with 1.8-1.21 support, powered by PacketEvents 2.0.", 7 | "authors": [ 8 | "GrimAC" 9 | ], 10 | "license": "GPLv3", 11 | "environment": "server", 12 | "entrypoints": { 13 | "main": [ 14 | "ac.grim.grimac.platform.fabric.GrimACFabricEntryPoint" 15 | ], 16 | "preLaunch": [ 17 | "ac.grim.grimac.platform.fabric.GrimACFabricEntryPoint" 18 | ] 19 | }, 20 | "mixins": [ 21 | "grimac.mixins.json" 22 | ], 23 | "custom": { 24 | "loom:injected_interfaces": { 25 | "net/minecraft/world/level/Level": [ 26 | "ac/grim/grimac/platform/api/world/PlatformWorld" 27 | ] 28 | } 29 | }, 30 | "accessWidener": "grimac.accesswidener", 31 | "depends": { 32 | "fabricloader": "\u003e\u003d0.16", 33 | "fabric-lifecycle-events-v1": "*", 34 | "cloud": "*", 35 | "packetevents": "*" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/manager/violationdatabase/postgresql/PostgresqlDialect.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.manager.violationdatabase.postgresql; 2 | 3 | import ac.grim.grimac.manager.violationdatabase.DatabaseDialect; 4 | 5 | public class PostgresqlDialect implements DatabaseDialect { 6 | 7 | @Override 8 | public String getUuidColumnType() { 9 | return "UUID"; 10 | } 11 | 12 | @Override 13 | public String getAutoIncrementPrimaryKeySyntax() { 14 | return "BIGSERIAL PRIMARY KEY"; 15 | } 16 | 17 | @Override 18 | public String getInsertOrIgnoreSyntax(String tableName, String columnNames) { 19 | return "INSERT INTO " + tableName + " (" + columnNames + ") VALUES (?) ON CONFLICT DO NOTHING"; 20 | } 21 | 22 | @Override 23 | public String getUniqueConstraintViolationSQLState() { 24 | return "23505"; // Postgresql duplicate key error 25 | } 26 | 27 | @Override 28 | public int getUniqueConstraintViolationErrorCode() { 29 | return 0; // Postgresql is not using numbers 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/item/TridentItem.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.item; 2 | 3 | import ac.grim.grimac.player.GrimPlayer; 4 | import ac.grim.grimac.utils.latency.CompensatedWorld; 5 | import com.github.retrooper.packetevents.protocol.item.ItemStack; 6 | import com.github.retrooper.packetevents.protocol.item.enchantment.type.EnchantmentTypes; 7 | import com.github.retrooper.packetevents.protocol.player.InteractionHand; 8 | 9 | public class TridentItem extends ItemBehaviour { 10 | 11 | public static final TridentItem INSTANCE = new TridentItem(); 12 | 13 | @Override 14 | public boolean canUse(ItemStack item, CompensatedWorld world, GrimPlayer player, InteractionHand hand) { 15 | if (this.nextDamageWillBreak(item)) { 16 | return false; 17 | } 18 | 19 | return item.getEnchantmentLevel(EnchantmentTypes.RIPTIDE) <= 0; 20 | } 21 | 22 | private boolean nextDamageWillBreak(ItemStack item) { 23 | return item.isDamageableItem() && item.getDamageValue() >= item.getMaxDamage() - 1; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/events/GrimExtensionResolver.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.events; 2 | 3 | import ac.grim.grimac.api.plugin.GrimPlugin; 4 | import org.jetbrains.annotations.NotNull; 5 | import org.jetbrains.annotations.Nullable; 6 | 7 | 8 | /** 9 | * A functional interface responsible for attempting to resolve a generic context object 10 | * into a {@link GrimPlugin}. 11 | *

12 | * Implementations of this are provided by the core GrimAC platform module (e.g., for Bukkit, Fabric) 13 | * and registered with the central {@link GrimPluginManager}. 14 | */ 15 | @FunctionalInterface 16 | public interface GrimExtensionResolver { 17 | 18 | /** 19 | * Attempts to resolve the given context object into a GrimPlugin. 20 | * 21 | * @param context The context object to resolve (e.g., a Bukkit Plugin, a Plugin Class, a Fabric Mod). 22 | * @return An Optional containing the resolved GrimPlugin if this resolver supports the context type, 23 | * otherwise an empty Optional. 24 | */ 25 | @Nullable GrimPlugin resolve(@NotNull Object context); 26 | 27 | } 28 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/checks/impl/sprint/SprintF.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.checks.impl.sprint; 2 | 3 | import ac.grim.grimac.checks.Check; 4 | import ac.grim.grimac.checks.CheckData; 5 | import ac.grim.grimac.checks.type.PostPredictionCheck; 6 | import ac.grim.grimac.player.GrimPlayer; 7 | import ac.grim.grimac.utils.anticheat.update.PredictionComplete; 8 | import com.github.retrooper.packetevents.protocol.player.ClientVersion; 9 | 10 | @CheckData(name = "SprintF", description = "Sprinting while gliding", experimental = true) 11 | public class SprintF extends Check implements PostPredictionCheck { 12 | public SprintF(GrimPlayer player) { 13 | super(player); 14 | } 15 | 16 | @Override 17 | public void onPredictionComplete(final PredictionComplete predictionComplete) { 18 | if (player.wasGliding && player.isGliding && player.getClientVersion() == ClientVersion.V_1_21_4) { 19 | if (player.isSprinting) { 20 | flagAndAlertWithSetback(); 21 | } else { 22 | reward(); 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/manager/violationdatabase/mysql/MySQLDialect.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.manager.violationdatabase.mysql; 2 | 3 | import ac.grim.grimac.manager.violationdatabase.DatabaseDialect; 4 | 5 | public class MySQLDialect implements DatabaseDialect { 6 | 7 | @Override 8 | public String getUuidColumnType() { 9 | return "BINARY(16)"; 10 | } 11 | 12 | @Override 13 | public String getAutoIncrementPrimaryKeySyntax() { 14 | return "BIGINT NOT NULL PRIMARY KEY AUTO_INCREMENT"; 15 | } 16 | 17 | @Override 18 | public String getInsertOrIgnoreSyntax(String tableName, String columnNames) { 19 | return "INSERT IGNORE INTO " + tableName + " (" + columnNames + ") VALUES (?)"; 20 | } 21 | 22 | @Override 23 | public String getUniqueConstraintViolationSQLState() { 24 | return "23000"; // Generic SQLSTATE for integrity constraint violation 25 | } 26 | 27 | @Override 28 | public int getUniqueConstraintViolationErrorCode() { 29 | return 1062; // MySQL specific error code for Duplicate entry 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/manager/violationdatabase/sqlite/SQLiteDialect.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.manager.violationdatabase.sqlite; 2 | 3 | import ac.grim.grimac.manager.violationdatabase.DatabaseDialect; 4 | 5 | public class SQLiteDialect implements DatabaseDialect { 6 | 7 | @Override 8 | public String getUuidColumnType() { 9 | return "BLOB"; 10 | } 11 | 12 | @Override 13 | public String getAutoIncrementPrimaryKeySyntax() { 14 | return "INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT"; 15 | } 16 | 17 | @Override 18 | public String getInsertOrIgnoreSyntax(String tableName, String columnNames) { 19 | return "INSERT OR IGNORE INTO " + tableName + " (" + columnNames + ") VALUES (?)"; 20 | } 21 | 22 | @Override 23 | public String getUniqueConstraintViolationSQLState() { 24 | return "23000"; // Generic SQLSTATE for integrity constraint violation 25 | } 26 | 27 | @Override 28 | public int getUniqueConstraintViolationErrorCode() { 29 | return 19; // SQLite specific error code for Constraint violation 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/platform/api/scheduler/TaskHandle.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of packetevents - https://github.com/retrooper/packetevents 3 | * Copyright (C) 2024 retrooper and contributors 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | package ac.grim.grimac.platform.api.scheduler; 20 | 21 | public interface TaskHandle { 22 | 23 | boolean isSync(); 24 | 25 | boolean isCancelled(); 26 | 27 | void cancel(); 28 | } 29 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/common/PropertiesUtil.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.common; 2 | 3 | import ac.grim.grimac.utils.anticheat.LogUtil; 4 | import lombok.experimental.UtilityClass; 5 | 6 | import java.io.InputStream; 7 | import java.util.Properties; 8 | 9 | @UtilityClass 10 | public class PropertiesUtil { 11 | 12 | public static Properties readProperties(Class clazz, String path) { 13 | final Properties properties = new Properties(); 14 | try (InputStream inputStream = clazz.getClassLoader().getResourceAsStream(path)) { 15 | if (inputStream != null) { 16 | properties.load(inputStream); 17 | } else { 18 | throw new RuntimeException("Cannot find properties file: " + path); 19 | } 20 | } catch (Exception e) { 21 | LogUtil.error(e); 22 | } 23 | return properties; 24 | } 25 | 26 | public static String getPropertyOrElse(Properties properties, String key, String defaultValue) { 27 | return properties.getProperty(key, defaultValue); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/inventory/InventoryStorage.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.inventory; 2 | 3 | import com.github.retrooper.packetevents.protocol.item.ItemStack; 4 | import lombok.Getter; 5 | 6 | public class InventoryStorage { 7 | protected final ItemStack[] items; 8 | @Getter 9 | private final int size; 10 | 11 | public InventoryStorage(int size) { 12 | this.items = new ItemStack[size]; 13 | this.size = size; 14 | 15 | for (int i = 0; i < size; i++) { 16 | items[i] = ItemStack.EMPTY; 17 | } 18 | } 19 | 20 | public void setItem(int item, ItemStack stack) { 21 | items[item] = stack == null ? ItemStack.EMPTY : stack; 22 | } 23 | 24 | public ItemStack getItem(int index) { 25 | return items[index]; 26 | } 27 | 28 | public ItemStack removeItem(int slot, int amount) { 29 | return slot >= 0 && slot < items.length && !items[slot].isEmpty() && amount > 0 ? items[slot].split(amount) : ItemStack.EMPTY; 30 | } 31 | 32 | public int getMaxStackSize() { 33 | return 64; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /fabric/src/main/java/ac/grim/grimac/platform/fabric/initables/FabricTickEndEvent.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.fabric.initables; 2 | 3 | import ac.grim.grimac.GrimAPI; 4 | import ac.grim.grimac.manager.init.start.AbstractTickEndEvent; 5 | import ac.grim.grimac.player.GrimPlayer; 6 | import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents; 7 | import net.minecraft.server.MinecraftServer; 8 | 9 | public class FabricTickEndEvent extends AbstractTickEndEvent { 10 | 11 | @Override 12 | public void start() { 13 | if (!super.shouldInjectEndTick()) { 14 | return; 15 | } 16 | 17 | // Register the end-of-tick callback 18 | ServerTickEvents.END_SERVER_TICK.register(this::onEndServerTick); 19 | } 20 | 21 | private void onEndServerTick(MinecraftServer server) { 22 | tickAllPlayers(); 23 | } 24 | 25 | private void tickAllPlayers() { 26 | for (GrimPlayer player : GrimAPI.INSTANCE.getPlayerDataManager().getEntries()) { 27 | if (player.disableGrim) continue; 28 | super.onEndOfTick(player); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/checks/impl/vehicle/VehicleB.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.checks.impl.vehicle; 2 | 3 | import ac.grim.grimac.checks.Check; 4 | import ac.grim.grimac.checks.CheckData; 5 | import ac.grim.grimac.checks.type.PacketCheck; 6 | import ac.grim.grimac.player.GrimPlayer; 7 | import com.github.retrooper.packetevents.event.PacketReceiveEvent; 8 | import com.github.retrooper.packetevents.protocol.packettype.PacketType; 9 | 10 | @CheckData(name = "VehicleB", description = "Claimed to be in a vehicle while not in a vehicle") 11 | public class VehicleB extends Check implements PacketCheck { 12 | public VehicleB(GrimPlayer player) { 13 | super(player); 14 | } 15 | 16 | @Override 17 | public void onPacketReceive(PacketReceiveEvent event) { 18 | if (event.getPacketType() == PacketType.Play.Client.STEER_VEHICLE) { 19 | if (!player.inVehicle()) { 20 | if (flagAndAlert() && shouldModifyPackets()) { 21 | event.setCancelled(true); 22 | player.onPacketCancel(); 23 | } 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/platform/api/manager/CommandAdapter.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.api.manager; 2 | 3 | import ac.grim.grimac.platform.api.command.PlayerSelector; 4 | import ac.grim.grimac.platform.api.sender.Sender; 5 | import org.incendo.cloud.parser.ParserDescriptor; 6 | import org.incendo.cloud.suggestion.SuggestionProvider; 7 | 8 | /** 9 | * Acts as a bridge between platform-agnostic command definitions 10 | * and platform-specific parsers, suggestion providers, etc. 11 | */ 12 | public interface CommandAdapter { 13 | 14 | /** 15 | * Provides a parser descriptor for a single player selector (@p, player name). 16 | * 17 | * @return The parser descriptor. 18 | */ 19 | ParserDescriptor singlePlayerSelectorParser(); 20 | 21 | /** 22 | * Provides a suggestion provider that lists all online players. 23 | *

24 | * Platform-specific implementations should handle things like 25 | * vanished players. 26 | * 27 | * @return The suggestion provider. 28 | */ 29 | SuggestionProvider onlinePlayerSuggestions(); 30 | } 31 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ac/grim/grimac/platform/bukkit/player/BukkitOfflinePlatformPlayer.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.bukkit.player; 2 | 3 | import ac.grim.grimac.platform.api.player.OfflinePlatformPlayer; 4 | import lombok.RequiredArgsConstructor; 5 | import org.bukkit.OfflinePlayer; 6 | import org.jetbrains.annotations.NotNull; 7 | 8 | import java.util.Objects; 9 | import java.util.UUID; 10 | 11 | @RequiredArgsConstructor 12 | public class BukkitOfflinePlatformPlayer implements OfflinePlatformPlayer { 13 | private final OfflinePlayer offlinePlayer; 14 | 15 | @Override 16 | public boolean isOnline() { 17 | return offlinePlayer.isOnline(); 18 | } 19 | 20 | @Override 21 | public @NotNull String getName() { 22 | return Objects.requireNonNull(offlinePlayer.getName()); 23 | } 24 | 25 | @Override 26 | public @NotNull UUID getUniqueId() { 27 | return offlinePlayer.getUniqueId(); 28 | } 29 | 30 | @Override 31 | public boolean equals(Object o) { 32 | return o instanceof OfflinePlatformPlayer player && this.getUniqueId().equals(player.getUniqueId()); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/checks/impl/badpackets/BadPacketsZ.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.checks.impl.badpackets; 2 | 3 | import ac.grim.grimac.checks.Check; 4 | import ac.grim.grimac.checks.CheckData; 5 | import ac.grim.grimac.checks.type.PacketCheck; 6 | import ac.grim.grimac.player.GrimPlayer; 7 | import com.github.retrooper.packetevents.event.PacketReceiveEvent; 8 | import com.github.retrooper.packetevents.protocol.packettype.PacketType; 9 | 10 | @CheckData(name = "BadPacketsZ", experimental = true) 11 | public class BadPacketsZ extends Check implements PacketCheck { 12 | private boolean sent; 13 | 14 | public BadPacketsZ(GrimPlayer player) { 15 | super(player); 16 | } 17 | 18 | @Override 19 | public void onPacketReceive(PacketReceiveEvent event) { 20 | if (event.getPacketType() == PacketType.Play.Client.CLIENT_TICK_END) { 21 | sent = false; 22 | } 23 | 24 | if (event.getPacketType() == PacketType.Play.Client.PLAYER_INPUT) { 25 | if (sent) { 26 | flagAndAlert(); 27 | } 28 | 29 | sent = true; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/data/SetBackData.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.data; 2 | 3 | import ac.grim.grimac.utils.math.Vector3dm; 4 | import lombok.Getter; 5 | import lombok.Setter; 6 | import lombok.ToString; 7 | 8 | @Getter 9 | @Setter 10 | @ToString 11 | public class SetBackData { 12 | private final TeleportData teleportData; 13 | private final float xRot, yRot; 14 | private final Vector3dm velocity; 15 | private final boolean vehicle; 16 | private boolean isComplete = false; 17 | // TODO: Rethink when we block movements for teleports, perhaps after 10 ticks or 5 blocks? 18 | private boolean isPlugin; 19 | private int ticksComplete = 0; 20 | 21 | public SetBackData(TeleportData teleportData, float xRot, float yRot, Vector3dm velocity, boolean vehicle, boolean isPlugin) { 22 | this.teleportData = teleportData; 23 | this.xRot = xRot; 24 | this.yRot = yRot; 25 | this.velocity = velocity; 26 | this.vehicle = vehicle; 27 | this.isPlugin = isPlugin; 28 | } 29 | 30 | public void tick() { 31 | if (isComplete) ticksComplete++; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/math/LegacyFastMath.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.math; 2 | 3 | import lombok.experimental.UtilityClass; 4 | import org.jetbrains.annotations.Contract; 5 | 6 | // My previous rant was wrong, we have 4 fastmath versions. what the fuck optifine. 7 | @UtilityClass 8 | public class LegacyFastMath { 9 | private static final float[] SIN_TABLE_FAST = new float[4096]; 10 | 11 | static { 12 | for (int i = 0; i < 4096; ++i) { 13 | SIN_TABLE_FAST[i] = (float) Math.sin(((float) i + 0.5f) / 4096f * ((float) Math.PI * 2f)); 14 | } 15 | 16 | for (int i = 0; i < 360; i += 90) { 17 | SIN_TABLE_FAST[(int) ((float) i * 11.377778f) & 4095] = (float) Math.sin(GrimMath.radians((float) i)); 18 | } 19 | } 20 | 21 | @Contract(pure = true) 22 | public static float sin(float value) { 23 | return SIN_TABLE_FAST[(int) (value * 651.8986f) & 4095]; 24 | } 25 | 26 | @Contract(pure = true) 27 | public static float cos(float value) { 28 | return SIN_TABLE_FAST[(int) ((value + ((float) Math.PI / 2f)) * 651.8986f) & 4095]; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/data/VehicleData.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.data; 2 | 3 | import ac.grim.grimac.utils.enums.BoatEntityStatus; 4 | import com.github.retrooper.packetevents.util.Vector3d; 5 | 6 | import java.util.concurrent.ConcurrentLinkedQueue; 7 | 8 | public class VehicleData { 9 | public boolean boatUnderwater = false; 10 | public double lastYd; 11 | public double midTickY; 12 | public float landFriction; 13 | public BoatEntityStatus status; 14 | public BoatEntityStatus oldStatus; 15 | public double waterLevel; 16 | public float deltaRotation; 17 | public float nextVehicleHorizontal = 0f; 18 | public float nextVehicleForward = 0f; 19 | public float vehicleHorizontal = 0f; 20 | public float vehicleForward = 0f; 21 | public boolean lastDummy = false; 22 | public boolean wasVehicleSwitch = false; 23 | public final ConcurrentLinkedQueue> vehicleTeleports = new ConcurrentLinkedQueue<>(); 24 | public float nextHorseJump = 0; 25 | public float horseJump = 0; 26 | public boolean horseJumping = false; 27 | public int camelDashCooldown; 28 | } 29 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ac/grim/grimac/platform/bukkit/manager/BukkitMessagePlaceHolderManager.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.bukkit.manager; 2 | 3 | import ac.grim.grimac.platform.api.manager.MessagePlaceHolderManager; 4 | import ac.grim.grimac.platform.api.player.PlatformPlayer; 5 | import ac.grim.grimac.platform.bukkit.player.BukkitPlatformPlayer; 6 | import com.github.retrooper.packetevents.util.reflection.Reflection; 7 | import me.clip.placeholderapi.PlaceholderAPI; 8 | import org.jetbrains.annotations.NotNull; 9 | import org.jetbrains.annotations.Nullable; 10 | 11 | public class BukkitMessagePlaceHolderManager implements MessagePlaceHolderManager { 12 | public static final boolean hasPlaceholderAPI = Reflection.getClassByNameWithoutException("me.clip.placeholderapi.PlaceholderAPI") != null; 13 | 14 | @Override 15 | public @NotNull String replacePlaceholders(@Nullable PlatformPlayer player, @NotNull String string) { 16 | if (!hasPlaceholderAPI) return string; 17 | return PlaceholderAPI.setPlaceholders(player instanceof BukkitPlatformPlayer bukkitPlatformPlayer ? bukkitPlatformPlayer.getBukkitPlayer() : null, string); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/checks/impl/multiactions/MultiActionsD.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.checks.impl.multiactions; 2 | 3 | import ac.grim.grimac.checks.Check; 4 | import ac.grim.grimac.checks.CheckData; 5 | import ac.grim.grimac.checks.type.PacketCheck; 6 | import ac.grim.grimac.player.GrimPlayer; 7 | import com.github.retrooper.packetevents.event.PacketReceiveEvent; 8 | import com.github.retrooper.packetevents.protocol.packettype.PacketType; 9 | 10 | @CheckData(name = "MultiActionsD", description = "Closed inventory while moving") 11 | public class MultiActionsD extends Check implements PacketCheck { 12 | public MultiActionsD(GrimPlayer player) { 13 | super(player); 14 | } 15 | 16 | @Override 17 | public void onPacketReceive(PacketReceiveEvent event) { 18 | if (event.getPacketType() == PacketType.Play.Client.CLOSE_WINDOW) { 19 | String verbose = MultiActionsC.getVerbose(player); 20 | if (!verbose.isEmpty() && flagAndAlert(verbose) && shouldModifyPackets()) { 21 | event.setCancelled(true); 22 | player.onPacketCancel(); 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/predictionengine/predictions/rideable/PredictionEngineRideableLava.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.predictionengine.predictions.rideable; 2 | 3 | import ac.grim.grimac.player.GrimPlayer; 4 | import ac.grim.grimac.predictionengine.predictions.PredictionEngineLava; 5 | import ac.grim.grimac.utils.data.VectorData; 6 | import ac.grim.grimac.utils.math.Vector3dm; 7 | import lombok.RequiredArgsConstructor; 8 | 9 | import java.util.List; 10 | import java.util.Set; 11 | 12 | @RequiredArgsConstructor 13 | public class PredictionEngineRideableLava extends PredictionEngineLava { 14 | private final Vector3dm movementVector; 15 | 16 | @Override 17 | public void addJumpsToPossibilities(GrimPlayer player, Set existingVelocities) { 18 | PredictionEngineRideableUtils.handleJumps(player, existingVelocities); 19 | } 20 | 21 | @Override 22 | public List applyInputsToVelocityPossibilities(GrimPlayer player, Set possibleVectors, float speed) { 23 | return PredictionEngineRideableUtils.applyInputsToVelocityPossibilities(movementVector, player, possibleVectors, speed); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/manager/player/features/types/ExemptElytraFeature.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.manager.player.features.types; 2 | 3 | import ac.grim.grimac.api.config.ConfigManager; 4 | import ac.grim.grimac.api.feature.FeatureState; 5 | import ac.grim.grimac.player.GrimPlayer; 6 | 7 | public class ExemptElytraFeature implements GrimFeature { 8 | 9 | @Override 10 | public String getName() { 11 | return "ExemptElytra"; 12 | } 13 | 14 | @Override 15 | public void setState(GrimPlayer player, ConfigManager config, FeatureState state) { 16 | switch (state) { 17 | case ENABLED -> player.setExemptElytra(true); 18 | case DISABLED -> player.setExemptElytra(false); 19 | default -> player.setExemptElytra(isEnabledInConfig(player, config)); 20 | } 21 | } 22 | 23 | @Override 24 | public boolean isEnabled(GrimPlayer player) { 25 | return player.isExemptElytra(); 26 | } 27 | 28 | @Override 29 | public boolean isEnabledInConfig(GrimPlayer player, ConfigManager config) { 30 | return config.getBooleanElse("exempt-elytra", false); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/predictionengine/predictions/rideable/PredictionEngineRideableWater.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.predictionengine.predictions.rideable; 2 | 3 | import ac.grim.grimac.player.GrimPlayer; 4 | import ac.grim.grimac.predictionengine.predictions.PredictionEngineWater; 5 | import ac.grim.grimac.utils.data.VectorData; 6 | import ac.grim.grimac.utils.math.Vector3dm; 7 | import lombok.RequiredArgsConstructor; 8 | 9 | import java.util.List; 10 | import java.util.Set; 11 | 12 | @RequiredArgsConstructor 13 | public class PredictionEngineRideableWater extends PredictionEngineWater { 14 | private final Vector3dm movementVector; 15 | 16 | @Override 17 | public void addJumpsToPossibilities(GrimPlayer player, Set existingVelocities) { 18 | PredictionEngineRideableUtils.handleJumps(player, existingVelocities); 19 | } 20 | 21 | @Override 22 | public List applyInputsToVelocityPossibilities(GrimPlayer player, Set possibleVectors, float speed) { 23 | return PredictionEngineRideableUtils.applyInputsToVelocityPossibilities(movementVector, player, possibleVectors, speed); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/checks/impl/badpackets/BadPacketsS.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.checks.impl.badpackets; 2 | 3 | import ac.grim.grimac.checks.Check; 4 | import ac.grim.grimac.checks.CheckData; 5 | import ac.grim.grimac.checks.type.PacketCheck; 6 | import ac.grim.grimac.player.GrimPlayer; 7 | import com.github.retrooper.packetevents.event.PacketReceiveEvent; 8 | import com.github.retrooper.packetevents.protocol.packettype.PacketType; 9 | import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientWindowConfirmation; 10 | 11 | @CheckData(name = "BadPacketsS") 12 | public class BadPacketsS extends Check implements PacketCheck { 13 | public BadPacketsS(GrimPlayer player) { 14 | super(player); 15 | } 16 | 17 | @Override 18 | public void onPacketReceive(PacketReceiveEvent event) { 19 | if (event.getPacketType() == PacketType.Play.Client.WINDOW_CONFIRMATION 20 | && !new WrapperPlayClientWindowConfirmation(event).isAccepted() 21 | && flagAndAlert() && shouldModifyPackets()) { 22 | event.setCancelled(true); 23 | player.onPacketCancel(); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/predictionengine/predictions/rideable/PredictionEngineRideableNormal.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.predictionengine.predictions.rideable; 2 | 3 | import ac.grim.grimac.player.GrimPlayer; 4 | import ac.grim.grimac.predictionengine.predictions.PredictionEngineNormal; 5 | import ac.grim.grimac.utils.data.VectorData; 6 | import ac.grim.grimac.utils.math.Vector3dm; 7 | import lombok.RequiredArgsConstructor; 8 | 9 | import java.util.List; 10 | import java.util.Set; 11 | 12 | @RequiredArgsConstructor 13 | public class PredictionEngineRideableNormal extends PredictionEngineNormal { 14 | private final Vector3dm movementVector; 15 | 16 | @Override 17 | public void addJumpsToPossibilities(GrimPlayer player, Set existingVelocities) { 18 | PredictionEngineRideableUtils.handleJumps(player, existingVelocities); 19 | } 20 | 21 | @Override 22 | public List applyInputsToVelocityPossibilities(GrimPlayer player, Set possibleVectors, float speed) { 23 | return PredictionEngineRideableUtils.applyInputsToVelocityPossibilities(movementVector, player, possibleVectors, speed); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/checks/impl/badpackets/BadPacketsK.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.checks.impl.badpackets; 2 | 3 | import ac.grim.grimac.checks.Check; 4 | import ac.grim.grimac.checks.CheckData; 5 | import ac.grim.grimac.checks.type.PacketCheck; 6 | import ac.grim.grimac.player.GrimPlayer; 7 | import com.github.retrooper.packetevents.event.PacketReceiveEvent; 8 | import com.github.retrooper.packetevents.protocol.packettype.PacketType; 9 | import com.github.retrooper.packetevents.protocol.player.GameMode; 10 | 11 | @CheckData(name = "BadPacketsK", description = "Sent spectate packets while not in spectator mode") 12 | public class BadPacketsK extends Check implements PacketCheck { 13 | public BadPacketsK(GrimPlayer player) { 14 | super(player); 15 | } 16 | 17 | @Override 18 | public void onPacketReceive(PacketReceiveEvent event) { 19 | if (event.getPacketType() == PacketType.Play.Client.SPECTATE 20 | && player.gamemode != GameMode.SPECTATOR 21 | && flagAndAlert() && shouldModifyPackets()) { 22 | event.setCancelled(true); 23 | player.onPacketCancel(); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/manager/init/start/TickRunner.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.manager.init.start; 2 | 3 | import ac.grim.grimac.GrimAPI; 4 | import ac.grim.grimac.platform.api.Platform; 5 | import ac.grim.grimac.utils.anticheat.LogUtil; 6 | 7 | public class TickRunner implements StartableInitable { 8 | @Override 9 | public void start() { 10 | LogUtil.info("Registering tick schedulers..."); 11 | 12 | if (GrimAPI.INSTANCE.getPlatform() == Platform.FOLIA) { 13 | GrimAPI.INSTANCE.getScheduler().getAsyncScheduler().runAtFixedRate(GrimAPI.INSTANCE.getGrimPlugin(), () -> { 14 | GrimAPI.INSTANCE.getTickManager().tickSync(); 15 | GrimAPI.INSTANCE.getTickManager().tickAsync(); 16 | }, 1, 1); 17 | } else { 18 | GrimAPI.INSTANCE.getScheduler().getGlobalRegionScheduler().runAtFixedRate(GrimAPI.INSTANCE.getGrimPlugin(), () -> GrimAPI.INSTANCE.getTickManager().tickSync(), 0, 1); 19 | GrimAPI.INSTANCE.getScheduler().getAsyncScheduler().runAtFixedRate(GrimAPI.INSTANCE.getGrimPlugin(), () -> GrimAPI.INSTANCE.getTickManager().tickAsync(), 0, 1); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/checks/impl/badpackets/BadPacketsB.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.checks.impl.badpackets; 2 | 3 | import ac.grim.grimac.checks.Check; 4 | import ac.grim.grimac.checks.CheckData; 5 | import ac.grim.grimac.checks.type.PacketCheck; 6 | import ac.grim.grimac.player.GrimPlayer; 7 | import com.github.retrooper.packetevents.event.PacketReceiveEvent; 8 | 9 | @CheckData(name = "BadPacketsB", description = "Ignored set rotation packet") 10 | public class BadPacketsB extends Check implements PacketCheck { 11 | 12 | public BadPacketsB(final GrimPlayer player) { 13 | super(player); 14 | } 15 | 16 | @Override 17 | public void onPacketReceive(PacketReceiveEvent event) { 18 | if (isTransaction(event.getPacketType())) { 19 | player.pendingRotations.removeIf(data -> { 20 | if (player.getLastTransactionReceived() > data.getTransaction()) { 21 | if (!data.isAccepted()) { 22 | flagAndAlert(); 23 | } 24 | 25 | return true; 26 | } 27 | 28 | return false; 29 | }); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/manager/player/features/types/ForceStuckSpeedFeature.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.manager.player.features.types; 2 | 3 | import ac.grim.grimac.api.config.ConfigManager; 4 | import ac.grim.grimac.api.feature.FeatureState; 5 | import ac.grim.grimac.player.GrimPlayer; 6 | 7 | public class ForceStuckSpeedFeature implements GrimFeature { 8 | 9 | @Override 10 | public String getName() { 11 | return "ForceStuckSpeed"; 12 | } 13 | 14 | @Override 15 | public void setState(GrimPlayer player, ConfigManager config, FeatureState state) { 16 | switch (state) { 17 | case ENABLED -> player.setForceStuckSpeed(true); 18 | case DISABLED -> player.setForceStuckSpeed(false); 19 | default -> player.setForceStuckSpeed(isEnabledInConfig(player, config)); 20 | } 21 | } 22 | 23 | @Override 24 | public boolean isEnabled(GrimPlayer player) { 25 | return player.isForceStuckSpeed(); 26 | } 27 | 28 | @Override 29 | public boolean isEnabledInConfig(GrimPlayer player, ConfigManager config) { 30 | return config.getBooleanElse("force-stuck-speed", true); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/predictionengine/predictions/rideable/PredictionEngineRideableWaterLegacy.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.predictionengine.predictions.rideable; 2 | 3 | import ac.grim.grimac.player.GrimPlayer; 4 | import ac.grim.grimac.predictionengine.predictions.PredictionEngineWaterLegacy; 5 | import ac.grim.grimac.utils.data.VectorData; 6 | import ac.grim.grimac.utils.math.Vector3dm; 7 | import lombok.RequiredArgsConstructor; 8 | 9 | import java.util.List; 10 | import java.util.Set; 11 | 12 | @RequiredArgsConstructor 13 | public class PredictionEngineRideableWaterLegacy extends PredictionEngineWaterLegacy { 14 | private final Vector3dm movementVector; 15 | 16 | @Override 17 | public void addJumpsToPossibilities(GrimPlayer player, Set existingVelocities) { 18 | PredictionEngineRideableUtils.handleJumps(player, existingVelocities); 19 | } 20 | 21 | @Override 22 | public List applyInputsToVelocityPossibilities(GrimPlayer player, Set possibleVectors, float speed) { 23 | return PredictionEngineRideableUtils.applyInputsToVelocityPossibilities(movementVector, player, possibleVectors, speed); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/collisions/datatypes/CollisionBox.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.collisions.datatypes; 2 | 3 | import com.github.retrooper.packetevents.protocol.world.BlockFace; 4 | 5 | import java.util.List; 6 | 7 | public interface CollisionBox { 8 | CollisionBox union(SimpleCollisionBox other); 9 | 10 | boolean isCollided(SimpleCollisionBox other); 11 | 12 | boolean isIntersected(SimpleCollisionBox other); 13 | 14 | CollisionBox copy(); 15 | 16 | CollisionBox offset(double x, double y, double z); 17 | 18 | void downCast(List list); 19 | 20 | /** 21 | * @param list A list that will contain all of the SimpleCollisionBoxes representing the CollisionBox. 22 | * @return int representing the size of elements in the array that belong to this downcast. 23 | * The contents of elements starting from list[size] and above are undefined and should not be iterated over. 24 | */ 25 | int downCast(SimpleCollisionBox[] list); 26 | 27 | boolean isNull(); 28 | 29 | boolean isFullBlock(); 30 | 31 | default boolean isSideFullBlock(BlockFace axis) { 32 | return isFullBlock(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /fabric/mc1205/src/main/java/ac/grim/grimac/platform/fabric/mc1205/Fabric1203PlatformServer.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.fabric.mc1205; 2 | 3 | import ac.grim.grimac.platform.api.sender.Sender; 4 | import ac.grim.grimac.platform.fabric.GrimACFabricLoaderPlugin; 5 | import ac.grim.grimac.platform.fabric.mc1194.Fabric1190PlatformServer; 6 | import net.minecraft.commands.CommandSourceStack; 7 | 8 | public class Fabric1203PlatformServer extends Fabric1190PlatformServer { 9 | 10 | // TODO (Cross-platform) implement proper bukkit equivalent for getting TPS over time 11 | @Override 12 | public double getTPS() { 13 | return Math.min(1000.0 / GrimACFabricLoaderPlugin.FABRIC_SERVER.getCurrentSmoothedTickTime(), GrimACFabricLoaderPlugin.FABRIC_SERVER.tickRateManager().tickrate()); 14 | } 15 | 16 | // Return type changed from int -> void in 1.20.3 17 | @Override 18 | public void dispatchCommand(Sender sender, String command) { 19 | CommandSourceStack commandSource = GrimACFabricLoaderPlugin.LOADER.getFabricSenderFactory().reverse(sender); 20 | GrimACFabricLoaderPlugin.FABRIC_SERVER.getCommands().performPrefixedCommand(commandSource, command); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/payload/Payload.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.payload; 2 | 3 | import com.github.retrooper.packetevents.netty.buffer.ByteBufHelper; 4 | import com.github.retrooper.packetevents.wrapper.PacketWrapper; 5 | import org.jetbrains.annotations.ApiStatus.NonExtendable; 6 | import org.jetbrains.annotations.ApiStatus.OverrideOnly; 7 | import org.jetbrains.annotations.NotNull; 8 | 9 | import static com.github.retrooper.packetevents.netty.buffer.UnpooledByteBufAllocationHelper.buffer; 10 | import static com.github.retrooper.packetevents.netty.buffer.UnpooledByteBufAllocationHelper.wrappedBuffer; 11 | import static com.github.retrooper.packetevents.wrapper.PacketWrapper.createUniversalPacketWrapper; 12 | 13 | public interface Payload { 14 | @NonExtendable 15 | default byte[] write() { 16 | Object buffer = buffer(); 17 | write(createUniversalPacketWrapper(buffer)); 18 | return ByteBufHelper.array(buffer); 19 | } 20 | 21 | @OverrideOnly 22 | void write(PacketWrapper wrapper); 23 | 24 | static @NotNull PacketWrapper wrapper(byte[] data) { 25 | return createUniversalPacketWrapper(wrappedBuffer(data)); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/manager/player/features/types/ForceSlowMovementFeature.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.manager.player.features.types; 2 | 3 | import ac.grim.grimac.api.config.ConfigManager; 4 | import ac.grim.grimac.api.feature.FeatureState; 5 | import ac.grim.grimac.player.GrimPlayer; 6 | 7 | public class ForceSlowMovementFeature implements GrimFeature { 8 | 9 | @Override 10 | public String getName() { 11 | return "ForceSlowMovement"; 12 | } 13 | 14 | @Override 15 | public void setState(GrimPlayer player, ConfigManager config, FeatureState state) { 16 | switch (state) { 17 | case ENABLED -> player.setForceSlowMovement(true); 18 | case DISABLED -> player.setForceSlowMovement(false); 19 | default -> player.setForceSlowMovement(isEnabledInConfig(player, config)); 20 | } 21 | } 22 | 23 | @Override 24 | public boolean isEnabled(GrimPlayer player) { 25 | return player.isForceSlowMovement(); 26 | } 27 | 28 | @Override 29 | public boolean isEnabledInConfig(GrimPlayer player, ConfigManager config) { 30 | return config.getBooleanElse("force-slow-movement", true); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/manager/player/features/types/ExperimentalChecksFeature.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.manager.player.features.types; 2 | 3 | import ac.grim.grimac.api.config.ConfigManager; 4 | import ac.grim.grimac.api.feature.FeatureState; 5 | import ac.grim.grimac.player.GrimPlayer; 6 | 7 | public class ExperimentalChecksFeature implements GrimFeature { 8 | 9 | @Override 10 | public String getName() { 11 | return "ExperimentalChecks"; 12 | } 13 | 14 | @Override 15 | public void setState(GrimPlayer player, ConfigManager config, FeatureState state) { 16 | switch (state) { 17 | case ENABLED -> player.setExperimentalChecks(true); 18 | case DISABLED -> player.setExperimentalChecks(false); 19 | default -> player.setExperimentalChecks(isEnabledInConfig(player, config)); 20 | } 21 | } 22 | 23 | @Override 24 | public boolean isEnabled(GrimPlayer player) { 25 | return player.isExperimentalChecks(); 26 | } 27 | 28 | @Override 29 | public boolean isEnabledInConfig(GrimPlayer player, ConfigManager config) { 30 | return config.getBooleanElse("experimental-checks", false); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ac/grim/grimac/platform/bukkit/manager/BukkitPlatformPluginManager.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.bukkit.manager; 2 | 3 | import ac.grim.grimac.platform.api.PlatformPlugin; 4 | import ac.grim.grimac.platform.api.manager.PlatformPluginManager; 5 | import ac.grim.grimac.platform.bukkit.BukkitPlatformPlugin; 6 | import org.bukkit.Bukkit; 7 | import org.bukkit.plugin.Plugin; 8 | import org.jetbrains.annotations.Nullable; 9 | 10 | public class BukkitPlatformPluginManager implements PlatformPluginManager { 11 | 12 | @Override 13 | public PlatformPlugin[] getPlugins() { 14 | Plugin[] bukkitPlugins = Bukkit.getPluginManager().getPlugins(); 15 | PlatformPlugin[] plugins = new PlatformPlugin[bukkitPlugins.length]; 16 | 17 | for (int i = 0; i < bukkitPlugins.length; i++) { 18 | plugins[i] = new BukkitPlatformPlugin(bukkitPlugins[i]); 19 | } 20 | 21 | return plugins; 22 | } 23 | 24 | @Override 25 | public @Nullable PlatformPlugin getPlugin(String pluginName) { 26 | Plugin bukkitPlugin = Bukkit.getPluginManager().getPlugin(pluginName); 27 | return bukkitPlugin == null ? null : new BukkitPlatformPlugin(bukkitPlugin); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/checks/impl/aim/AimDuplicateLook.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.checks.impl.aim; 2 | 3 | import ac.grim.grimac.checks.Check; 4 | import ac.grim.grimac.checks.CheckData; 5 | import ac.grim.grimac.checks.type.RotationCheck; 6 | import ac.grim.grimac.player.GrimPlayer; 7 | import ac.grim.grimac.utils.anticheat.update.RotationUpdate; 8 | 9 | @CheckData(name = "AimDuplicateLook") 10 | public class AimDuplicateLook extends Check implements RotationCheck { 11 | private boolean exempt; 12 | 13 | public AimDuplicateLook(GrimPlayer playerData) { 14 | super(playerData); 15 | } 16 | 17 | @Override 18 | public void process(final RotationUpdate rotationUpdate) { 19 | if (player.packetStateData.lastPacketWasTeleport || player.packetStateData.lastPacketWasOnePointSeventeenDuplicate || player.compensatedEntities.self.getRiding() != null) { 20 | exempt = true; 21 | return; 22 | } 23 | 24 | if (exempt) { // Exempt for a tick on teleport 25 | exempt = false; 26 | return; 27 | } 28 | 29 | if (rotationUpdate.getFrom().equals(rotationUpdate.getTo())) { 30 | flagAndAlert(); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/checks/impl/badpackets/BadPacketsI.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.checks.impl.badpackets; 2 | 3 | import ac.grim.grimac.checks.Check; 4 | import ac.grim.grimac.checks.CheckData; 5 | import ac.grim.grimac.checks.type.PacketCheck; 6 | import ac.grim.grimac.player.GrimPlayer; 7 | import com.github.retrooper.packetevents.event.PacketReceiveEvent; 8 | import com.github.retrooper.packetevents.protocol.packettype.PacketType; 9 | import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerAbilities; 10 | 11 | @CheckData(name = "BadPacketsI", description = "Claimed to be flying while unable to fly") 12 | public class BadPacketsI extends Check implements PacketCheck { 13 | public BadPacketsI(GrimPlayer player) { 14 | super(player); 15 | } 16 | 17 | @Override 18 | public void onPacketReceive(PacketReceiveEvent event) { 19 | if (event.getPacketType() == PacketType.Play.Client.PLAYER_ABILITIES 20 | && new WrapperPlayClientPlayerAbilities(event).isFlying() && !player.canFly 21 | && flagAndAlert() && shouldModifyPackets()) { 22 | event.setCancelled(true); 23 | player.onPacketCancel(); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/checks/impl/crash/CrashB.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.checks.impl.crash; 2 | 3 | import ac.grim.grimac.checks.Check; 4 | import ac.grim.grimac.checks.CheckData; 5 | import ac.grim.grimac.checks.type.PacketCheck; 6 | import ac.grim.grimac.player.GrimPlayer; 7 | import com.github.retrooper.packetevents.event.PacketReceiveEvent; 8 | import com.github.retrooper.packetevents.protocol.packettype.PacketType; 9 | import com.github.retrooper.packetevents.protocol.player.GameMode; 10 | 11 | @CheckData(name = "CrashB", description = "Sent creative mode inventory click packets while not in creative mode") 12 | public class CrashB extends Check implements PacketCheck { 13 | public CrashB(GrimPlayer player) { 14 | super(player); 15 | } 16 | 17 | @Override 18 | public void onPacketReceive(PacketReceiveEvent event) { 19 | if (event.getPacketType() == PacketType.Play.Client.CREATIVE_INVENTORY_ACTION) { 20 | if (player.gamemode != GameMode.CREATIVE) { 21 | event.setCancelled(true); 22 | player.onPacketCancel(); 23 | flagAndAlert(); // Could be transaction split, no need to setback though 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/checks/impl/crash/CrashE.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.checks.impl.crash; 2 | 3 | import ac.grim.grimac.checks.Check; 4 | import ac.grim.grimac.checks.CheckData; 5 | import ac.grim.grimac.checks.type.PacketCheck; 6 | import ac.grim.grimac.player.GrimPlayer; 7 | import com.github.retrooper.packetevents.event.PacketReceiveEvent; 8 | import com.github.retrooper.packetevents.protocol.packettype.PacketType; 9 | import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientSettings; 10 | 11 | @CheckData(name = "CrashE") 12 | public class CrashE extends Check implements PacketCheck { 13 | 14 | public CrashE(GrimPlayer playerData) { 15 | super(playerData); 16 | } 17 | 18 | @Override 19 | public void onPacketReceive(final PacketReceiveEvent event) { 20 | if (event.getPacketType() == PacketType.Play.Client.CLIENT_SETTINGS) { 21 | WrapperPlayClientSettings wrapper = new WrapperPlayClientSettings(event); 22 | int viewDistance = wrapper.getViewDistance(); 23 | if (viewDistance < 2) { 24 | flagAndAlert("distance=" + viewDistance); 25 | wrapper.setViewDistance(2); 26 | } 27 | } 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/checks/impl/scaffolding/InvalidPlaceB.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.checks.impl.scaffolding; 2 | 3 | import ac.grim.grimac.checks.CheckData; 4 | import ac.grim.grimac.checks.type.BlockPlaceCheck; 5 | import ac.grim.grimac.player.GrimPlayer; 6 | import ac.grim.grimac.utils.anticheat.update.BlockPlace; 7 | import com.github.retrooper.packetevents.PacketEvents; 8 | import com.github.retrooper.packetevents.manager.server.ServerVersion; 9 | 10 | @CheckData(name = "InvalidPlaceB", description = "Sent impossible block face id") 11 | public class InvalidPlaceB extends BlockPlaceCheck { 12 | public InvalidPlaceB(GrimPlayer player) { 13 | super(player); 14 | } 15 | 16 | @Override 17 | public void onBlockPlace(final BlockPlace place) { 18 | if (place.getFaceId() == 255 && PacketEvents.getAPI().getServerManager().getVersion().isOlderThanOrEquals(ServerVersion.V_1_8)) { 19 | return; 20 | } 21 | 22 | if (place.getFaceId() < 0 || place.getFaceId() > 5) { 23 | // ban 24 | if (flagAndAlert("direction=" + place.getFaceId()) && shouldModifyPackets() && shouldCancel()) { 25 | place.resync(); 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/manager/init/start/TAB.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.manager.init.start; 2 | 3 | import ac.grim.grimac.GrimAPI; 4 | import ac.grim.grimac.utils.anticheat.LogUtil; 5 | import ac.grim.grimac.utils.viaversion.ViaVersionUtil; 6 | import com.github.retrooper.packetevents.PacketEvents; 7 | import com.github.retrooper.packetevents.manager.server.ServerVersion; 8 | 9 | public class TAB implements StartableInitable { 10 | 11 | @Override 12 | public void start() { 13 | if (GrimAPI.INSTANCE.getPluginManager().getPlugin("TAB") == null) return; 14 | if (!ViaVersionUtil.isAvailable) return; 15 | // I don't know when team limits were changed, 1.13 is reasonable enough 16 | if (PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_13)) 17 | return; 18 | 19 | LogUtil.warn("GrimAC has detected that you have installed TAB with ViaVersion."); 20 | LogUtil.warn("Please note that currently, TAB is incompatible as it sends illegal packets to players using versions newer than your server version."); 21 | LogUtil.warn("You may be able to remedy this by setting `compensate-for-packetevents-bug` to true in the TAB config."); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/command/commands/GrimVerbose.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.command.commands; 2 | 3 | import ac.grim.grimac.GrimAPI; 4 | import ac.grim.grimac.command.BuildableCommand; 5 | import ac.grim.grimac.platform.api.sender.Sender; 6 | import org.incendo.cloud.CommandManager; 7 | import org.incendo.cloud.context.CommandContext; 8 | import org.jetbrains.annotations.NotNull; 9 | 10 | public class GrimVerbose implements BuildableCommand { 11 | @Override 12 | public void register(CommandManager commandManager) { 13 | commandManager.command( 14 | commandManager.commandBuilder("grim", "grimac") 15 | .literal("verbose") 16 | .permission("grim.verbose") 17 | .handler(this::handleVerbose) 18 | ); 19 | } 20 | 21 | private void handleVerbose(@NotNull CommandContext context) { 22 | Sender sender = context.sender(); 23 | if (sender.isPlayer()) { 24 | GrimAPI.INSTANCE.getAlertManager().toggleVerbose(context.sender().getPlatformPlayer(), false); 25 | } else if (sender.isConsole()) { 26 | GrimAPI.INSTANCE.getAlertManager().toggleConsoleVerbose(); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ac/grim/grimac/platform/bukkit/utils/anticheat/MultiLibUtil.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.bukkit.utils.anticheat; 2 | 3 | import ac.grim.grimac.utils.anticheat.LogUtil; 4 | import ac.grim.grimac.utils.reflection.ReflectionUtils; 5 | import com.github.retrooper.packetevents.PacketEvents; 6 | import com.github.retrooper.packetevents.manager.server.ServerVersion; 7 | import org.bukkit.entity.Player; 8 | 9 | import java.lang.reflect.Method; 10 | 11 | public class MultiLibUtil { 12 | 13 | public final static Method externalPlayerMethod = ReflectionUtils.getMethod(Player.class, "isExternalPlayer"); 14 | private static final boolean IS_PRE_1_18 = PacketEvents.getAPI().getServerManager().getVersion().isOlderThan(ServerVersion.V_1_18); 15 | 16 | // TODO: cache external players for better performance, but this only matters for people using multi-lib 17 | public static boolean isExternalPlayer(Player player) { 18 | if (externalPlayerMethod == null || IS_PRE_1_18) return false; 19 | try { 20 | return (boolean) externalPlayerMethod.invoke(player); 21 | } catch (Exception e) { 22 | LogUtil.error("Failed to invoke external player method", e); 23 | return false; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ac/grim/grimac/platform/bukkit/command/BukkitPlayerSelectorParser.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.bukkit.command; 2 | 3 | import ac.grim.grimac.platform.api.command.AbstractPlayerSelectorParser; 4 | import ac.grim.grimac.platform.api.command.PlayerSelector; 5 | import org.incendo.cloud.bukkit.parser.selector.SinglePlayerSelectorParser; 6 | import org.incendo.cloud.context.CommandContext; 7 | import org.incendo.cloud.parser.ParserDescriptor; 8 | 9 | import java.util.concurrent.CompletableFuture; 10 | 11 | public class BukkitPlayerSelectorParser extends AbstractPlayerSelectorParser { 12 | 13 | @Override 14 | public ParserDescriptor descriptor() { 15 | return super.createDescriptor(); 16 | } 17 | 18 | @Override 19 | protected ParserDescriptor getPlatformSpecificDescriptor() { 20 | return SinglePlayerSelectorParser.singlePlayerSelectorParser(); 21 | } 22 | 23 | @Override 24 | protected CompletableFuture adaptToCommonSelector(CommandContext context, Object platformSpecificSelector) { 25 | return CompletableFuture.completedFuture(new BukkitPlayerSelectorAdapter((org.incendo.cloud.bukkit.data.SinglePlayerSelector) platformSpecificSelector)); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/webhook/JsonSerializable.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.webhook; 2 | 3 | import com.google.gson.JsonArray; 4 | import com.google.gson.JsonElement; 5 | import com.google.gson.JsonNull; 6 | import org.jetbrains.annotations.NotNull; 7 | import org.jetbrains.annotations.Nullable; 8 | 9 | import java.util.function.Function; 10 | import java.util.function.IntFunction; 11 | 12 | public interface JsonSerializable { 13 | @NotNull JsonElement toJson(); 14 | 15 | static @NotNull JsonArray serializeArray(@Nullable JsonSerializable @NotNull [] serializableArray) { 16 | JsonArray array = new JsonArray(); 17 | 18 | for (JsonSerializable serializable : serializableArray) { 19 | array.add(serializable == null ? JsonNull.INSTANCE : serializable.toJson()); 20 | } 21 | 22 | return array; 23 | } 24 | 25 | static T @NotNull [] deserializeArray(JsonArray jsonArray, IntFunction newArray, Function constructor) { 26 | T[] array = newArray.apply(jsonArray.size()); 27 | 28 | for (int i = 0; i < jsonArray.size(); i++) { 29 | array[i] = constructor.apply(jsonArray.get(i)); 30 | } 31 | 32 | return array; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/platform/api/permissions/PermissionDefaultValue.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.api.permissions; 2 | 3 | /** 4 | * Represents the default value for a permission, used across platforms. 5 | * This enum provides a cross-platform abstraction for permission defaults, 6 | * mapping to platform-specific values (e.g., Bukkit's PermissionDefault, Fabric's boolean). 7 | */ 8 | public enum PermissionDefaultValue { 9 | /** 10 | * Permission defaults to true (granted by default). 11 | * - Bukkit: Maps to PermissionDefault.TRUE 12 | * - Fabric: Maps to true 13 | */ 14 | TRUE, 15 | 16 | /** 17 | * Permission defaults to false (denied by default). 18 | * - Bukkit: Maps to PermissionDefault.FALSE 19 | * - Fabric: Maps to false 20 | */ 21 | FALSE, 22 | 23 | /** 24 | * Permission defaults to requiring operator (op) status. 25 | * - Bukkit: Maps to PermissionDefault.OP 26 | * - Fabric: Maps to requiring op-permission-level 27 | */ 28 | OP, 29 | 30 | /** 31 | * Permission defaults to not requiring operator (op) status. 32 | * - Bukkit: Maps to PermissionDefault.NOT_OP 33 | * - Fabric: Maps to requiring {@literal <} op-permission-level 34 | */ 35 | NOT_OP 36 | } 37 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/checks/impl/timer/VehicleTimer.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.checks.impl.timer; 2 | 3 | import ac.grim.grimac.checks.CheckData; 4 | import ac.grim.grimac.player.GrimPlayer; 5 | import com.github.retrooper.packetevents.protocol.packettype.PacketType; 6 | import com.github.retrooper.packetevents.protocol.packettype.PacketTypeCommon; 7 | 8 | @CheckData(name = "VehicleTimer", setback = 10) 9 | public class VehicleTimer extends Timer { 10 | private boolean isDummy = false; 11 | 12 | public VehicleTimer(GrimPlayer player) { 13 | super(player); 14 | } 15 | 16 | @Override 17 | public boolean shouldCountPacketForTimer(PacketTypeCommon packetType) { 18 | // Ignore teleports 19 | if (player.packetStateData.lastPacketWasTeleport) return false; 20 | 21 | if (packetType == PacketType.Play.Client.VEHICLE_MOVE) { 22 | isDummy = false; 23 | return true; // Client controlling vehicle 24 | } 25 | 26 | if (packetType == PacketType.Play.Client.STEER_VEHICLE) { 27 | if (isDummy) { // Server is controlling vehicle 28 | return true; 29 | } 30 | isDummy = true; // Client is controlling vehicle 31 | } 32 | 33 | return false; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /fabric/src/main/java/ac/grim/grimac/platform/fabric/FabricPlatformPlugin.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.fabric; 2 | 3 | import ac.grim.grimac.platform.api.PlatformPlugin; 4 | import net.fabricmc.loader.api.ModContainer; 5 | import org.jetbrains.annotations.Contract; 6 | import org.jetbrains.annotations.NotNull; 7 | 8 | import java.util.Objects; 9 | 10 | public class FabricPlatformPlugin implements PlatformPlugin { 11 | private final @NotNull ModContainer modContainer; 12 | 13 | @Contract(pure = true) 14 | public FabricPlatformPlugin(@NotNull ModContainer modContainer) { 15 | this.modContainer = Objects.requireNonNull(modContainer); 16 | } 17 | 18 | @Override 19 | public boolean isEnabled() { 20 | // Fabric mods are always "enabled" if loaded, as there's no explicit enable/disable state 21 | // You can add custom logic if needed (e.g., check mod configuration) 22 | return true; 23 | } 24 | 25 | @Override 26 | public String getName() { 27 | // Get the mod ID (unique identifier) 28 | return modContainer.getMetadata().getId(); 29 | } 30 | 31 | @Override 32 | public String getVersion() { 33 | // Get the mod version from metadata 34 | return modContainer.getMetadata().getVersion().getFriendlyString(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ac/grim/grimac/platform/bukkit/command/BukkitPlayerSelectorAdapter.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.bukkit.command; 2 | 3 | import ac.grim.grimac.GrimAPI; 4 | import ac.grim.grimac.platform.api.command.PlayerSelector; 5 | import ac.grim.grimac.platform.api.sender.Sender; 6 | import ac.grim.grimac.platform.bukkit.sender.BukkitSenderFactory; 7 | import lombok.RequiredArgsConstructor; 8 | import org.incendo.cloud.bukkit.data.SinglePlayerSelector; 9 | 10 | import java.util.Collection; 11 | import java.util.Collections; 12 | 13 | @RequiredArgsConstructor 14 | public class BukkitPlayerSelectorAdapter implements PlayerSelector { 15 | private final SinglePlayerSelector bukkitSelector; 16 | 17 | @Override 18 | public boolean isSingle() { 19 | return true; 20 | } 21 | 22 | @Override 23 | public Sender getSinglePlayer() { 24 | return ((BukkitSenderFactory) GrimAPI.INSTANCE.getSenderFactory()).map(bukkitSelector.single()); 25 | } 26 | 27 | @Override 28 | public Collection getPlayers() { 29 | return Collections.singletonList(((BukkitSenderFactory) GrimAPI.INSTANCE.getSenderFactory()).map(bukkitSelector.single())); 30 | } 31 | 32 | @Override 33 | public String inputString() { 34 | return bukkitSelector.inputString(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/inventory/slot/EquipmentSlot.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.inventory.slot; 2 | 3 | import ac.grim.grimac.player.GrimPlayer; 4 | import ac.grim.grimac.utils.inventory.EquipmentType; 5 | import ac.grim.grimac.utils.inventory.InventoryStorage; 6 | import com.github.retrooper.packetevents.protocol.item.ItemStack; 7 | import com.github.retrooper.packetevents.protocol.item.enchantment.type.EnchantmentTypes; 8 | import com.github.retrooper.packetevents.protocol.player.GameMode; 9 | 10 | public class EquipmentSlot extends Slot { 11 | private final EquipmentType type; 12 | 13 | public EquipmentSlot(EquipmentType type, InventoryStorage menu, int slot) { 14 | super(menu, slot); 15 | this.type = type; 16 | } 17 | 18 | @Override 19 | public int getMaxStackSize() { 20 | return 1; 21 | } 22 | 23 | @Override 24 | public boolean mayPlace(ItemStack itemStack) { 25 | return type == EquipmentType.getEquipmentSlotForItem(itemStack); 26 | } 27 | 28 | public boolean mayPickup(GrimPlayer player) { 29 | ItemStack itemstack = this.getItem(); 30 | return (itemstack.isEmpty() || player.gamemode == GameMode.CREATIVE || itemstack.getEnchantmentLevel(EnchantmentTypes.BINDING_CURSE) == 0) && super.mayPickup(player); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/checks/impl/badpackets/BadPacketsY.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.checks.impl.badpackets; 2 | 3 | import ac.grim.grimac.checks.Check; 4 | import ac.grim.grimac.checks.CheckData; 5 | import ac.grim.grimac.checks.type.PacketCheck; 6 | import ac.grim.grimac.player.GrimPlayer; 7 | import com.github.retrooper.packetevents.event.PacketReceiveEvent; 8 | import com.github.retrooper.packetevents.protocol.packettype.PacketType; 9 | import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientHeldItemChange; 10 | 11 | @CheckData(name = "BadPacketsY", description = "Sent out of bounds slot id") 12 | public class BadPacketsY extends Check implements PacketCheck { 13 | public BadPacketsY(GrimPlayer player) { 14 | super(player); 15 | } 16 | 17 | @Override 18 | public void onPacketReceive(PacketReceiveEvent event) { 19 | if (event.getPacketType() == PacketType.Play.Client.HELD_ITEM_CHANGE) { 20 | final int slot = new WrapperPlayClientHeldItemChange(event).getSlot(); 21 | if (slot > 8 || slot < 0) { // ban 22 | if (flagAndAlert("slot=" + slot) && shouldModifyPackets()) { 23 | event.setCancelled(true); 24 | player.onPacketCancel(); 25 | } 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /fabric/src/main/java/ac/grim/grimac/platform/fabric/manager/FabricPlatformPluginManager.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.fabric.manager; 2 | 3 | import ac.grim.grimac.platform.api.PlatformPlugin; 4 | import ac.grim.grimac.platform.api.manager.PlatformPluginManager; 5 | import ac.grim.grimac.platform.fabric.FabricPlatformPlugin; 6 | import net.fabricmc.loader.api.FabricLoader; 7 | import net.fabricmc.loader.api.ModContainer; 8 | 9 | import java.util.Collection; 10 | import java.util.Optional; 11 | 12 | public class FabricPlatformPluginManager implements PlatformPluginManager { 13 | 14 | @Override 15 | public PlatformPlugin[] getPlugins() { 16 | // Get all loaded mods from Fabric Loader 17 | Collection mods = FabricLoader.getInstance().getAllMods(); 18 | PlatformPlugin[] plugins = new PlatformPlugin[mods.size()]; 19 | int i = 0; 20 | for (ModContainer mod : mods) { 21 | plugins[i++] = new FabricPlatformPlugin(mod); 22 | } 23 | return plugins; 24 | } 25 | 26 | @Override 27 | public PlatformPlugin getPlugin(String pluginName) { 28 | // Look up a mod by its ID 29 | Optional mod = FabricLoader.getInstance().getModContainer(pluginName); 30 | return mod.map(FabricPlatformPlugin::new).orElse(null); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/checks/impl/sprint/SprintG.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.checks.impl.sprint; 2 | 3 | import ac.grim.grimac.checks.Check; 4 | import ac.grim.grimac.checks.CheckData; 5 | import ac.grim.grimac.checks.type.PostPredictionCheck; 6 | import ac.grim.grimac.player.GrimPlayer; 7 | import ac.grim.grimac.utils.anticheat.update.PredictionComplete; 8 | import com.github.retrooper.packetevents.protocol.player.ClientVersion; 9 | 10 | @CheckData(name = "SprintG", description = "Sprinting while in water", experimental = true) 11 | public class SprintG extends Check implements PostPredictionCheck { 12 | public SprintG(GrimPlayer player) { 13 | super(player); 14 | } 15 | 16 | @Override 17 | public void onPredictionComplete(final PredictionComplete predictionComplete) { 18 | if (player.wasTouchingWater && (player.wasWasTouchingWater || player.getClientVersion() == ClientVersion.V_1_21_4) 19 | && !player.wasEyeInWater && player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_13) 20 | && player.wasLastPredictionCompleteChecked && predictionComplete.isChecked()) { 21 | if (player.isSprinting && !player.isSwimming) { 22 | flagAndAlertWithSetback(); 23 | } else { 24 | reward(); 25 | } 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/collisions/datatypes/HexCollisionBox.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.collisions.datatypes; 2 | 3 | public class HexCollisionBox extends SimpleCollisionBox { 4 | 5 | /** 6 | * Creates a box defined by two points in 3d space; used to represent hitboxes and collision boxes. 7 | * Mojang's block hitbox values are all based on chunks, so they're stored in game as 16 * the actual size 8 | * When copying block hitbox values, it may be easier to simple copy the multiplied values and use this class 9 | * If your min/max values are {@literal <} 1 you should probably check out {@link SimpleCollisionBox} 10 | * 11 | * @param minX 16 * x position of first corner 12 | * @param minY 16 * y position of first corner 13 | * @param minZ 16 * z position of first corner 14 | * @param maxX 16 * x position of second corner 15 | * @param maxY 16 * y position of second corner 16 | * @param maxZ 16 * z position of second corner 17 | */ 18 | public HexCollisionBox(double minX, double minY, double minZ, double maxX, double maxY, double maxZ) { 19 | this.minX = minX / 16d; 20 | this.minY = minY / 16d; 21 | this.minZ = minZ / 16d; 22 | this.maxX = maxX / 16d; 23 | this.maxY = maxY / 16d; 24 | this.maxZ = maxZ / 16d; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/checks/impl/badpackets/BadPacketsA.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.checks.impl.badpackets; 2 | 3 | import ac.grim.grimac.checks.Check; 4 | import ac.grim.grimac.checks.CheckData; 5 | import ac.grim.grimac.checks.type.PacketCheck; 6 | import ac.grim.grimac.player.GrimPlayer; 7 | import com.github.retrooper.packetevents.event.PacketReceiveEvent; 8 | import com.github.retrooper.packetevents.protocol.packettype.PacketType; 9 | import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientHeldItemChange; 10 | 11 | @CheckData(name = "BadPacketsA", description = "Sent duplicate slot id") 12 | public class BadPacketsA extends Check implements PacketCheck { 13 | private int lastSlot = -1; 14 | 15 | public BadPacketsA(final GrimPlayer player) { 16 | super(player); 17 | } 18 | 19 | @Override 20 | public void onPacketReceive(PacketReceiveEvent event) { 21 | if (event.getPacketType() == PacketType.Play.Client.HELD_ITEM_CHANGE) { 22 | final int slot = new WrapperPlayClientHeldItemChange(event).getSlot(); 23 | 24 | if (slot == lastSlot && flagAndAlert("slot=" + slot) && shouldModifyPackets()) { 25 | event.setCancelled(true); 26 | player.onPacketCancel(); 27 | } 28 | 29 | lastSlot = slot; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/checks/impl/breaking/InvalidBreak.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.checks.impl.breaking; 2 | 3 | import ac.grim.grimac.checks.Check; 4 | import ac.grim.grimac.checks.CheckData; 5 | import ac.grim.grimac.checks.type.BlockBreakCheck; 6 | import ac.grim.grimac.player.GrimPlayer; 7 | import ac.grim.grimac.utils.anticheat.update.BlockBreak; 8 | import com.github.retrooper.packetevents.protocol.player.ClientVersion; 9 | import com.github.retrooper.packetevents.protocol.player.DiggingAction; 10 | 11 | @CheckData(name = "InvalidBreak", description = "Sent impossible block face id") 12 | public class InvalidBreak extends Check implements BlockBreakCheck { 13 | public InvalidBreak(GrimPlayer player) { 14 | super(player); 15 | } 16 | 17 | @Override 18 | public void onBlockBreak(BlockBreak blockBreak) { 19 | if (blockBreak.faceId == 255 && blockBreak.action == DiggingAction.CANCELLED_DIGGING && player.getClientVersion().isOlderThanOrEquals(ClientVersion.V_1_7_10)) { 20 | return; 21 | } 22 | 23 | if (blockBreak.faceId < 0 || blockBreak.faceId > 5) { 24 | // ban 25 | if (flagAndAlert("face=" + blockBreak.faceId + ", action=" + blockBreak.action) && shouldModifyPackets()) { 26 | blockBreak.cancel(); 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/collisions/datatypes/NoCollisionBox.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.collisions.datatypes; 2 | 3 | import java.util.List; 4 | 5 | public class NoCollisionBox implements CollisionBox { 6 | 7 | public static final NoCollisionBox INSTANCE = new NoCollisionBox(); 8 | 9 | private NoCollisionBox() { 10 | } 11 | 12 | @Override 13 | public CollisionBox union(SimpleCollisionBox other) { 14 | return other; 15 | } 16 | 17 | @Override 18 | public boolean isCollided(SimpleCollisionBox other) { 19 | return false; 20 | } 21 | 22 | @Override 23 | public boolean isIntersected(SimpleCollisionBox other) { 24 | return false; 25 | } 26 | 27 | @Override 28 | public CollisionBox offset(double x, double y, double z) { 29 | return this; 30 | } 31 | 32 | @Override 33 | public void downCast(List list) { /**/ } 34 | 35 | @Override 36 | public int downCast(SimpleCollisionBox[] list) { 37 | return 0; 38 | } 39 | 40 | @Override 41 | public boolean isNull() { 42 | return true; 43 | } 44 | 45 | @Override 46 | public boolean isFullBlock() { 47 | return false; 48 | } 49 | 50 | @Override 51 | public CollisionBox copy() { 52 | return this; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /bukkit/src/main/java/ac/grim/grimac/platform/bukkit/BukkitPlatformServer.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.bukkit; 2 | 3 | import ac.grim.grimac.platform.api.PlatformServer; 4 | import ac.grim.grimac.platform.api.sender.Sender; 5 | import io.github.retrooper.packetevents.util.SpigotReflectionUtil; 6 | import org.bukkit.Bukkit; 7 | import org.bukkit.command.CommandSender; 8 | 9 | 10 | public class BukkitPlatformServer implements PlatformServer { 11 | 12 | @Override 13 | public String getPlatformImplementationString() { 14 | return Bukkit.getVersion(); 15 | } 16 | 17 | @Override 18 | public void dispatchCommand(Sender sender, String command) { 19 | CommandSender commandSender = GrimACBukkitLoaderPlugin.LOADER.getBukkitSenderFactory().reverse(sender); 20 | Bukkit.dispatchCommand(commandSender, command); 21 | } 22 | 23 | @Override 24 | public Sender getConsoleSender() { 25 | return GrimACBukkitLoaderPlugin.LOADER.getBukkitSenderFactory().map(Bukkit.getConsoleSender()); 26 | } 27 | 28 | @Override 29 | public void registerOutgoingPluginChannel(String name) { 30 | GrimACBukkitLoaderPlugin.LOADER.getServer().getMessenger().registerOutgoingPluginChannel(GrimACBukkitLoaderPlugin.LOADER, name); 31 | } 32 | 33 | @Override 34 | public double getTPS() { 35 | return SpigotReflectionUtil.getTPS(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/command/commands/GrimBrands.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.command.commands; 2 | 3 | import ac.grim.grimac.GrimAPI; 4 | import ac.grim.grimac.command.BuildableCommand; 5 | import ac.grim.grimac.platform.api.sender.Sender; 6 | import org.incendo.cloud.CommandManager; 7 | import org.incendo.cloud.context.CommandContext; 8 | import org.incendo.cloud.description.Description; 9 | import org.jetbrains.annotations.NotNull; 10 | 11 | import java.util.Objects; 12 | 13 | public class GrimBrands implements BuildableCommand { 14 | @Override 15 | public void register(CommandManager commandManager) { 16 | commandManager.command( 17 | commandManager.commandBuilder("grim", "grimac") 18 | .literal("brands", Description.of("Toggle brands for the sender")) 19 | .permission("grim.brand") 20 | .handler(this::handleBrands) 21 | ); 22 | } 23 | 24 | private void handleBrands(@NotNull CommandContext context) { 25 | Sender sender = context.sender(); 26 | if (sender.isPlayer()) { 27 | GrimAPI.INSTANCE.getAlertManager().toggleBrands(Objects.requireNonNull(context.sender().getPlatformPlayer()), false); 28 | } else if (sender.isConsole()) { 29 | GrimAPI.INSTANCE.getAlertManager().toggleConsoleBrands(); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /fabric/src/main/java/ac/grim/grimac/platform/fabric/manager/FabricItemResetHandler.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.fabric.manager; 2 | 3 | import ac.grim.grimac.platform.api.manager.ItemResetHandler; 4 | import ac.grim.grimac.platform.api.player.PlatformPlayer; 5 | import ac.grim.grimac.platform.fabric.utils.convert.FabricConversionUtil; 6 | import com.github.retrooper.packetevents.protocol.player.InteractionHand; 7 | import net.minecraft.server.level.ServerPlayer; 8 | import org.jetbrains.annotations.Nullable; 9 | 10 | public class FabricItemResetHandler implements ItemResetHandler { 11 | @Override 12 | public void resetItemUsage(@Nullable PlatformPlayer player) { 13 | if (player != null) { 14 | ((ServerPlayer) player.getNative()).stopUsingItem(); 15 | } 16 | } 17 | 18 | @Override 19 | public @Nullable InteractionHand getItemUsageHand(@Nullable PlatformPlayer platformPlayer) { 20 | if (platformPlayer == null) { 21 | return null; 22 | } 23 | 24 | ServerPlayer player = (ServerPlayer) platformPlayer.getNative(); 25 | return player.isUsingItem() ? FabricConversionUtil.fromFabricHand(player.getUsedItemHand()) : null; 26 | } 27 | 28 | @Override 29 | public boolean isUsingItem(@Nullable PlatformPlayer player) { 30 | return player != null && ((ServerPlayer) player.getNative()).isUsingItem(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # https://gist.github.com/dedunumax/54e82214715e35439227 2 | ############################## 3 | ## Java 4 | ############################## 5 | .mtj.tmp/ 6 | *.class 7 | *.jar 8 | *.war 9 | *.ear 10 | *.nar 11 | hs_err_pid* 12 | 13 | ############################## 14 | ## Gradle 15 | ############################## 16 | bin/ 17 | build/ 18 | .gradle 19 | .gradletasknamecache 20 | gradle-app.setting 21 | !gradle-wrapper.jar 22 | buildSrc/.kotlin 23 | 24 | ############################## 25 | ## IntelliJ 26 | ############################## 27 | out/ 28 | .idea/ 29 | .idea_modules/ 30 | *.iml 31 | *.ipr 32 | *.iws 33 | 34 | ############################## 35 | ## Eclipse 36 | ############################## 37 | .settings/ 38 | tmp/ 39 | .metadata 40 | .classpath 41 | .project 42 | *.tmp 43 | *.bak 44 | *.swp 45 | *~.nib 46 | local.properties 47 | .loadpath 48 | .factorypath 49 | 50 | ############################## 51 | ## NetBeans 52 | ############################## 53 | nbproject/private/ 54 | nbbuild/ 55 | dist/ 56 | nbdist/ 57 | nbactions.xml 58 | nb-configuration.xml 59 | 60 | ############################## 61 | ## Visual Studio Code 62 | ############################## 63 | .vscode/ 64 | .code-workspace 65 | 66 | ############################## 67 | ## OS X 68 | ############################## 69 | .DS_Store 70 | 71 | ############################## 72 | ## Fabric 73 | ############################## 74 | run/ 75 | fabric/run/ 76 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/command/commands/GrimHelp.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.command.commands; 2 | 3 | import ac.grim.grimac.GrimAPI; 4 | import ac.grim.grimac.command.BuildableCommand; 5 | import ac.grim.grimac.platform.api.sender.Sender; 6 | import ac.grim.grimac.utils.anticheat.MessageUtil; 7 | import org.incendo.cloud.CommandManager; 8 | import org.incendo.cloud.context.CommandContext; 9 | import org.incendo.cloud.description.Description; 10 | import org.jetbrains.annotations.NotNull; 11 | 12 | public class GrimHelp implements BuildableCommand { 13 | @Override 14 | public void register(CommandManager commandManager) { 15 | commandManager.command( 16 | commandManager.commandBuilder("grim", "grimac") 17 | .literal("help", Description.of("Display help information")) 18 | .permission("grim.help") 19 | .handler(this::handleHelp) 20 | ); 21 | } 22 | 23 | private void handleHelp(@NotNull CommandContext context) { 24 | Sender sender = context.sender(); 25 | 26 | for (String string : GrimAPI.INSTANCE.getConfigManager().getConfig().getStringList("help")) { 27 | if (string == null) continue; 28 | string = MessageUtil.replacePlaceholders(sender, string); 29 | sender.sendMessage(MessageUtil.miniMessage(string)); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /common/src/main/java/ac/grim/grimac/utils/collisions/blocks/PistonBaseCollision.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.utils.collisions.blocks; 2 | 3 | import ac.grim.grimac.player.GrimPlayer; 4 | import ac.grim.grimac.utils.collisions.datatypes.CollisionBox; 5 | import ac.grim.grimac.utils.collisions.datatypes.CollisionFactory; 6 | import ac.grim.grimac.utils.collisions.datatypes.HexCollisionBox; 7 | import ac.grim.grimac.utils.collisions.datatypes.SimpleCollisionBox; 8 | import com.github.retrooper.packetevents.protocol.player.ClientVersion; 9 | import com.github.retrooper.packetevents.protocol.world.states.WrappedBlockState; 10 | 11 | public class PistonBaseCollision implements CollisionFactory { 12 | 13 | @Override 14 | public CollisionBox fetch(GrimPlayer player, ClientVersion version, WrappedBlockState block, int x, int y, int z) { 15 | if (!block.isExtended()) return new SimpleCollisionBox(0, 0, 0, 1, 1, 1, true); 16 | 17 | return switch (block.getFacing()) { 18 | case UP -> new HexCollisionBox(0, 0, 0, 16, 12, 16); 19 | case NORTH -> new HexCollisionBox(0, 0, 4, 16, 16, 16); 20 | case SOUTH -> new HexCollisionBox(0, 0, 0, 16, 16, 12); 21 | case WEST -> new HexCollisionBox(4, 0, 0, 16, 16, 16); 22 | case EAST -> new HexCollisionBox(0, 0, 0, 12, 16, 16); 23 | default -> new HexCollisionBox(0, 4, 0, 16, 16, 16); 24 | }; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /fabric/src/main/java/ac/grim/grimac/platform/fabric/utils/metrics/CustomChart.java: -------------------------------------------------------------------------------- 1 | package ac.grim.grimac.platform.fabric.utils.metrics; 2 | 3 | import java.util.function.BiConsumer; 4 | 5 | public abstract class CustomChart { 6 | 7 | private final String chartId; 8 | 9 | protected CustomChart(String chartId) { 10 | if (chartId == null) { 11 | throw new IllegalArgumentException("chartId must not be null"); 12 | } 13 | this.chartId = chartId; 14 | } 15 | 16 | public JsonObjectBuilder.JsonObject getRequestJsonObject( 17 | BiConsumer errorLogger, boolean logErrors) { 18 | JsonObjectBuilder builder = new JsonObjectBuilder(); 19 | builder.appendField("chartId", chartId); 20 | try { 21 | JsonObjectBuilder.JsonObject data = getChartData(); 22 | if (data == null) { 23 | // If the data is null we don't send the chart. 24 | return null; 25 | } 26 | builder.appendField("data", data); 27 | } catch (Throwable t) { 28 | if (logErrors) { 29 | errorLogger.accept("Failed to get data for custom chart with id " + chartId, t); 30 | } 31 | return null; 32 | } 33 | return builder.build(); 34 | } 35 | 36 | protected abstract JsonObjectBuilder.JsonObject getChartData() throws Exception; 37 | } 38 | --------------------------------------------------------------------------------