From 558636579c2c2df5941525d9af1f6e5a4ef658cc Mon Sep 17 00:00:00 2001 From: noil Date: Sun, 27 Oct 2019 11:45:44 -0400 Subject: [PATCH] First commit to new GitHub repo. --- .gitignore | 22 + .gitlab-ci.yml | 31 + LICENSE | 674 ++++++++++++++++++ README.md | 1 + build.gradle | 120 ++++ .../production/seppuku-1.12.2_main/mcmod.info | 16 + .../me/rigamortis/seppuku/Seppuku.class | Bin 0 -> 11140 bytes .../seppuku/api/command/Command.class | Bin 0 -> 2644 bytes .../seppuku/api/config/Configurable.class | Bin 0 -> 630 bytes .../seppuku/api/event/EventCancellable.class | Bin 0 -> 1070 bytes .../api/event/EventStageable$EventStage.class | Bin 0 -> 1253 bytes .../seppuku/api/event/EventStageable.class | Bin 0 -> 902 bytes .../api/event/entity/EventHorseSaddled.class | Bin 0 -> 386 bytes .../api/event/entity/EventSteerEntity.class | Bin 0 -> 383 bytes .../seppuku/api/event/gui/EventBookPage.class | Bin 0 -> 609 bytes .../api/event/gui/EventBookTitle.class | Bin 0 -> 615 bytes .../api/event/gui/EventRenderHelmet.class | Bin 0 -> 380 bytes .../api/event/gui/EventRenderPortal.class | Bin 0 -> 380 bytes .../api/event/gui/EventRenderPotions.class | Bin 0 -> 383 bytes .../api/event/minecraft/EventDisplayGui.class | Bin 0 -> 719 bytes .../api/event/minecraft/EventKeyPress.class | Bin 0 -> 567 bytes .../api/event/minecraft/EventRunTick.class | Bin 0 -> 626 bytes .../EventUpdateFramebufferSize.class | Bin 0 -> 387 bytes .../event/network/EventReceivePacket.class | Bin 0 -> 1100 bytes .../api/event/network/EventSendPacket.class | Bin 0 -> 1091 bytes .../event/player/EventApplyCollision.class | Bin 0 -> 392 bytes .../api/event/player/EventClickBlock.class | Bin 0 -> 1077 bytes .../api/event/player/EventCloseScreen.class | Bin 0 -> 383 bytes .../api/event/player/EventDestroyBlock.class | Bin 0 -> 704 bytes .../api/event/player/EventExtendedReach.class | Bin 0 -> 389 bytes .../player/EventGetBlockReachDistance.class | Bin 0 -> 680 bytes .../event/player/EventHittingPosition.class | Bin 0 -> 728 bytes .../seppuku/api/event/player/EventMove.class | Bin 0 -> 1328 bytes .../event/player/EventPlayerDamageBlock.class | Bin 0 -> 1098 bytes .../api/event/player/EventPlayerUpdate.class | Bin 0 -> 689 bytes .../event/player/EventPushOutOfBlocks.class | Bin 0 -> 395 bytes .../api/event/player/EventPushedByWater.class | Bin 0 -> 389 bytes .../player/EventResetBlockRemoving.class | Bin 0 -> 404 bytes .../api/event/player/EventRightClick.class | Bin 0 -> 686 bytes .../event/player/EventRightClickBlock.class | Bin 0 -> 1766 bytes .../event/player/EventSendChatMessage.class | Bin 0 -> 677 bytes .../seppuku/api/event/player/EventStep.class | Bin 0 -> 330 bytes .../api/event/player/EventSwingArm.class | Bin 0 -> 680 bytes .../api/event/player/EventUpdateInput.class | Bin 0 -> 351 bytes .../player/EventUpdateWalkingPlayer.class | Bin 0 -> 710 bytes .../api/event/render/EventHurtCamEffect.class | Bin 0 -> 389 bytes .../api/event/render/EventRender2D.class | Bin 0 -> 1018 bytes .../api/event/render/EventRender3D.class | Bin 0 -> 588 bytes .../event/render/EventRenderBlockModel.class | Bin 0 -> 3065 bytes .../event/render/EventRenderBlockSide.class | Bin 0 -> 914 bytes .../api/event/render/EventRenderEntity.class | Bin 0 -> 2133 bytes .../api/event/render/EventRenderFluid.class | Bin 0 -> 2156 bytes .../render/EventRenderLivingEntity.class | Bin 0 -> 1149 bytes .../api/event/render/EventRenderName.class | Bin 0 -> 722 bytes .../EventRenderOverlay$OverlayType.class | Bin 0 -> 1400 bytes .../api/event/render/EventRenderOverlay.class | Bin 0 -> 941 bytes .../event/world/EventAddCollisionBox.class | Bin 0 -> 1088 bytes .../event/world/EventCollideSoulSand.class | Bin 0 -> 393 bytes .../api/event/world/EventGetBlockLayer.class | Bin 0 -> 1000 bytes .../api/event/world/EventLandOnSlime.class | Bin 0 -> 381 bytes .../api/event/world/EventLightUpdate.class | Bin 0 -> 385 bytes .../event/world/EventLiquidCollisionBB.class | Bin 0 -> 1131 bytes .../api/event/world/EventSetOpaqueCube.class | Bin 0 -> 387 bytes .../api/event/world/EventWalkOnSlime.class | Bin 0 -> 381 bytes .../seppuku/api/friend/Friend.class | Bin 0 -> 1257 bytes .../api/logging/SeppukuFormatter.class | Bin 0 -> 1031 bytes .../rigamortis/seppuku/api/macro/Macro.class | Bin 0 -> 1039 bytes .../api/module/Module$ModuleType.class | Bin 0 -> 1495 bytes .../seppuku/api/module/Module.class | Bin 0 -> 6719 bytes .../seppuku/api/patch/ClassPatch.class | Bin 0 -> 1517 bytes .../seppuku/api/patch/MethodPatch.class | Bin 0 -> 565 bytes .../rigamortis/seppuku/api/util/ASMUtil.class | Bin 0 -> 3748 bytes .../api/util/GLUProjection$ClampMode.class | Bin 0 -> 1283 bytes .../seppuku/api/util/GLUProjection$Line.class | Bin 0 -> 3373 bytes .../util/GLUProjection$Projection$Type.class | Bin 0 -> 1448 bytes .../api/util/GLUProjection$Projection.class | Bin 0 -> 1261 bytes .../api/util/GLUProjection$Vector3D.class | Bin 0 -> 3529 bytes .../seppuku/api/util/GLUProjection.class | Bin 0 -> 10221 bytes .../seppuku/api/util/MathUtil.class | Bin 0 -> 4740 bytes .../seppuku/api/util/ReflectionUtil.class | Bin 0 -> 2582 bytes .../seppuku/api/util/RenderUtil.class | Bin 0 -> 10392 bytes .../seppuku/api/util/StringUtil.class | Bin 0 -> 2949 bytes .../rigamortis/seppuku/api/util/Timer.class | Bin 0 -> 791 bytes .../seppuku/api/value/BooleanValue.class | Bin 0 -> 990 bytes .../seppuku/api/value/NumberValue.class | Bin 0 -> 3141 bytes .../seppuku/api/value/OptionalValue.class | Bin 0 -> 1922 bytes .../seppuku/api/value/StringValue.class | Bin 0 -> 938 bytes .../rigamortis/seppuku/api/value/Value.class | Bin 0 -> 2552 bytes .../seppuku/impl/command/BindCommand.class | Bin 0 -> 3760 bytes .../seppuku/impl/command/ColorCommand.class | Bin 0 -> 2768 bytes .../seppuku/impl/command/ConnectCommand.class | Bin 0 -> 2443 bytes .../seppuku/impl/command/CoordsCommand.class | Bin 0 -> 2121 bytes .../impl/command/DisconnectCommand.class | Bin 0 -> 1769 bytes .../seppuku/impl/command/DupeCommand.class | Bin 0 -> 1980 bytes .../seppuku/impl/command/FriendCommand.class | Bin 0 -> 5414 bytes .../seppuku/impl/command/HClipCommand.class | Bin 0 -> 2554 bytes .../seppuku/impl/command/HelpCommand.class | Bin 0 -> 3140 bytes .../seppuku/impl/command/HideCommand.class | Bin 0 -> 2576 bytes .../seppuku/impl/command/IPCommand.class | Bin 0 -> 1836 bytes .../seppuku/impl/command/InvSeeCommand.class | Bin 0 -> 3113 bytes .../seppuku/impl/command/MacroCommand.class | Bin 0 -> 5794 bytes .../seppuku/impl/command/ModuleCommand.class | Bin 0 -> 3604 bytes .../seppuku/impl/command/NameCommand.class | Bin 0 -> 1763 bytes .../seppuku/impl/command/PeekCommand.class | Bin 0 -> 5764 bytes .../seppuku/impl/command/PitchCommand.class | Bin 0 -> 1953 bytes .../seppuku/impl/command/ReloadCommand.class | Bin 0 -> 944 bytes .../seppuku/impl/command/SayCommand.class | Bin 0 -> 1482 bytes .../impl/command/SpectateCommand.class | Bin 0 -> 2247 bytes .../seppuku/impl/command/ToggleCommand.class | Bin 0 -> 3581 bytes .../seppuku/impl/command/UnloadCommand.class | Bin 0 -> 891 bytes .../seppuku/impl/command/VClipCommand.class | Bin 0 -> 2256 bytes .../impl/command/WaypointsCommand.class | Bin 0 -> 8524 bytes .../seppuku/impl/command/XrayCommand.class | Bin 0 -> 4522 bytes .../seppuku/impl/command/YawCommand.class | Bin 0 -> 1938 bytes .../seppuku/impl/config/BindConfig.class | Bin 0 -> 3092 bytes .../seppuku/impl/config/ColorConfig.class | Bin 0 -> 3257 bytes .../seppuku/impl/config/FriendConfig.class | Bin 0 -> 2918 bytes .../seppuku/impl/config/HiddenConfig.class | Bin 0 -> 3192 bytes .../seppuku/impl/config/MacroConfig.class | Bin 0 -> 2779 bytes .../seppuku/impl/config/ToggledConfig.class | Bin 0 -> 2909 bytes .../seppuku/impl/config/ValueConfig.class | Bin 0 -> 5337 bytes .../seppuku/impl/config/WaypointsConfig.class | Bin 0 -> 3722 bytes .../seppuku/impl/config/XrayConfig.class | Bin 0 -> 2980 bytes .../seppuku/impl/fml/SeppukuMod.class | Bin 0 -> 1125 bytes .../fml/core/SeppukuAccessTransformer.class | Bin 0 -> 515 bytes .../fml/core/SeppukuClassTransformer.class | Bin 0 -> 5939 bytes .../impl/fml/core/SeppukuLoadingPlugin.class | Bin 0 -> 1827 bytes .../seppuku/impl/management/ChatManager.class | Bin 0 -> 2647 bytes .../impl/management/CommandManager$1.class | Bin 0 -> 6204 bytes .../impl/management/CommandManager.class | Bin 0 -> 8278 bytes .../impl/management/ConfigManager.class | Bin 0 -> 4010 bytes .../impl/management/FriendManager.class | Bin 0 -> 5590 bytes .../impl/management/MacroManager.class | Bin 0 -> 1646 bytes .../impl/management/ModuleManager.class | Bin 0 -> 13069 bytes .../management/PatchManager$Environment.class | Bin 0 -> 1289 bytes .../impl/management/PatchManager.class | Bin 0 -> 5906 bytes .../impl/management/RotationManager.class | Bin 0 -> 1609 bytes .../impl/management/TickRateManager.class | Bin 0 -> 2303 bytes .../impl/management/WaypointManager.class | Bin 0 -> 2034 bytes .../impl/module/combat/AutoArmorModule.class | Bin 0 -> 5552 bytes .../impl/module/combat/AutoTotemModule.class | Bin 0 -> 4442 bytes .../impl/module/combat/BowBombModule.class | Bin 0 -> 3212 bytes .../impl/module/combat/CriticalsModule.class | Bin 0 -> 3915 bytes .../module/combat/CrystalAuraModule.class | Bin 0 -> 12608 bytes .../impl/module/combat/FastBowModule.class | Bin 0 -> 3230 bytes .../impl/module/combat/KillAuraModule.class | Bin 0 -> 8060 bytes .../impl/module/combat/NoCrystalModule.class | Bin 0 -> 9902 bytes .../impl/module/combat/RespawnModule.class | Bin 0 -> 1605 bytes .../impl/module/combat/VelocityModule.class | Bin 0 -> 3721 bytes .../impl/module/hidden/CommandsModule.class | Bin 0 -> 3724 bytes .../impl/module/hidden/KeybindsModule.class | Bin 0 -> 2268 bytes .../impl/module/hidden/MacroModule.class | Bin 0 -> 2549 bytes .../impl/module/misc/AutoFishModule.class | Bin 0 -> 3055 bytes .../impl/module/misc/BreedModule.class | Bin 0 -> 3274 bytes .../impl/module/misc/ChatMutatorModule.class | Bin 0 -> 5385 bytes .../impl/module/misc/ColoredBooksModule.class | Bin 0 -> 1784 bytes .../impl/module/misc/ColoredSignsModule.class | Bin 0 -> 2036 bytes .../impl/module/misc/CoordLoggerModule.class | Bin 0 -> 6525 bytes .../seppuku/impl/module/misc/DyeModule.class | Bin 0 -> 3557 bytes .../impl/module/misc/GreeterModule.class | Bin 0 -> 2741 bytes .../impl/module/misc/LaggerModule.class | Bin 0 -> 8211 bytes .../misc/MiddleClickFriendsModule.class | Bin 0 -> 3551 bytes .../impl/module/misc/MoreInvModule.class | Bin 0 -> 2590 bytes .../impl/module/misc/NoHandShakeModule.class | Bin 0 -> 2524 bytes .../impl/module/misc/NoRotateModule.class | Bin 0 -> 2119 bytes .../impl/module/misc/PortalGuiModule.class | Bin 0 -> 1796 bytes .../impl/module/misc/ReconnectModule.class | Bin 0 -> 3957 bytes .../impl/module/misc/ShearModule.class | Bin 0 -> 3313 bytes .../impl/module/misc/TimeStampModule.class | Bin 0 -> 2026 bytes .../module/movement/ElytraFlyModule.class | Bin 0 -> 5756 bytes .../impl/module/movement/FlightModule.class | Bin 0 -> 9358 bytes .../module/movement/HorseJumpModule.class | Bin 0 -> 1862 bytes .../impl/module/movement/SafeWalkModule.class | Bin 0 -> 3773 bytes .../impl/module/movement/SpeedModule.class | Bin 0 -> 6338 bytes .../impl/module/movement/SprintModule.class | Bin 0 -> 3428 bytes .../impl/module/player/BlinkModule.class | Bin 0 -> 4365 bytes .../impl/module/player/GodModeModule.class | Bin 0 -> 7390 bytes .../impl/module/player/InteractModule.class | Bin 0 -> 6495 bytes .../impl/module/player/ItemSpoofModule.class | Bin 0 -> 5153 bytes .../impl/module/player/NoHungerModule.class | Bin 0 -> 2758 bytes .../impl/module/player/NoPushModule.class | Bin 0 -> 1844 bytes .../impl/module/player/NoSwingModule.class | Bin 0 -> 1199 bytes .../impl/module/player/RotationLock.class | Bin 0 -> 2436 bytes .../impl/module/render/BrightnessModule.class | Bin 0 -> 4797 bytes .../impl/module/render/ChamsModule.class | Bin 0 -> 5322 bytes .../impl/module/render/HudModule.class | Bin 0 -> 12636 bytes .../impl/module/render/NoOverlayModule.class | Bin 0 -> 2865 bytes .../impl/module/render/StorageESPModule.class | Bin 0 -> 10364 bytes .../impl/module/render/TracersModule.class | Bin 0 -> 7842 bytes .../impl/module/render/WallHackModule.class | Bin 0 -> 18399 bytes .../impl/module/render/XrayModule.class | Bin 0 -> 6377 bytes .../impl/module/world/AutoToolModule.class | Bin 0 -> 10307 bytes .../impl/module/world/FastPlaceModule.class | Bin 0 -> 1742 bytes .../impl/module/world/PhaseModule.class | Bin 0 -> 8663 bytes .../impl/module/world/SpeedMineModule.class | Bin 0 -> 6782 bytes .../impl/module/world/TimerModule.class | Bin 0 -> 2572 bytes .../world/WaypointsModule$WaypointData.class | Bin 0 -> 2256 bytes .../impl/module/world/WaypointsModule.class | Bin 0 -> 5876 bytes .../impl/patch/AbstractHorsePatch.class | Bin 0 -> 3137 bytes .../impl/patch/ActiveRenderInfoPatch.class | Bin 0 -> 2000 bytes .../seppuku/impl/patch/BlockFencePatch.class | Bin 0 -> 3373 bytes .../impl/patch/BlockFluidRendererPatch.class | Bin 0 -> 3505 bytes .../seppuku/impl/patch/BlockLiquidPatch.class | Bin 0 -> 5082 bytes .../impl/patch/BlockModelRendererPatch.class | Bin 0 -> 3694 bytes .../seppuku/impl/patch/BlockPanePatch.class | Bin 0 -> 3369 bytes .../seppuku/impl/patch/BlockPatch.class | Bin 0 -> 5435 bytes .../seppuku/impl/patch/BlockSlimePatch.class | Bin 0 -> 3259 bytes .../impl/patch/BlockSoulSandPatch.class | Bin 0 -> 2795 bytes .../seppuku/impl/patch/BlockStairsPatch.class | Bin 0 -> 3377 bytes .../seppuku/impl/patch/EntityLlamaPatch.class | Bin 0 -> 2605 bytes .../seppuku/impl/patch/EntityPatch.class | Bin 0 -> 441 bytes .../seppuku/impl/patch/EntityPigPatch.class | Bin 0 -> 3803 bytes .../impl/patch/EntityPlayerPatch.class | Bin 0 -> 3203 bytes .../impl/patch/EntityPlayerSPPatch.class | Bin 0 -> 9364 bytes .../impl/patch/EntityRendererPatch.class | Bin 0 -> 5682 bytes .../impl/patch/GuiIngameForgePatch.class | Bin 0 -> 4190 bytes .../impl/patch/GuiScreenBookPatch.class | Bin 0 -> 3625 bytes .../impl/patch/ItemRendererPatch.class | Bin 0 -> 3810 bytes .../seppuku/impl/patch/KeyBindingPatch.class | Bin 0 -> 1926 bytes .../seppuku/impl/patch/MinecraftPatch.class | Bin 0 -> 5493 bytes .../impl/patch/NetworkManagerPatch.class | Bin 0 -> 5085 bytes .../impl/patch/PlayerControllerMPPatch.class | Bin 0 -> 8753 bytes .../impl/patch/RenderLivingBasePatch.class | Bin 0 -> 3093 bytes .../impl/patch/RenderManagerPatch.class | Bin 0 -> 4394 bytes .../seppuku/impl/patch/VisGraphPatch.class | Bin 0 -> 2654 bytes .../seppuku/impl/patch/WorldPatch.class | Bin 0 -> 2673 bytes .../seppuku-1.12.2_main/pack.mcmeta | 7 + .../seppuku-1.12.2_main/seppuku_at.cfg | 114 +++ gradle.properties | 3 + gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 54417 bytes gradle/wrapper/gradle-wrapper.properties | 6 + gradlew | 172 +++++ gradlew.bat | 84 +++ lib/json-simple-1.1.1.jar | Bin 0 -> 23931 bytes .../java/me/rigamortis/seppuku/Seppuku.java | 319 +++++++++ .../seppuku/api/animation/Animation.java | 9 + .../rigamortis/seppuku/api/cape/CapeUser.java | 32 + .../seppuku/api/command/Command.java | 100 +++ .../seppuku/api/config/Configurable.java | 27 + .../seppuku/api/event/EventCancellable.java | 31 + .../seppuku/api/event/EventStageable.java | 31 + .../seppuku/api/event/client/EventLoad.java | 7 + .../seppuku/api/event/client/EventReload.java | 8 + .../seppuku/api/event/client/EventUnload.java | 8 + .../api/event/command/EventCommandLoad.java | 24 + .../api/event/entity/EventHorseSaddled.java | 10 + .../api/event/entity/EventPigTravel.java | 10 + .../api/event/entity/EventSteerEntity.java | 10 + .../seppuku/api/event/gui/EventBookPage.java | 22 + .../seppuku/api/event/gui/EventBookTitle.java | 22 + .../api/event/gui/EventRenderHelmet.java | 10 + .../api/event/gui/EventRenderPortal.java | 10 + .../api/event/gui/EventRenderPotions.java | 10 + .../api/event/minecraft/EventDisplayGui.java | 25 + .../api/event/minecraft/EventKeyPress.java | 22 + .../api/event/minecraft/EventRunTick.java | 15 + .../minecraft/EventUpdateFramebufferSize.java | 9 + .../api/event/module/EventModuleLoad.java | 24 + .../api/event/network/EventReceivePacket.java | 26 + .../api/event/network/EventSendPacket.java | 26 + .../api/event/player/EventApplyCollision.java | 10 + .../api/event/player/EventClickBlock.java | 36 + .../api/event/player/EventCloseScreen.java | 10 + .../api/event/player/EventDestroyBlock.java | 25 + .../api/event/player/EventExtendedReach.java | 10 + .../player/EventGetBlockReachDistance.java | 25 + .../event/player/EventHittingPosition.java | 25 + .../seppuku/api/event/player/EventMove.java | 56 ++ .../event/player/EventPlayerDamageBlock.java | 36 + .../api/event/player/EventPlayerJoin.java | 32 + .../api/event/player/EventPlayerLeave.java | 33 + .../api/event/player/EventPlayerUpdate.java | 15 + .../event/player/EventPushOutOfBlocks.java | 10 + .../api/event/player/EventPushedByWater.java | 10 + .../event/player/EventResetBlockRemoving.java | 10 + .../api/event/player/EventRightClick.java | 25 + .../event/player/EventRightClickBlock.java | 58 ++ .../event/player/EventSendChatMessage.java | 24 + .../seppuku/api/event/player/EventStep.java | 8 + .../api/event/player/EventSwingArm.java | 25 + .../api/event/player/EventUpdateInput.java | 8 + .../player/EventUpdateWalkingPlayer.java | 15 + .../api/event/render/EventHurtCamEffect.java | 10 + .../api/event/render/EventOrientCamera.java | 10 + .../api/event/render/EventRender2D.java | 34 + .../api/event/render/EventRender3D.java | 22 + .../event/render/EventRenderBlockModel.java | 98 +++ .../event/render/EventRenderBlockSide.java | 34 + .../event/render/EventRenderBossHealth.java | 10 + .../api/event/render/EventRenderEntity.java | 76 ++ .../api/event/render/EventRenderFluid.java | 67 ++ .../event/render/EventRenderLivingEntity.java | 26 + .../api/event/render/EventRenderName.java | 25 + .../api/event/render/EventRenderOverlay.java | 31 + .../api/event/world/EventAddCollisionBox.java | 36 + .../api/event/world/EventCanCollide.java | 10 + .../api/event/world/EventCollideSoulSand.java | 10 + .../api/event/world/EventFoliageColor.java | 23 + .../api/event/world/EventGetBlockLayer.java | 36 + .../api/event/world/EventGrassColor.java | 23 + .../api/event/world/EventLandOnSlime.java | 10 + .../api/event/world/EventLightUpdate.java | 15 + .../event/world/EventLiquidCollisionBB.java | 39 + .../api/event/world/EventSetOpaqueCube.java | 10 + .../api/event/world/EventWalkOnSlime.java | 10 + .../api/event/world/EventWaterColor.java | 23 + .../rigamortis/seppuku/api/friend/Friend.java | 51 ++ .../hud/component/DraggableHudComponent.java | 278 ++++++++ .../api/gui/hud/component/HudComponent.java | 102 +++ .../hud/component/HudComponentOptions.java | 80 +++ .../seppuku/api/ignore/Ignored.java | 23 + .../seppuku/api/logging/SeppukuFormatter.java | 22 + .../rigamortis/seppuku/api/macro/Macro.java | 42 ++ .../rigamortis/seppuku/api/module/Module.java | 216 ++++++ .../api/notification/Notification.java | 145 ++++ .../seppuku/api/patch/ClassPatch.java | 56 ++ .../seppuku/api/patch/MethodPatch.java | 24 + .../seppuku/api/patch/access/AccessPatch.java | 22 + .../rigamortis/seppuku/api/util/ASMUtil.java | 79 ++ .../seppuku/api/util/ColorUtil.java | 21 + .../seppuku/api/util/GLUProjection.java | 596 ++++++++++++++++ .../rigamortis/seppuku/api/util/ItemUtil.java | 17 + .../rigamortis/seppuku/api/util/MathUtil.java | 139 ++++ .../seppuku/api/util/PotionUtil.java | 25 + .../seppuku/api/util/ReflectionUtil.java | 48 ++ .../seppuku/api/util/RenderUtil.java | 352 +++++++++ .../seppuku/api/util/StringUtil.java | 119 ++++ .../me/rigamortis/seppuku/api/util/Timer.java | 30 + .../seppuku/api/value/BooleanValue.java | 24 + .../seppuku/api/value/NumberValue.java | 74 ++ .../seppuku/api/value/OptionalValue.java | 46 ++ .../seppuku/api/value/StringValue.java | 24 + .../rigamortis/seppuku/api/value/Value.java | 72 ++ .../impl/command/AutoIgnoreCommand.java | 128 ++++ .../seppuku/impl/command/BindCommand.java | 86 +++ .../seppuku/impl/command/ColorCommand.java | 49 ++ .../seppuku/impl/command/ConnectCommand.java | 47 ++ .../seppuku/impl/command/CoordsCommand.java | 35 + .../impl/command/CrashSlimeCommand.java | 62 ++ .../impl/command/DisconnectCommand.java | 44 ++ .../seppuku/impl/command/DupeCommand.java | 35 + .../seppuku/impl/command/EnchantCommand.java | 94 +++ .../seppuku/impl/command/FakeChatCommand.java | 36 + .../impl/command/FindEntityCommand.java | 34 + .../seppuku/impl/command/FriendCommand.java | 131 ++++ .../seppuku/impl/command/GiveCommand.java | 135 ++++ .../seppuku/impl/command/HClipCommand.java | 47 ++ .../seppuku/impl/command/HelpCommand.java | 42 ++ .../seppuku/impl/command/HideCommand.java | 51 ++ .../seppuku/impl/command/IPCommand.java | 39 + .../seppuku/impl/command/IgnoreCommand.java | 113 +++ .../seppuku/impl/command/InvSeeCommand.java | 69 ++ .../impl/command/JavaScriptCommand.java | 79 ++ .../seppuku/impl/command/JoinDateCommand.java | 99 +++ .../seppuku/impl/command/MacroCommand.java | 134 ++++ .../seppuku/impl/command/ModuleCommand.java | 48 ++ .../seppuku/impl/command/NameCommand.java | 34 + .../seppuku/impl/command/PeekCommand.java | 151 ++++ .../seppuku/impl/command/PitchCommand.java | 40 ++ .../seppuku/impl/command/ReloadCommand.java | 26 + .../seppuku/impl/command/RenameCommand.java | 66 ++ .../seppuku/impl/command/SayCommand.java | 28 + .../seppuku/impl/command/SeedCommand.java | 50 ++ .../seppuku/impl/command/SignBookCommand.java | 49 ++ .../seppuku/impl/command/SkullCommand.java | 58 ++ .../seppuku/impl/command/SpawnEggCommand.java | 143 ++++ .../seppuku/impl/command/SpectateCommand.java | 47 ++ .../impl/command/StackSizeCommand.java | 51 ++ .../seppuku/impl/command/TeleportCommand.java | 52 ++ .../seppuku/impl/command/ToggleCommand.java | 87 +++ .../seppuku/impl/command/UnloadCommand.java | 25 + .../seppuku/impl/command/VClipCommand.java | 41 ++ .../impl/command/WaypointsCommand.java | 187 +++++ .../seppuku/impl/command/XrayCommand.java | 162 +++++ .../seppuku/impl/command/YawCommand.java | 41 ++ .../seppuku/impl/config/AutoIgnoreConfig.java | 72 ++ .../seppuku/impl/config/BindConfig.java | 73 ++ .../seppuku/impl/config/ColorConfig.java | 73 ++ .../seppuku/impl/config/FriendConfig.java | 73 ++ .../seppuku/impl/config/HiddenConfig.java | 73 ++ .../seppuku/impl/config/HudConfig.java | 122 ++++ .../seppuku/impl/config/IgnoreConfig.java | 65 ++ .../seppuku/impl/config/MacroConfig.java | 67 ++ .../seppuku/impl/config/ToggledConfig.java | 71 ++ .../seppuku/impl/config/ValueConfig.java | 136 ++++ .../seppuku/impl/config/WaypointsConfig.java | 78 ++ .../seppuku/impl/config/WorldConfig.java | 69 ++ .../seppuku/impl/config/XrayConfig.java | 75 ++ .../seppuku/impl/fml/SeppukuMod.java | 26 + .../fml/core/SeppukuAccessTransformer.java | 17 + .../fml/core/SeppukuClassTransformer.java | 146 ++++ .../impl/fml/core/SeppukuLoadingPlugin.java | 43 ++ .../seppuku/impl/gui/hud/GuiHudEditor.java | 130 ++++ .../impl/gui/hud/anchor/AnchorPoint.java | 48 ++ .../gui/hud/component/ArmorComponent.java | 44 ++ .../gui/hud/component/ArrayListComponent.java | 99 +++ .../gui/hud/component/BiomeComponent.java | 35 + .../gui/hud/component/CompassComponent.java | 87 +++ .../gui/hud/component/CoordsComponent.java | 36 + .../gui/hud/component/DirectionComponent.java | 73 ++ .../hud/component/EnemyPotionsComponent.java | 108 +++ .../impl/gui/hud/component/FpsComponent.java | 28 + .../gui/hud/component/HelloComponent.java | 33 + .../impl/gui/hud/component/HubComponent.java | 119 ++++ .../gui/hud/component/InventoryComponent.java | 45 ++ .../hud/component/NetherCoordsComponent.java | 41 ++ .../hud/component/NotificationsComponent.java | 59 ++ .../hud/component/PacketTimeComponent.java | 48 ++ .../impl/gui/hud/component/PingComponent.java | 32 + .../hud/component/PotionEffectsComponent.java | 95 +++ .../hud/component/ServerBrandComponent.java | 28 + .../gui/hud/component/SpeedComponent.java | 38 + .../impl/gui/hud/component/TimeComponent.java | 31 + .../hud/component/TotemCountComponent.java | 43 ++ .../impl/gui/hud/component/TpsComponent.java | 31 + .../gui/hud/component/TutorialComponent.java | 75 ++ .../gui/hud/component/WatermarkComponent.java | 29 + .../impl/gui/menu/GuiSeppukuMainMenu.java | 196 +++++ .../seppuku/impl/gui/menu/MainMenuButton.java | 111 +++ .../impl/management/AnimationManager.java | 52 ++ .../seppuku/impl/management/CapeManager.java | 145 ++++ .../seppuku/impl/management/ChatManager.java | 62 ++ .../impl/management/CommandManager.java | 315 ++++++++ .../impl/management/ConfigManager.java | 84 +++ .../impl/management/FriendManager.java | 143 ++++ .../seppuku/impl/management/HudManager.java | 232 ++++++ .../impl/management/IgnoredManager.java | 42 ++ .../impl/management/JoinLeaveManager.java | 92 +++ .../seppuku/impl/management/MacroManager.java | 40 ++ .../impl/management/ModuleManager.java | 280 ++++++++ .../impl/management/NotificationManager.java | 52 ++ .../seppuku/impl/management/PatchManager.java | 144 ++++ .../impl/management/PositionManager.java | 56 ++ .../impl/management/RotationManager.java | 55 ++ .../impl/management/TickRateManager.java | 64 ++ .../impl/management/WaypointManager.java | 36 + .../seppuku/impl/management/WorldManager.java | 65 ++ .../impl/module/combat/AutoArmorModule.java | 120 ++++ .../module/combat/AutoDisconnectModule.java | 33 + .../impl/module/combat/AutoTotemModule.java | 84 +++ .../impl/module/combat/BowBombModule.java | 41 ++ .../impl/module/combat/CriticalsModule.java | 56 ++ .../impl/module/combat/CrystalAuraModule.java | 289 ++++++++ .../impl/module/combat/FastBowModule.java | 38 + .../impl/module/combat/KillAuraModule.java | 141 ++++ .../impl/module/combat/NoCrystalModule.java | 251 +++++++ .../module/combat/ObsidianReplaceModule.java | 357 ++++++++++ .../impl/module/combat/RegenModule.java | 124 ++++ .../impl/module/combat/RespawnModule.java | 26 + .../impl/module/combat/VelocityModule.java | 68 ++ .../impl/module/hidden/CommandsModule.java | 69 ++ .../impl/module/hidden/IgnoreModule.java | 53 ++ .../impl/module/hidden/KeybindsModule.java | 33 + .../impl/module/hidden/MacroModule.java | 36 + .../impl/module/misc/AutoCraftModule.java | 53 ++ .../impl/module/misc/AutoFishModule.java | 49 ++ .../impl/module/misc/AutoIgnoreModule.java | 94 +++ .../impl/module/misc/AutoSignModule.java | 78 ++ .../seppuku/impl/module/misc/BreedModule.java | 39 + .../impl/module/misc/BuildHeightModule.java | 32 + .../impl/module/misc/ChatFilterModule.java | 103 +++ .../impl/module/misc/ChatMutatorModule.java | 136 ++++ .../module/misc/ChatTimeStampsModule.java | 57 ++ .../impl/module/misc/ChestAlertModule.java | 49 ++ .../impl/module/misc/ColoredBooksModule.java | 28 + .../impl/module/misc/ColoredSignsModule.java | 30 + .../impl/module/misc/CoordLoggerModule.java | 111 +++ .../impl/module/misc/DiscordBypassModule.java | 60 ++ .../seppuku/impl/module/misc/DyeModule.java | 45 ++ .../impl/module/misc/GreeterModule.java | 50 ++ .../impl/module/misc/LaggerModule.java | 112 +++ .../impl/module/misc/MapBypassModule.java | 35 + .../module/misc/MiddleClickFriendsModule.java | 59 ++ .../impl/module/misc/MoreInvModule.java | 42 ++ .../seppuku/impl/module/misc/NoAfkModule.java | 44 ++ .../impl/module/misc/NoBiomeColorModule.java | 132 ++++ .../impl/module/misc/NoDesyncModule.java | 47 ++ .../module/misc/NoGlobalSoundsModule.java | 42 ++ .../impl/module/misc/NoHandShakeModule.java | 38 + .../impl/module/misc/NoRotateModule.java | 33 + .../impl/module/misc/PacketLoggerModule.java | 171 +++++ .../impl/module/misc/PortalGuiModule.java | 26 + .../impl/module/misc/ReconnectModule.java | 69 ++ .../seppuku/impl/module/misc/ShearModule.java | 42 ++ .../impl/module/misc/TimeStampModule.java | 35 + .../impl/module/misc/VanillaTabModule.java | 28 + .../impl/module/movement/AutoWalkModule.java | 37 + .../impl/module/movement/ElytraFlyModule.java | 115 +++ .../module/movement/EntityControlModule.java | 46 ++ .../impl/module/movement/FlightModule.java | 234 ++++++ .../impl/module/movement/GuiMoveModule.java | 62 ++ .../impl/module/movement/HorseJumpModule.java | 27 + .../impl/module/movement/JesusModule.java | 159 +++++ .../impl/module/movement/NoFallModule.java | 30 + .../module/movement/NoSlowDownModule.java | 110 +++ .../impl/module/movement/NoVoidModule.java | 48 ++ .../impl/module/movement/SafeWalkModule.java | 82 +++ .../impl/module/movement/ScaffoldModule.java | 314 ++++++++ .../impl/module/movement/SneakModule.java | 81 +++ .../impl/module/movement/SpeedModule.java | 142 ++++ .../impl/module/movement/SprintModule.java | 56 ++ .../impl/module/movement/StepModule.java | 84 +++ .../impl/module/movement/StrafeModule.java | 85 +++ .../impl/module/player/BlinkModule.java | 76 ++ .../impl/module/player/FreeCamModule.java | 219 ++++++ .../impl/module/player/GodModeModule.java | 152 ++++ .../impl/module/player/InteractModule.java | 117 +++ .../impl/module/player/ItemSpoofModule.java | 101 +++ .../impl/module/player/NoHungerModule.java | 43 ++ .../impl/module/player/NoPushModule.java | 36 + .../impl/module/player/NoSwingModule.java | 22 + .../impl/module/player/RotationLock.java | 48 ++ .../module/render/BlockHighlightModule.java | 41 ++ .../impl/module/render/BrightnessModule.java | 108 +++ .../impl/module/render/ChamsModule.java | 180 +++++ .../impl/module/render/HolesModule.java | 168 +++++ .../seppuku/impl/module/render/HudModule.java | 56 ++ .../module/render/NoBossHealthModule.java | 20 + .../impl/module/render/NoBreakAnimModule.java | 24 + .../impl/module/render/NoHurtCamModule.java | 22 + .../impl/module/render/NoLagModule.java | 101 +++ .../impl/module/render/NoOverlayModule.java | 53 ++ .../impl/module/render/ProjectilesModule.java | 496 +++++++++++++ .../impl/module/render/SmallShieldModule.java | 26 + .../impl/module/render/StorageESPModule.java | 262 +++++++ .../impl/module/render/TracersModule.java | 145 ++++ .../impl/module/render/ViewClipModule.java | 22 + .../impl/module/render/WallHackModule.java | 578 +++++++++++++++ .../impl/module/render/XrayModule.java | 138 ++++ .../impl/module/ui/HudEditorModule.java | 34 + .../impl/module/world/AutoToolModule.java | 237 ++++++ .../impl/module/world/FastPlaceModule.java | 32 + .../module/world/LiquidInteractModule.java | 22 + .../impl/module/world/NewChunksModule.java | 98 +++ .../impl/module/world/NoChunkModule.java | 28 + .../impl/module/world/NoWeatherModule.java | 44 ++ .../impl/module/world/NukerModule.java | 143 ++++ .../impl/module/world/PhaseModule.java | 188 +++++ .../impl/module/world/SlimeChunksModule.java | 113 +++ .../impl/module/world/SpeedMineModule.java | 117 +++ .../impl/module/world/TimerModule.java | 40 ++ .../impl/module/world/WaypointsModule.java | 137 ++++ .../impl/patch/AbstractClientPlayerPatch.java | 42 ++ .../impl/patch/AbstractHorsePatch.java | 107 +++ .../impl/patch/ActiveRenderInfoPatch.java | 49 ++ .../impl/patch/BiomeColorHelperPatch.java | 113 +++ .../seppuku/impl/patch/BlockFencePatch.java | 59 ++ .../impl/patch/BlockFluidRendererPatch.java | 80 +++ .../seppuku/impl/patch/BlockLiquidPatch.java | 146 ++++ .../impl/patch/BlockModelRendererPatch.java | 83 +++ .../seppuku/impl/patch/BlockPanePatch.java | 59 ++ .../seppuku/impl/patch/BlockPatch.java | 173 +++++ .../seppuku/impl/patch/BlockSlimePatch.java | 104 +++ .../impl/patch/BlockSoulSandPatch.java | 64 ++ .../seppuku/impl/patch/BlockStairsPatch.java | 59 ++ .../seppuku/impl/patch/EntityLlamaPatch.java | 63 ++ .../seppuku/impl/patch/EntityPatch.java | 31 + .../seppuku/impl/patch/EntityPigPatch.java | 103 +++ .../seppuku/impl/patch/EntityPlayerPatch.java | 110 +++ .../impl/patch/EntityPlayerSPPatch.java | 382 ++++++++++ .../impl/patch/EntityRendererPatch.java | 174 +++++ .../impl/patch/GuiBossOverlayPatch.java | 48 ++ .../impl/patch/GuiIngameForgePatch.java | 148 ++++ .../impl/patch/GuiScreenBookPatch.java | 102 +++ .../seppuku/impl/patch/ItemRendererPatch.java | 107 +++ .../seppuku/impl/patch/KeyBindingPatch.java | 52 ++ .../seppuku/impl/patch/MinecraftPatch.java | 172 +++++ .../impl/patch/NetworkManagerPatch.java | 147 ++++ .../impl/patch/PlayerControllerMPPatch.java | 355 +++++++++ .../impl/patch/RenderLivingBasePatch.java | 128 ++++ .../impl/patch/RenderManagerPatch.java | 109 +++ .../seppuku/impl/patch/VisGraphPatch.java | 62 ++ .../seppuku/impl/patch/WorldPatch.java | 61 ++ .../java/team/stiff/pomelo/EventManager.java | 51 ++ .../pomelo/dispatch/EventDispatcher.java | 19 + .../team/stiff/pomelo/filter/EventFilter.java | 24 + .../pomelo/filter/EventFilterScanner.java | 20 + .../stiff/pomelo/handler/EventHandler.java | 34 + .../handler/scan/EventHandlerScanner.java | 24 + .../impl/annotated/AnnotatedEventManager.java | 75 ++ .../dispatch/MethodEventDispatcher.java | 36 + .../annotated/filter/MethodFilterScanner.java | 34 + .../annotated/handler/MethodEventHandler.java | 69 ++ .../handler/annotation/Listener.java | 29 + .../handler/scan/MethodHandlerScanner.java | 41 ++ src/main/resources/mcmod.info | 16 + src/main/resources/pack.mcmeta | 7 + src/main/resources/seppuku_at.cfg | 116 +++ 588 files changed, 28047 insertions(+) create mode 100644 .gitignore create mode 100644 .gitlab-ci.yml create mode 100644 LICENSE create mode 100644 README.md create mode 100644 build.gradle create mode 100644 classes/production/seppuku-1.12.2_main/mcmod.info create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/Seppuku.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/command/Command.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/config/Configurable.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/EventCancellable.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/EventStageable$EventStage.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/EventStageable.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/entity/EventHorseSaddled.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/entity/EventSteerEntity.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/gui/EventBookPage.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/gui/EventBookTitle.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/gui/EventRenderHelmet.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/gui/EventRenderPortal.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/gui/EventRenderPotions.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/minecraft/EventDisplayGui.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/minecraft/EventKeyPress.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/minecraft/EventRunTick.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/minecraft/EventUpdateFramebufferSize.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/network/EventReceivePacket.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/network/EventSendPacket.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/player/EventApplyCollision.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/player/EventClickBlock.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/player/EventCloseScreen.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/player/EventDestroyBlock.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/player/EventExtendedReach.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/player/EventGetBlockReachDistance.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/player/EventHittingPosition.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/player/EventMove.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/player/EventPlayerDamageBlock.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/player/EventPlayerUpdate.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/player/EventPushOutOfBlocks.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/player/EventPushedByWater.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/player/EventResetBlockRemoving.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/player/EventRightClick.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/player/EventRightClickBlock.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/player/EventSendChatMessage.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/player/EventStep.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/player/EventSwingArm.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/player/EventUpdateInput.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/player/EventUpdateWalkingPlayer.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/render/EventHurtCamEffect.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/render/EventRender2D.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/render/EventRender3D.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/render/EventRenderBlockModel.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/render/EventRenderBlockSide.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/render/EventRenderEntity.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/render/EventRenderFluid.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/render/EventRenderLivingEntity.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/render/EventRenderName.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/render/EventRenderOverlay$OverlayType.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/render/EventRenderOverlay.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/world/EventAddCollisionBox.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/world/EventCollideSoulSand.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/world/EventGetBlockLayer.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/world/EventLandOnSlime.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/world/EventLightUpdate.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/world/EventLiquidCollisionBB.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/world/EventSetOpaqueCube.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/world/EventWalkOnSlime.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/friend/Friend.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/logging/SeppukuFormatter.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/macro/Macro.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/module/Module$ModuleType.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/module/Module.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/patch/ClassPatch.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/patch/MethodPatch.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/util/ASMUtil.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/util/GLUProjection$ClampMode.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/util/GLUProjection$Line.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/util/GLUProjection$Projection$Type.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/util/GLUProjection$Projection.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/util/GLUProjection$Vector3D.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/util/GLUProjection.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/util/MathUtil.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/util/ReflectionUtil.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/util/RenderUtil.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/util/StringUtil.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/util/Timer.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/value/BooleanValue.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/value/NumberValue.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/value/OptionalValue.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/value/StringValue.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/value/Value.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/BindCommand.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/ColorCommand.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/ConnectCommand.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/CoordsCommand.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/DisconnectCommand.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/DupeCommand.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/FriendCommand.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/HClipCommand.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/HelpCommand.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/HideCommand.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/IPCommand.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/InvSeeCommand.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/MacroCommand.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/ModuleCommand.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/NameCommand.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/PeekCommand.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/PitchCommand.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/ReloadCommand.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/SayCommand.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/SpectateCommand.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/ToggleCommand.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/UnloadCommand.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/VClipCommand.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/WaypointsCommand.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/XrayCommand.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/YawCommand.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/config/BindConfig.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/config/ColorConfig.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/config/FriendConfig.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/config/HiddenConfig.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/config/MacroConfig.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/config/ToggledConfig.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/config/ValueConfig.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/config/WaypointsConfig.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/config/XrayConfig.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/fml/SeppukuMod.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/fml/core/SeppukuAccessTransformer.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/fml/core/SeppukuClassTransformer.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/fml/core/SeppukuLoadingPlugin.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/management/ChatManager.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/management/CommandManager$1.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/management/CommandManager.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/management/ConfigManager.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/management/FriendManager.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/management/MacroManager.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/management/ModuleManager.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/management/PatchManager$Environment.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/management/PatchManager.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/management/RotationManager.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/management/TickRateManager.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/management/WaypointManager.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/combat/AutoArmorModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/combat/AutoTotemModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/combat/BowBombModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/combat/CriticalsModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/combat/CrystalAuraModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/combat/FastBowModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/combat/KillAuraModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/combat/NoCrystalModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/combat/RespawnModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/combat/VelocityModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/hidden/CommandsModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/hidden/KeybindsModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/hidden/MacroModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/misc/AutoFishModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/misc/BreedModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/misc/ChatMutatorModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/misc/ColoredBooksModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/misc/ColoredSignsModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/misc/CoordLoggerModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/misc/DyeModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/misc/GreeterModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/misc/LaggerModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/misc/MiddleClickFriendsModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/misc/MoreInvModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/misc/NoHandShakeModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/misc/NoRotateModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/misc/PortalGuiModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/misc/ReconnectModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/misc/ShearModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/misc/TimeStampModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/movement/ElytraFlyModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/movement/FlightModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/movement/HorseJumpModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/movement/SafeWalkModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/movement/SpeedModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/movement/SprintModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/player/BlinkModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/player/GodModeModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/player/InteractModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/player/ItemSpoofModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/player/NoHungerModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/player/NoPushModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/player/NoSwingModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/player/RotationLock.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/render/BrightnessModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/render/ChamsModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/render/HudModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/render/NoOverlayModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/render/StorageESPModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/render/TracersModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/render/WallHackModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/render/XrayModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/world/AutoToolModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/world/FastPlaceModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/world/PhaseModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/world/SpeedMineModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/world/TimerModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/world/WaypointsModule$WaypointData.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/world/WaypointsModule.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/AbstractHorsePatch.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/ActiveRenderInfoPatch.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/BlockFencePatch.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/BlockFluidRendererPatch.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/BlockLiquidPatch.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/BlockModelRendererPatch.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/BlockPanePatch.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/BlockPatch.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/BlockSlimePatch.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/BlockSoulSandPatch.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/BlockStairsPatch.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/EntityLlamaPatch.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/EntityPatch.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/EntityPigPatch.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/EntityPlayerPatch.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/EntityPlayerSPPatch.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/EntityRendererPatch.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/GuiIngameForgePatch.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/GuiScreenBookPatch.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/ItemRendererPatch.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/KeyBindingPatch.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/MinecraftPatch.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/NetworkManagerPatch.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/PlayerControllerMPPatch.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/RenderLivingBasePatch.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/RenderManagerPatch.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/VisGraphPatch.class create mode 100644 classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/WorldPatch.class create mode 100644 classes/production/seppuku-1.12.2_main/pack.mcmeta create mode 100644 classes/production/seppuku-1.12.2_main/seppuku_at.cfg create mode 100644 gradle.properties create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100644 gradlew create mode 100644 gradlew.bat create mode 100644 lib/json-simple-1.1.1.jar create mode 100644 src/main/java/me/rigamortis/seppuku/Seppuku.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/animation/Animation.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/cape/CapeUser.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/command/Command.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/config/Configurable.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/EventCancellable.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/EventStageable.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/client/EventLoad.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/client/EventReload.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/client/EventUnload.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/command/EventCommandLoad.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/entity/EventHorseSaddled.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/entity/EventPigTravel.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/entity/EventSteerEntity.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/gui/EventBookPage.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/gui/EventBookTitle.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/gui/EventRenderHelmet.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/gui/EventRenderPortal.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/gui/EventRenderPotions.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/minecraft/EventDisplayGui.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/minecraft/EventKeyPress.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/minecraft/EventRunTick.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/minecraft/EventUpdateFramebufferSize.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/module/EventModuleLoad.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/network/EventReceivePacket.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/network/EventSendPacket.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/player/EventApplyCollision.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/player/EventClickBlock.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/player/EventCloseScreen.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/player/EventDestroyBlock.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/player/EventExtendedReach.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/player/EventGetBlockReachDistance.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/player/EventHittingPosition.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/player/EventMove.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/player/EventPlayerDamageBlock.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/player/EventPlayerJoin.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/player/EventPlayerLeave.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/player/EventPlayerUpdate.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/player/EventPushOutOfBlocks.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/player/EventPushedByWater.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/player/EventResetBlockRemoving.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/player/EventRightClick.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/player/EventRightClickBlock.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/player/EventSendChatMessage.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/player/EventStep.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/player/EventSwingArm.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/player/EventUpdateInput.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/player/EventUpdateWalkingPlayer.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/render/EventHurtCamEffect.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/render/EventOrientCamera.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/render/EventRender2D.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/render/EventRender3D.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/render/EventRenderBlockModel.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/render/EventRenderBlockSide.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/render/EventRenderBossHealth.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/render/EventRenderEntity.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/render/EventRenderFluid.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/render/EventRenderLivingEntity.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/render/EventRenderName.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/render/EventRenderOverlay.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/world/EventAddCollisionBox.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/world/EventCanCollide.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/world/EventCollideSoulSand.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/world/EventFoliageColor.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/world/EventGetBlockLayer.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/world/EventGrassColor.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/world/EventLandOnSlime.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/world/EventLightUpdate.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/world/EventLiquidCollisionBB.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/world/EventSetOpaqueCube.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/world/EventWalkOnSlime.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/event/world/EventWaterColor.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/friend/Friend.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/gui/hud/component/DraggableHudComponent.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/gui/hud/component/HudComponent.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/gui/hud/component/HudComponentOptions.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/ignore/Ignored.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/logging/SeppukuFormatter.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/macro/Macro.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/module/Module.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/notification/Notification.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/patch/ClassPatch.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/patch/MethodPatch.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/patch/access/AccessPatch.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/util/ASMUtil.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/util/ColorUtil.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/util/GLUProjection.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/util/ItemUtil.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/util/MathUtil.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/util/PotionUtil.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/util/ReflectionUtil.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/util/RenderUtil.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/util/StringUtil.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/util/Timer.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/value/BooleanValue.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/value/NumberValue.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/value/OptionalValue.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/value/StringValue.java create mode 100644 src/main/java/me/rigamortis/seppuku/api/value/Value.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/command/AutoIgnoreCommand.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/command/BindCommand.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/command/ColorCommand.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/command/ConnectCommand.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/command/CoordsCommand.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/command/CrashSlimeCommand.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/command/DisconnectCommand.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/command/DupeCommand.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/command/EnchantCommand.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/command/FakeChatCommand.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/command/FindEntityCommand.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/command/FriendCommand.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/command/GiveCommand.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/command/HClipCommand.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/command/HelpCommand.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/command/HideCommand.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/command/IPCommand.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/command/IgnoreCommand.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/command/InvSeeCommand.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/command/JavaScriptCommand.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/command/JoinDateCommand.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/command/MacroCommand.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/command/ModuleCommand.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/command/NameCommand.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/command/PeekCommand.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/command/PitchCommand.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/command/ReloadCommand.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/command/RenameCommand.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/command/SayCommand.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/command/SeedCommand.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/command/SignBookCommand.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/command/SkullCommand.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/command/SpawnEggCommand.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/command/SpectateCommand.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/command/StackSizeCommand.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/command/TeleportCommand.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/command/ToggleCommand.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/command/UnloadCommand.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/command/VClipCommand.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/command/WaypointsCommand.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/command/XrayCommand.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/command/YawCommand.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/config/AutoIgnoreConfig.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/config/BindConfig.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/config/ColorConfig.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/config/FriendConfig.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/config/HiddenConfig.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/config/HudConfig.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/config/IgnoreConfig.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/config/MacroConfig.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/config/ToggledConfig.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/config/ValueConfig.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/config/WaypointsConfig.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/config/WorldConfig.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/config/XrayConfig.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/fml/SeppukuMod.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/fml/core/SeppukuAccessTransformer.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/fml/core/SeppukuClassTransformer.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/fml/core/SeppukuLoadingPlugin.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/gui/hud/GuiHudEditor.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/gui/hud/anchor/AnchorPoint.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/gui/hud/component/ArmorComponent.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/gui/hud/component/ArrayListComponent.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/gui/hud/component/BiomeComponent.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/gui/hud/component/CompassComponent.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/gui/hud/component/CoordsComponent.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/gui/hud/component/DirectionComponent.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/gui/hud/component/EnemyPotionsComponent.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/gui/hud/component/FpsComponent.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/gui/hud/component/HelloComponent.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/gui/hud/component/HubComponent.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/gui/hud/component/InventoryComponent.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/gui/hud/component/NetherCoordsComponent.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/gui/hud/component/NotificationsComponent.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/gui/hud/component/PacketTimeComponent.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/gui/hud/component/PingComponent.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/gui/hud/component/PotionEffectsComponent.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/gui/hud/component/ServerBrandComponent.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/gui/hud/component/SpeedComponent.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/gui/hud/component/TimeComponent.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/gui/hud/component/TotemCountComponent.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/gui/hud/component/TpsComponent.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/gui/hud/component/TutorialComponent.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/gui/hud/component/WatermarkComponent.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/gui/menu/GuiSeppukuMainMenu.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/gui/menu/MainMenuButton.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/management/AnimationManager.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/management/CapeManager.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/management/ChatManager.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/management/CommandManager.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/management/ConfigManager.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/management/FriendManager.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/management/HudManager.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/management/IgnoredManager.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/management/JoinLeaveManager.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/management/MacroManager.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/management/ModuleManager.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/management/NotificationManager.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/management/PatchManager.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/management/PositionManager.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/management/RotationManager.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/management/TickRateManager.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/management/WaypointManager.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/management/WorldManager.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/combat/AutoArmorModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/combat/AutoDisconnectModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/combat/AutoTotemModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/combat/BowBombModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/combat/CriticalsModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/combat/CrystalAuraModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/combat/FastBowModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/combat/KillAuraModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/combat/NoCrystalModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/combat/ObsidianReplaceModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/combat/RegenModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/combat/RespawnModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/combat/VelocityModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/hidden/CommandsModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/hidden/IgnoreModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/hidden/KeybindsModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/hidden/MacroModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/misc/AutoCraftModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/misc/AutoFishModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/misc/AutoIgnoreModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/misc/AutoSignModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/misc/BreedModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/misc/BuildHeightModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/misc/ChatFilterModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/misc/ChatMutatorModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/misc/ChatTimeStampsModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/misc/ChestAlertModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/misc/ColoredBooksModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/misc/ColoredSignsModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/misc/CoordLoggerModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/misc/DiscordBypassModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/misc/DyeModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/misc/GreeterModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/misc/LaggerModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/misc/MapBypassModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/misc/MiddleClickFriendsModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/misc/MoreInvModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/misc/NoAfkModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/misc/NoBiomeColorModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/misc/NoDesyncModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/misc/NoGlobalSoundsModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/misc/NoHandShakeModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/misc/NoRotateModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/misc/PacketLoggerModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/misc/PortalGuiModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/misc/ReconnectModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/misc/ShearModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/misc/TimeStampModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/misc/VanillaTabModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/movement/AutoWalkModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/movement/ElytraFlyModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/movement/EntityControlModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/movement/FlightModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/movement/GuiMoveModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/movement/HorseJumpModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/movement/JesusModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/movement/NoFallModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/movement/NoSlowDownModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/movement/NoVoidModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/movement/SafeWalkModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/movement/ScaffoldModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/movement/SneakModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/movement/SpeedModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/movement/SprintModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/movement/StepModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/movement/StrafeModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/player/BlinkModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/player/FreeCamModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/player/GodModeModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/player/InteractModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/player/ItemSpoofModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/player/NoHungerModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/player/NoPushModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/player/NoSwingModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/player/RotationLock.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/render/BlockHighlightModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/render/BrightnessModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/render/ChamsModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/render/HolesModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/render/HudModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/render/NoBossHealthModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/render/NoBreakAnimModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/render/NoHurtCamModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/render/NoLagModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/render/NoOverlayModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/render/ProjectilesModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/render/SmallShieldModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/render/StorageESPModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/render/TracersModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/render/ViewClipModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/render/WallHackModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/render/XrayModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/ui/HudEditorModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/world/AutoToolModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/world/FastPlaceModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/world/LiquidInteractModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/world/NewChunksModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/world/NoChunkModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/world/NoWeatherModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/world/NukerModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/world/PhaseModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/world/SlimeChunksModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/world/SpeedMineModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/world/TimerModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/module/world/WaypointsModule.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/patch/AbstractClientPlayerPatch.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/patch/AbstractHorsePatch.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/patch/ActiveRenderInfoPatch.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/patch/BiomeColorHelperPatch.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/patch/BlockFencePatch.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/patch/BlockFluidRendererPatch.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/patch/BlockLiquidPatch.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/patch/BlockModelRendererPatch.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/patch/BlockPanePatch.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/patch/BlockPatch.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/patch/BlockSlimePatch.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/patch/BlockSoulSandPatch.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/patch/BlockStairsPatch.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/patch/EntityLlamaPatch.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/patch/EntityPatch.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/patch/EntityPigPatch.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/patch/EntityPlayerPatch.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/patch/EntityPlayerSPPatch.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/patch/EntityRendererPatch.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/patch/GuiBossOverlayPatch.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/patch/GuiIngameForgePatch.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/patch/GuiScreenBookPatch.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/patch/ItemRendererPatch.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/patch/KeyBindingPatch.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/patch/MinecraftPatch.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/patch/NetworkManagerPatch.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/patch/PlayerControllerMPPatch.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/patch/RenderLivingBasePatch.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/patch/RenderManagerPatch.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/patch/VisGraphPatch.java create mode 100644 src/main/java/me/rigamortis/seppuku/impl/patch/WorldPatch.java create mode 100644 src/main/java/team/stiff/pomelo/EventManager.java create mode 100644 src/main/java/team/stiff/pomelo/dispatch/EventDispatcher.java create mode 100644 src/main/java/team/stiff/pomelo/filter/EventFilter.java create mode 100644 src/main/java/team/stiff/pomelo/filter/EventFilterScanner.java create mode 100644 src/main/java/team/stiff/pomelo/handler/EventHandler.java create mode 100644 src/main/java/team/stiff/pomelo/handler/scan/EventHandlerScanner.java create mode 100644 src/main/java/team/stiff/pomelo/impl/annotated/AnnotatedEventManager.java create mode 100644 src/main/java/team/stiff/pomelo/impl/annotated/dispatch/MethodEventDispatcher.java create mode 100644 src/main/java/team/stiff/pomelo/impl/annotated/filter/MethodFilterScanner.java create mode 100644 src/main/java/team/stiff/pomelo/impl/annotated/handler/MethodEventHandler.java create mode 100644 src/main/java/team/stiff/pomelo/impl/annotated/handler/annotation/Listener.java create mode 100644 src/main/java/team/stiff/pomelo/impl/annotated/handler/scan/MethodHandlerScanner.java create mode 100644 src/main/resources/mcmod.info create mode 100644 src/main/resources/pack.mcmeta create mode 100644 src/main/resources/seppuku_at.cfg diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2c770e0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,22 @@ +# eclipse +bin +*.launch +.settings +.metadata +.classpath +.project + +# idea +out +*.ipr +*.iws +*.iml +.idea + +# gradle +build +.gradle + +# other +eclipse +run diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..701fa55 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,31 @@ +image: java:8 + +# Disable the Gradle daemon for Continuous Integration servers as correctness +# is usually a priority over speed in CI environments. Using a fresh +# runtime for each build is more reliable since the runtime is completely +# isolated from any previous builds. + +# TODO: work out shadowjar nonsense +variables: + GRADLE_OPTS: "-Dorg.gradle.daemon=false" + +before_script: + - export GRADLE_USER_HOME=`pwd`/.gradle + +build: + stage: build + script: + - sed -i 's/IDE/RELEASE/g' src/main/java/me/rigamortis/seppuku/impl/fml/core/SeppukuClassTransformer.java + - chmod +x gradlew + - ./gradlew setupDecompWorkspace + - ./gradlew build + artifacts: + paths: + - build/libs/*.jar + expire_in: 1 month + cache: + key: "$CI_COMMIT_REF_NAME" + policy: push + paths: + - build + - .gradle diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..3e4674c --- /dev/null +++ b/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + Seppuku-MC 1.12.2 + Copyright (C) 2019 riga + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Seppuku-MC 1.12.2 Copyright (C) 2019 riga + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/README.md b/README.md new file mode 100644 index 0000000..e428049 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +strong hack \ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..42c1b62 --- /dev/null +++ b/build.gradle @@ -0,0 +1,120 @@ +buildscript { + repositories { + jcenter() + + maven { + url = "http://files.minecraftforge.net/maven" + } + } + + dependencies { + classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT' + classpath "com.github.jengelman.gradle.plugins:shadow:1.2.3" + } +} + +apply plugin: 'net.minecraftforge.gradle.forge' +//Only edit below this line, the above code adds and enables the necessary things for Forge to be setup. + +apply plugin: "com.github.johnrengelman.shadow" + +version = "1.0" +group = "com.yourname.modid" // http://maven.apache.org/guides/mini/guide-naming-conventions.html +archivesBaseName = "seppuku-1.12.2" + +sourceCompatibility = targetCompatibility = '1.8' // Need this here so eclipse task generates correctly. +compileJava { + sourceCompatibility = targetCompatibility = '1.8' +} + +minecraft { + version = "1.12.2-14.23.5.2768" + runDir = "run" + + // the mappings can be changed at any time, and must be in the following format. + // snapshot_YYYYMMDD snapshot are built nightly. + // stable_# stables are built at the discretion of the MCP team. + // Use non-default mappings at your own risk. they may not always work. + // simply re-run your setup task after changing the mappings to update your workspace. + mappings = "snapshot_20171003" + // makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable. +} + +dependencies { + compile files('lib/json-simple-1.1.1.jar') +} + +jar { + manifest { + attributes 'FMLCorePlugin': 'me.rigamortis.seppuku.impl.fml.core.SeppukuLoadingPlugin' + attributes 'FMLCorePluginContainsFMLMod': 'true' + attributes 'FMLAT': 'seppuku_at.cfg' + } +} + +reobf { + jar { + mappingType = 'SEARGE' + } + + shadowJar { + //mappingType = 'NOTCH' + mappingType = 'SEARGE' + classpath = sourceSets.main.compileClasspath + } +} + +shadowJar { + dependencies { + include(dependency('org.json.simple:parser')) + include(dependency('net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT')) + } + + manifest { + attributes 'FMLCorePlugin': 'me.rigamortis.seppuku.impl.fml.core.SeppukuLoadingPlugin' + attributes 'FMLCorePluginContainsFMLMod': 'true' + attributes 'FMLAT': 'seppuku_at.cfg' + } + + exclude 'dummyThing' + exclude 'LICENSE.txt' + classifier = 'full' +} + +task signJar(type: SignJar, dependsOn: reobfJar) { + onlyIf { + project.hasProperty('keyStore') + } + + keyStore = project.findProperty('keyStore') + alias = project.findProperty('keyStoreAlias') + storePass = project.findProperty('keyStorePass') + keyPass = project.findProperty('keyStoreKeyPass') + inputFile = jar.archivePath + outputFile = jar.archivePath +} + +build.dependsOn {[ + 'shadowJar', + 'reobfShadowJar', + 'signJar' +]} + +processResources { + // this will ensure that this task is redone when the versions change. + inputs.property "version", project.version + inputs.property "mcversion", project.minecraft.version + + // replace stuff in mcmod.info, nothing else + from(sourceSets.main.resources.srcDirs) { + include 'mcmod.info' + + // replace version and mcversion + expand 'version':project.version, 'mcversion':project.minecraft.version + } + + // copy everything else except the mcmod.info + from(sourceSets.main.resources.srcDirs) { + exclude 'mcmod.info' + } +} diff --git a/classes/production/seppuku-1.12.2_main/mcmod.info b/classes/production/seppuku-1.12.2_main/mcmod.info new file mode 100644 index 0000000..7f2f84a --- /dev/null +++ b/classes/production/seppuku-1.12.2_main/mcmod.info @@ -0,0 +1,16 @@ +[ +{ + "modid": "seppukumod", + "name": "Seppuku", + "description": "Seppuku is a hacked client built on forge", + "version": "${version}", + "mcversion": "${mcversion}", + "url": "http://seppuku.pw", + "updateUrl": "http://seppuku.pw", + "authorList": ["Riga"], + "credits": "Riga, Dan, Noil, D3x, TheCyberBrick, Hal", + "logoFile": "", + "screenshots": [], + "dependencies": [] +} +] diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/Seppuku.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/Seppuku.class new file mode 100644 index 0000000000000000000000000000000000000000..b2302633276ccb7f2439ce31244191b1c5f7ef04 GIT binary patch literal 11140 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 WW|fG=DYW!)YZgcU%V*>8f4>16WiyBX literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/command/Command.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/command/Command.class new file mode 100644 index 0000000000000000000000000000000000000000..348703784ad83dc6bfa6e3143cae2f92870442ef GIT binary patch literal 2644 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 literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/entity/EventHorseSaddled.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/entity/EventHorseSaddled.class new file mode 100644 index 0000000000000000000000000000000000000000..00834f1953445db7dc44ba5ee64ae72718318094 GIT binary patch literal 386 zcmbV|KTE_w5XIl*@<(Iz#KPWAEnEu=QMu+&EP~C+^?S*ntNF)fbKu9a5-j`xekgG^ z*jWh9GLQW|W_av=e!YJHIKys=3APjLB$yK7E7KS^BTNpDmV|KLmQ0xDrs2DxUa`H` zt4f@`ye)LK)Yf?ZF+=xgdcs9sv$Ezv*R6G?S3P&#@H{Bp8O3XEoRT)~MO}NiZEepB zU6vJ>mxOfD4z}PM<5Tv3O`JUGwaySCBAov>hH(1V>KHuNO~F;=Ux)()@=v}7ogW=XR|FrxPA!auAfnhTYc<%cY@Z!3dUgKDWEOlZE5X7C@S(&z zgO!b7LJs*p5)R4d*ZT*6Gwi0AU^~H1f+-=sl3M&VVRCr1B!si(o(a=jYQF8O6}vmT zD%I@eO<~KWbu#de4E>{Ygp0gl?u~85@S1CHbcug4^8pr~+093B zNk|t>?+U(=p=AH}fs-e@wi!Z1g!6xv5KjNPIo8f>U2s_r&%*%%{iI=#POaCBmCVRM dbo>T-RS_W3j8y}h*wD845zwtWz{CmBorZ-*RzyuO><66G;n6njl;5R^#>9m`z#nD2 zEr<_RZf4HCbMBdM=KbUK4ZsQZ9hlfHAcvZbx{U^d846D_RQnUL5PT+lj}LUDeD9RO zI#a&VU50vd^SCvn;fvsohRc2B%d2EQlF_Xg&9b;)EM`LyskB}-O?|IohU5NR@<@4N z9zhWN|i41y#Y%bv-?2oRi2^RKtYT;NY7D}3+q*yFe(oZ&*IJ$q#?&Q6!1PdR)hZ65B zb{2v&a5&##E{8jxU+*6P&M`?b!ft}S1Y<&cZEDj`38SOq1tFX@D<+I{Q}dmxmTVvO zvXo>$Zwg&5v^Ac8!mxib9pN&sSXr~yRbzY8sgB#$y*Q;?qjnIh84QEJW0{{R3 literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/gui/EventRenderPortal.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/gui/EventRenderPortal.class new file mode 100644 index 0000000000000000000000000000000000000000..dcf2dc480b817d77c4372fd8de47ec18b6dbba6f GIT binary patch literal 380 zcmbV|KTE_w5XIl*@<(Iz4hwrbwQwyI3+0+at01Cs{a$W3SCdWHB=^0n1PecaA4;4J z*I5Ye!ef4q86GoV-yfd<&M`?b!ft}S1Y<&cZLI00gwfIQoDk0HB@@QEv3%E83wBR> zQHryl*M%Q>)&n8(%%JU9!8E zK3!fB(#N`Y1>YJUaqz3-^hK|Ah7b|q;$Inrv%lts)S0#gm!;nghX~|C{*inM7mbC~ gz(92J4tf(KKq4B84QyjeG#lzjC>0{?hz7`h0Fv!vJOBUy literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/gui/EventRenderPotions.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/gui/EventRenderPotions.class new file mode 100644 index 0000000000000000000000000000000000000000..0d1a51177c1ea950f7a13626878faed201ee4ae7 GIT binary patch literal 383 zcmbV|y-LJD6ot>t=0{_67aMCkwQwv%1ZA5=t01DX{cQHKjwUlzCS(zoMVz=gxv&t3C4u@+E~+038SOqIU$_6B@@QEv3%E63-(WX zQA)C(yF!<9?M=^{Fl?VqL%7TkJ_x!o~ku2xor{4!tvN3ogrkJscvCPwEfJm3Gls hNDT}`C-0y)2?8XdvBbbOwnVeRM?$F(VMjDT_5)a+WUT-I literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/minecraft/EventDisplayGui.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/minecraft/EventDisplayGui.class new file mode 100644 index 0000000000000000000000000000000000000000..24550914e219e625ea3649f391ec4ac897fc9f8b GIT binary patch literal 719 zcmbV}%}&BV6ot=}QlwT;KwxWP6fkjIxG@+uC~k-w4Ev#uI9giL9}?e66OD-rAHat) z-nJ-)jl|8&J-6qc`=#^o`SuRr7ko$5vf7qYLov|xhm{1>^D{!Xbu_lu6HdNihatyj3y)LUx|@Jol@Vkg)KxYS%#-R-U!&V>y@It4UZ6dZ(qPhAAa8u?D3W&*>!hlw8x}T5 z(Oiqc%5{#L2YqYNZ3&i*V LF@8X{l8vP=8r7iH literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/minecraft/EventKeyPress.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/minecraft/EventKeyPress.class new file mode 100644 index 0000000000000000000000000000000000000000..e1d20599ded384f57cd69eee873399b896eeb969 GIT binary patch literal 567 zcmbVJ!A`NXlSnhb@hTr#jegLS3?6?YlTR=+)@ zavt7GhRQ$%@+$F1Qs0TujF{RW^u%l^v`TSKn(?EG7)}Ph{|Jd*QyGEKOc zD=rr@h`CR8o)!-=zew?=T;6CIMW+;CEK^9CTJ1DXltbq>OtdF^DqH?*>Tn_!!i9}p z7e!bM$NyZoFMV3hD~f+t{G9M5sr+LDlKJfpzv@ zVLTHu;Ly26T40mrUDB4R1DY!}F=awDm$}jxkh+q4a;l8(ik%l2Pt>gJtcEQ^%09R5=Hr<-sG)Z>V$l1^1C4D3G8T75 zG!|-DmN9gKB;>OZSF*%aQqP|xv7R@QMl>!|{IR0HFXEvLryhfmE#Kiaj;MwH)=ghB zND38-8(AuCFDfgF-ZP(b2Rc?6&YHgFZ69u zoWrawbhXgdjQnf*?%DK&G^<%zv(j~Io#|E2T{pZ8N_R%_h8w49IagR+I(0YlQ@7NP zQ>$yvhq7clH?Mq2i0AEK3r@|Lc=Y$``C4yu0v`e4_CK--v+<;=bhAj0sCQQCIA2c literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/network/EventReceivePacket.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/network/EventReceivePacket.class new file mode 100644 index 0000000000000000000000000000000000000000..d22c10e0958eb92cf8aab0dd909cd6df565607e0 GIT binary patch literal 1100 zcmbtTO>fgc5Pj<;HgODrQrd=(l1LoV6m@&(1yV&w5lBc80*ZR#vNc0k;@FYxguew+ zDc8&$g{p1Zdtq+*#v+4MR(pLsV zU~Q0uDmqrFHvT+V&fjU~bhwhzPq~)MOA1NP=v;awE0lIu!Yrg*R3=azQeHp`G}}AN zrE+?4`SO*!*3`-g`Au0X*CdP=PD(aMf@6^GpQxR~1_VeHDik zMP?QrngS30s>+_L3-c4`{m;2F1KRty=4kOfDf7J%aLmBiDzWXM#@~Rw7aT9~TI=k7 zhUnZsgY$`92bcMK#ctKP@G5*8NweJT;E5F_^JT1BdPFSf9g7Ud>*ma|-7p z8wIdygX3qo!QvXKoiA<-MRP9z2}~Dcjo7>A6EdLW79_w^)d>0=;4uv#|-XBgafG= zHhQtte5hg>rs9+4HKu}x(cGS| zlhU(k`et)}wwa25l#J6*zE)-uwHXn6=i)*H@bEN12`a<0R4Hbj3dNTR%vh#@L-q=46L?Om*(o8_!UT|E6>AhR+&Yx)(CW5!ZqV{=be-DOEy7x!bxp~&M2zAGw&OaH2fYk; J@C4<9`ft3s9>M?s literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/player/EventApplyCollision.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/player/EventApplyCollision.class new file mode 100644 index 0000000000000000000000000000000000000000..854d92b4fac26d843eba37319927961ea0aaf236 GIT binary patch literal 392 zcmbV|F-yci5QX35l8eUZiIuILTDTTgdI%D<3O361dvVdxO?KHN2lunA1PgzFKT4bg zOF?iJ9`ikBc)R=g_5K0i47(X7*iNyNVn&$Gx#8}TFgZM05aPl;7{aXN#@zPx(u8}x zwBqcQuF`g)0}uRT#@!RQgn3yT75GutE_B?g)_C8)^h$eHW@VaAd8^kZsOtf)ytnJZ zS<5ZE=7Nyjxjt0phKHQ}UuI68^-AZ6kr2-RA4NF*Yk3SWbW<5?hj-!tk^I(BBu8!_ jIu%kQ1Ih6l=v9mespwQ}U=tgn`Pe5ynGj)1G(!FjU1w-` literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/player/EventClickBlock.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/player/EventClickBlock.class new file mode 100644 index 0000000000000000000000000000000000000000..78af6199eebea8d25cfdeabe8739c070d63c3042 GIT binary patch literal 1077 zcmbVL+iDX*82)BAhc>RJjWuf3wno)+8G3cO)JIiR`t{LvNvC+mRgPX(|!*Ci& z%|jJQKNZKC=UN3k6#9g}2x5QnI?kRkG>(NY88+*%2T>j#3SUKY0=Ay3Na;O>m!mrD zMcz6@g>5_|;r;kM33sRD?^PZi$@Hx_3aHYX#=Zzuo4@+2Pc=CU( zVtDkoi-o+1d>I7AGjm7d83yzUHtD@|=u0;2ik#5g1SP-~8a>**qjQ($?&J&D!HSfO#1uJ>>a*Xajr71z+EGxO{T$RUAM!WS}}W^>k@e1`Lp z77h$~%NF~V&?^8XAtRYJsu+)Zgmw(t`ulCIW2@`tZ)X|$1?rcjR%wah2Kpse)rfo9 f$VRP^o48eHq|&3p$dHU||G|jqi0Qy>8-4vJvqbF5XQgB<&VbbiQog+sfBAHh$uFPR^ghH>-XZItD8;OBnLj0m0;lm_)y~P zd6kXe41DbGV}_5N&#(6n0B6|EF~W9+oeX0_dS#sHuL+~Wqd6g-H1|vxm&WmQs2A+- z^umg>S2mTlbL~ywwHf!1rXyUGH7jo(blv#gbgJXF9i9iJTcdc%u2-$qFYMJ#fQfB7 zo>iXNT@vzHGx&;cO$gclJ#g}*m%2cVgmC`P5W?wSn?JGIRcvke9u5%6kwTHQ#EYgv hYQ;cu{04dzBSI#ciVbXHL$p}E6QNv)uq7Iy_y!z$WLp3L literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/player/EventDestroyBlock.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/player/EventDestroyBlock.class new file mode 100644 index 0000000000000000000000000000000000000000..87753c6cbbf50e1451df5ea2eb3331a454625f2c GIT binary patch literal 704 zcmbV}%}T>S6ot>EX=-Dw+G^XaqR>`wT(}UGF8t}Lh@f;o#?g-Ek7QElTPY}l3m?FT z5^s_!qKkr?JNMk2Irk&;{_*+-U>7YLChBDruu{Tm2@Qrq7{mnbSbV}n$!k?Bix~g zRH~;#Q;!s(><>K2BXujhAkr%4u?)lHKH(x%T#lu$dFYCXjQD9PPGqd3V3JX$h__M` zEW<{-GnTYSa<6g#v>^MHq|P5(`sUoyi1rT)yUnb zV1X3f%TgJoRmqiSayl7(D|Vk?JW!LzS=q3j#Z+>`G=@?57f_GfDUkIG#?GcqTG#pk OVts>H-yqA`#@Z+D3!5eY literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/player/EventExtendedReach.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/player/EventExtendedReach.class new file mode 100644 index 0000000000000000000000000000000000000000..34dfb15a5e8405d02e2de02b514e0e2bc19cbdb3 GIT binary patch literal 389 zcmbV|y-veG5QJwP|9~+hqM@b(3XXyX1<^#IvQhv_f3a8Oz<)ZQBX}$-q!c^=4~1A; zbQDPJNu&KnyPCWE{Mvp1xWpvJ2>THZB8&;)wW*A|A&gE=mjr)S=S&!QS^_*F+BOIzDSN- kKr|Fm0|UX?JLpXe50PjnHn58w(PZcYp;(BpC+Z>j209sLn*aa+ literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/player/EventGetBlockReachDistance.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/player/EventGetBlockReachDistance.class new file mode 100644 index 0000000000000000000000000000000000000000..8255fc5c56055a4b2ab904d21d34b6400899a1e5 GIT binary patch literal 680 zcmbu5%}&BV6ot<~DNqm)6xbQ#23a@@-DyY^#SPI!4f~-?V4$>3TS$B<6BCVz3m?FT zGTteO#OTV+{p-m&U+4Yf^$oxg>J|)aWs$^o8r3vv44HunBjMVTfpr+n6XmL?#gJ_5 z_ZW<}H=r-Yu5#toY}%K>o#;DsDR(_vI6V<4y)TbOG*Tf$yE~OUP(v~Gf=Gotl)gWk z%((CsmviYx+;_yi4ETj!E@gD)c=qH*3VU?EggK_@Mn@CmhBErP##98E3)gSftv3s7 z*-@Hn=Wox0v6zcI(#YhIg2{0DZ%l@gHsy|Rhy1!fmUe_)dR>EFn<1fNXfkM~RH|9p z4yiNhspbpVBMk{yR4wX2j>LJYpc;#)Z_uU<3RJa0hm=}tX@ln8GZNn}1quf#4HQXR zik+$p_0mZvX)Fy~wvpxu<;T zMB+~KSSy!%LJ#@bRMTRxj+L+UDZ^fUzP!<6Fx$bcWGHvZ_cHeSGP)6cmpYYh;0U)T zB9+wBrm2UDP)@p@y7!WG&G(avaf?Ua%4v(tXqHWIk*=SQ9=Q=67sMZTK|A%IGi_~GPH&7 zNY~ANVXofjVVj=Qq~~QY5)8_6lozl-agnMH^$j}h<||lp{{_YqRR(N|%cM=Bi85(d zP^7AwsZqibRWz5nGICocRp!a*Wb`fHe1`EzNoHrI&9&5~lnJIbjLg4*PDz~rS-)WH Vv|FQfn=>HR4~X>xvYKwJd;u)#r33%~ literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/player/EventMove.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/player/EventMove.class new file mode 100644 index 0000000000000000000000000000000000000000..1d3293c27d21defd61157643b047c1f3b6e631fd GIT binary patch literal 1328 zcmb7?O>fgc5Qg7%oP?yNh0>NlpdTqDjw{uuLT~`}(!eQj0Y!zI8%#0eOO6u}Zu}xZ zB0}Q858y{3-dU%iM2-T7otd4T-S?T@{rT(r4*++umq!-6Ib?84%xy7cF_kRrEUF5* zc6aE9&qqC9VY}Y(BexxN{ATFAj$FSJ1<}ZTa#ry`LA~dwaf~=VC}bW6ogg|?DBFuR z*J`zDL%}@izM|Gjoia}c?GuW7CoN`H>)oc;YItEF^GVW--UNMxgL>O{!{F3wcf%;? zyM4dc8@wC1UN3O{AvxV%%NzNj`$#4NOjhgE*WskQl3iVd$UXhP_Uta~O1DIzV}+Dm z<;|EpffLh?yXDf0I4O>^m+_1)|ExO*oBrcKx?i4>@4xkio`q#N7A_!XA&(^smY9oJ zQn>TKSMd*9wD^(NY5J{J{2FYgfgS#oEI*P7Lr@qQLZdx_v?mjN4r~D{w3j&hh!pFA zqVo;P*&D-f>@iYK!5qVM3Yjs|U-ah7wAU#DtWx9(k6Gg}>$DrpUu9N)ahkTs)irvF z1V!mcU<@4zj;SL7%5Z(1XT&%zz0{|juP{C{Fd)KGB=RC+#RU@)Md<=F(#s*MMIxj7 z_=BC-*-gT2=@T~Mswrk>f~jzg8fPFztV590Cmwnpq?8C!#EmIPiq|S272f46NSPp& zIUsUNasxLLLCjeYClO>b8N{3g*(ZoQ2Sgr8K(-P=(z753i6Gm_Am@Hm{51Cna(@np M{1E}!(Qi=t4FE99;{X5v literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/player/EventPlayerDamageBlock.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/player/EventPlayerDamageBlock.class new file mode 100644 index 0000000000000000000000000000000000000000..0f18a14768c63db4e905409aa53b875cee07a98f GIT binary patch literal 1098 zcmbtT+iDX*82)BAhc>RprW&=?wuuT!Do!uFQ!CiRRgi)b=;d^srepWS9twRc1&iQ? z5737a|CwEMD!h4Zt%DI%r~b5e?ke!-F=~+E{0BlQ?4-P9vG~ zP({*D#c|GyTm?K7`3Zj=#Qy0)oIPh~91CAEtlO}AQ4#J7Uqy2QwqB@6<=YIqBOCTA zuMJUS8_!61Cw@=D-6{EdQ-nt{eJ73rs`RF@FM^p!mEKpyMt-6w(yM7Gd8+0jjMH3Y zJd;UMoEBUpipw(@58_OC=wQP`3vCYzSY&wl zUyWnf`rCbDW=BN641)4Ox})(719~r;^s+kiB{yb8hG=er^57bc9_0-D{eX?~8oG3*KV2ik%t{M6B(OyIQijv4&zh6Z za6Zz)fhKR6V&4#YC7>c?By)=@+T%8%9gQ~rep&07>Wcm^8isy}`e~_ESz@@2e#KQc i;{I-A&1&Qh?%IshdQ=)2l97jhFrqu6J8;iLU-ge+MUA2epjH>iUwS^(pDke zWTPJGJCi0*ZAX0>bfs1Xe+NtHgJRXQLeV&o&!i{XxB2-#9>|m$0_9}VNu#jH)atBr zzLZXs={{X4oKu>*_$jTwR`_si=7qbA2K-tB|KSBMurS#WuE^Qeb1maxdUHpzm=*bE!XsBjGn TD~v3x!r|TJNEsWjFSfq``8vo# literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/player/EventPushOutOfBlocks.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/player/EventPushOutOfBlocks.class new file mode 100644 index 0000000000000000000000000000000000000000..c5806dce8731dcb4857c23350014fc484108916a GIT binary patch literal 395 zcmbu5y-ou$5QJwh_XEd4B05SspuiM#0g6PVIuRsLdgn02#P=in9Er!GLZaXScqqi) zi4uu|wKUpqw5zfG`Stz*;2fhA1MDW)OE4tF7rN5z6=866ydZ?r`auzfxvtcWFPF;R z%cWswKd%dE7SigDf6TC5X-BxsOC_v+l4WgM?SxZJBaCqN*LEL2l~tjP>7I&11pHxL n5g)z+Ys@5i2BMQU&?_4O64sb)U>jSkS>H!YDHCCbH9+2d-8s0&G7=1Y03S;1 zSYnX{klr`W7JOrT%>M6@lV`os8A3#a^M3~sPXF2+qNlnpxGeo6aezR+$`{Fz k3y8)-YG5EbegnOV5g-wb#RfL9A({<+B$NsfwnPJD-(>z~)Bpeg literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/player/EventResetBlockRemoving.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/player/EventResetBlockRemoving.class new file mode 100644 index 0000000000000000000000000000000000000000..b1291a723468ac0a5b8f8aa4c8bacfe1ad5db22f GIT binary patch literal 404 zcmbu5KTpFj5XIl6NdqBJ#LU75448opRH0TdMGOUXcf+ZeI&tLuk@#3lNDO=cJ`~~- zu_6Y}(vyErr+a6Ae!YJHxWImb5q4wj#h4JrSEe-0lrTCzSrWpzdt|~SGbP`(#ftrd zURiMtGM8(+)ZX;`V}{L>sR`Fv!OEMpE}U;nt!l2ScGD_d8O0r!jjF7EVXtm_Sa8kF z%({HD;KFsLTwfBBd)NA$Z%v-VbyhnR*%tc# zVZTycN=M$w%tQiVlufQ0#|xo`b?Qh zwSz$N}7cvCYKtfF^s}zKy`A*K-L0`lXS~8Zub|6 NH3zZgAX~}A?H|zWlWG6} literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/player/EventRightClickBlock.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/player/EventRightClickBlock.class new file mode 100644 index 0000000000000000000000000000000000000000..4c068496e5380d3d0ae40076f110925ea2184a0e GIT binary patch literal 1766 zcmbu8Ur*Ce7{;HocAJ}36c9v3HU!_A4wAz z6EFM#ekkMno=z2LRZL{+;KlGD5f%Aq=c^Oov$iV5gGfcW|KCMWaZ9?9U zj-|jsS9FVSK9! z8Kl({sOvp4IV3$9{L(LLJu-4O;2TiYbE9WUkm4(`K6FOQq01DS%R>(?pM3n1%EX;& zYq``HrLMk>hOs9PeJ<~Ut~8tP-80w14QyGsf{KMIu3E5g&BAp|3GDty*#)-#c3L6r zyP+q8Abo^JquEBCe(*B=|0W7dMWX_Psh-$WPk7WHJN6d{du@b* zy*`3rZ;W8t3+4#LPwMOpYsdqbC68MaWsa^pj~U#?0)4Zzvy(=m-8q`Eo=JonF-t*> zn8r{e<}qo1o?@gl4)v@r+MiMQNP_|yfNXj3o-(mg!PtaqL^kQ+JyNqpNnPVNc2%v` z2(GRo%%!Re%+eTB;4XRm31UowtY|?NabE{wOoB8Bq?rT4S>g;Vp{4;bCqdS=AayM3 yK+H*yEdtrj0pTJs$OEisK#G$fJ6e!cJk)_?UQ}9|Cj{~|2ZY}UgFI4?q45(5!f8?f literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/player/EventSendChatMessage.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/player/EventSendChatMessage.class new file mode 100644 index 0000000000000000000000000000000000000000..ad344a13ecaaaa769af9f512902408fc99cfe473 GIT binary patch literal 677 zcmbu6OHaZ;6ot=}(n_tM$U~Rz029ZBJCqHP6}rK&A7D~O`yhRg_^&k4n7Hr<_@j)s zEfS(8F6?4v&Yg45eA9XVczpwKh64*a_Dd+BW}s>55c6xQP)xLI5<74BGsD%Go^9?w<8a53~G z50xXlAdFSSBe_^4cL^5@#pP1^F<-diUWWWK6(i}-`g0Lq<)lPqIr2*})LQMIXyl1D zJk}^k!l@jnlwxx^Di%3a$1SNAxy2y%mF& zV$iBUYZF^EmPie#uF-6DUcfrX&(I!8X|QN4lNZ>b{xW$h*e2D;-LR>iepZ&sD6LG6 zJd@MRXs_6Lg7!d*JkH39)hx!&4XYT2-8E2;+$oUp4aUl<4LYv50b;B{j5Ww!c4GAt D;<1o4 literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/player/EventStep.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/player/EventStep.class new file mode 100644 index 0000000000000000000000000000000000000000..f2271c0059bc95c0464e116fa7ec5097a3fc82ea GIT binary patch literal 330 zcmb7no>U%{!sITvjPXHH~=a^tW!!*N;kY1V2_-n%C=y*wpZ~7-D%u3Vo{n%FQ9(C1- zb5QoRZkF1az`thfpUprxFI!g5taRHuZw586wd2dEv^9!1+<9di{mM?=23UBumxO%L zkFMrB6Vj)Do71)4=mIek!r6ag3G;BS8r`kbL$&7G;}DVj8;YbQS2Pt;TLzMochH*{ Y5i-$KY{;}DT5RV8yU2wId!iAFAG)khKmY&$ literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/player/EventSwingArm.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/player/EventSwingArm.class new file mode 100644 index 0000000000000000000000000000000000000000..23e600662f41cbdffba1cc463d03f44a667265a0 GIT binary patch literal 680 zcmbV}!A`{8P+()!9bn?PAZ|1yhCo~pHyHK!-O#z9<5LFXOt~s(GVE7>b=LY6*_w_dL%vICm!UI|{*@Tm)G2hQLt*!YuOhu@ z>cK?K7*4v5m=$#2In37{_E2!y<-J_!6i|?g+^E0b|A8GL5Tz0Wnq} L#tLLBo>=$i5QWdA`Oz3{Dfj^H)P;8=h$wDEK?rrBc7Kx&_164cZf*)bmMg)958y+I zlj6#yGjN#iFr0z;`u_L?aEeKa5q1;oB^VRpOVb#CMHn3(%?aUkyI{gNHx1AFx?uOH zi%Ohn-j=$WYi9=jHADYwI>LEgvvOvs>(+VGsgAAfUwWmjQM~5HD_iMTcIsw;C%e#| z?;6|t3qtzP_O9exGaT9fyKu77Yn>rPL^%8B5yE6hQI&3%>b_WU>2ZKSo-h*)*P%e*k@A9wCSM6;9iY|PCF?d3I^{+ zYZ12;PZE(ZH22$q@MAgTK^Uhp@e>h6*(mdQBz zxXpr|i0_RXL$w|Dx$5#*8vJ7{rB9NoUKSRO6n_!%r1nEJ;Hh}zY9#gWF286nl#@wA zjlx`0#c8IFrGA z(?3P!uRPNxL;ZiT*o8%($q1uGZPUI$s7ZEwURBFyv2;eeXquM8N~_P>4-L zM}fpz8tpgQ)!6?0dj9}$f&CN{>?YVtFeSuSrZMiCFgZS15W>7&F=1MmhVOj6Wc#3( zl{g1QTk2||tr_^o4BeCI3A3VRWzD0mTkA}(dhR;^;+5`<;te-WS#DNr)qH?kZ(XkI z`FhQzn-S9c*4vVA%n)<fgc5Qg7%zGyHwEv2+jAQ6`&g|37uE}&k3oFYJN6^Y}d_3xPz1 z#DO2ck3zh=iGZYV2(r98JDz#xnel%A@%0;k1GMU>;LaM#*tN^u8t&C_U%;QLG&d?b zG2vMzAbJ9gEL4#m9qBBIirgfzz+OMrxty3-hpBp(%P=xJ&gHl;@^~rusX+CaiA{be zAltna5<3Hd^7CY*1%f_Hy(%U{ot~&+M9)S)VWELajXlqu<@~)N^ppNX%hZh3Bw;U^ z%=C0xoE1_{jnwBBG}ZA)r}Cve969^(3xWn?oxfS=ztrw<0ztOyFSmOZ?*3)XyfrbYwUUkk*C+N=t z=7RhY*rdlY9x~dq(T?voTHSfK+0l+u*qTNCLaNS@1a4w$uJtEK>EjZ}?q5M}Vfzxu X-olJ#AWed_{sCeqVkfZUD&GDH>jls( literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/render/EventRender3D.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/render/EventRender3D.class new file mode 100644 index 0000000000000000000000000000000000000000..cb21f8ae83f72312c9a093d889e6ac0f5422b400 GIT binary patch literal 588 zcmbV}K~KU!6oh9B6sbiJ0lgY8z`;F8ylA+nJrOlZxG%85MJS}S{45g_jfn?;fIrGO zErbY1FZs<0?@>fgES6uNTHlXC5x(nJ5xbu)VO2%&vOCc3D}p$H(^U4 zUGwT)maFMN3l!SM*SFE6r-P2_jj5E{)4m#aRbb+IC8onC!=Ur_M9aVo)nv;2xt#0S zEP9Tlni;7V+7D%*{eceTO*}j#{n_;e*9>)dzrmEM)k#&DZ|lzEGz$9KGYQK^&gn=k zl#475U1VSjH2*^*P>gfrSouSF*Bj}6C_tJnj`@UXKB<5e=d(+(&tivXj*~~-Vs#oH z5RH>}Sg)KcI6U|01$KGgr8mzGs4m@9@|<`tN#*aLyRgcXtb*S%jW<{?Y?g6$A{LVv jcWGF~5PuESqB{n%w_uz^EpuJv4~V@6vDYB`$;Q$zWJhfY literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/render/EventRenderBlockModel.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/render/EventRenderBlockModel.class new file mode 100644 index 0000000000000000000000000000000000000000..986fabbb1c9b7176046108da1d0c13f5bd576d2d GIT binary patch literal 3065 zcmbuAZEqVz5XWcjvmHB^G;L{$TWIJ*sC`X(0RnvrZjcXp1;59`?B8`bfwvqvD*o{(vQ5|*!{j2g>83Z z?bzm?pi0Zzm+fc0whRT`(mebyklomgWVbCN8M!LF+hJqGIdW8CIO@yTi>09JTA0MG z&o4*ED?_+Vs8=s~2HHU!gl@-+_gn=G8`w{^2D`g5S{no*hy*QaC+WazX>-Q(_arcb zw#12IN01eH-8Pn+c$cKb$-59NAL56 zrgyE{4%?Q1y`{biFvEAD1heGXs;S;Vu%xz=j^Qxr=gQ08AoAtofWIRbjID6OyVzTf^v+CRgP)Z3}7{bSJ%se`-#$d?%)+&>I*m+l>b zLB08$YW z2YvuQs_N|8G6<#gP+6MYnVos}nejgUzJCC4fISBm-Y=qtrZ%lQcIwz=u!ceGPZ*lL zNM<}#k@ORBk#Q5|U-jW3gOkW;Boi?VBm)~T*q>FTvLl9F@0G$%pP_afkEm#+N7ARW za43`Sxy*Vm_C?SaiPC-%tYw!fW%$wyB~R2?gmIFol&5k!olRz3Ocj?`GRk-k#J_3h z%)lAeb2XC0yD*lS@fmi!&MSnJnwF`qN^_|kuOSMCg3I(B#Ia zo4UVHxu&EFw46<0VAIIBW^WZT3>ziTQ2}JXfN{*l+l1eE24a^Wb_ueHw{t+MKVN{f i=7MbDT~Yi5(!53WX(~C$9)Yy~0;1=vC$epBZ2SROgRYMN literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/render/EventRenderEntity.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/render/EventRenderEntity.class new file mode 100644 index 0000000000000000000000000000000000000000..c848c64647d9cd5841f88d2e01bbeff627e25946 GIT binary patch literal 2133 zcmbu9YflqV5Qg8=%huK^g2=@y0>XAd7V!>RiPR=4F$M?`Ke?0@S4$z=#oLealF*p= z!5`p{GQM-RQrK)k+ z{QPv^9CXlP|4D9fbK9@DWlvhrqYJRNd=syow@w}>QOqNUqj}_UERW+NIz*g6XC7VX zRJe86;I!+I!sKDD8f(s}RorS-I+MXYh1-ASrRO}-O@-qB%(--B;@>XEMZWJW{|F2u zq>j`QQcAtDntEkH^~##+m1X6642tFNrR?Kw2TAR1T4Ud!tnmgCR-u8U)t7D{W%Xqm zNL#(x1`Mk=*Ffg0j?_;%NCKc6X`CWK58KyEtq*6=PrB0>rFNPY3);@)?ksnJiE}v5 z+eH)dgw}*TsWqWbYfbnwT9XVUTT@1ZUVJeaXl7t@m1t>e2Z=9K5(JRK$l-a7kPi)- z2#R=vJdyN^v=#uv8e`_IDa>H)Gkf`2&*t%%FQgMq)uO zVPqF1sq;6iQC2?+Vi9Dl4Tw}uKt^LhQc;kJSP(NFBozgjBFNP?AksJiDa3-LqaZh8 zL9BR?bQENoATw=1WNrjx4C9p2=Djmwe2TQD7z=V46HVvVj12J^L_zKoWUdW}jIDs! tu^^c!NI4c{G9F~lOALqg5kVfe0g+duIFDC!>Qj8J(66W)cW`R9|2N~7cQOC~ literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/render/EventRenderFluid.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/render/EventRenderFluid.class new file mode 100644 index 0000000000000000000000000000000000000000..c2e9b08a58b94b47093aad44cd502bb18bed1ead GIT binary patch literal 2156 zcmbW1TTc^F5Xa}V+XC%!5d{UjfgtTdIe;MIg@h7GOd4av@W9)4dw`W~OSZfC>i6&~ z_@If6i4T4NKa_Fi>=x?jStO>(xz5c0H*;qD>-UeJ0I&v|Ip~Mw0qBDj8dhm|M8g^l z>wWOJ4>lO&t6tMN*>)V!YB89pG(^DbZbLY}eHic$P2a2WSLF+vXAE-EWiPM;!C+qT zkaxUAm$9ETM7Mr<^`@zj2?N*TbvrobQVDI)ey|!I9tyu4x?WBA3`&ZU{a9=d= zTKK%&ZBCfcja~H+lN~U~K6e{#u*Kk0K?$WvQ?W=&OEJ?VqF7u`UEF72>@;ggJY2z7 zcpcWO!haX#Fj{FkwzqHlF74w(BRF=kqMMbv;J$lg*PDLews=dNo`xqOw@+Oz&MxZ2 zU()8Stl6#?x-~4+(2)pa-8)?{TPP~jngXF;OYxh#LR~4t!H!_uL&YAwq;jKgM>O`e zRLvw;63%yoWf%6Qsd+wh>L^O5o*XqkBsD@(-5tq*_oR7wGhh&s{yWIBn(yT?2*q?; z(St{Alr9wUW1u>ApBjY&vd!%^L*Eg*E`2m(YO^f8x6f=7uEP@(1|Vlb9!wJkVaSAG z7%|}*j565x&rW2p{4Y<*vtu_L;d$rD?87wvq4ndRUItQxg{u^i$r<6~jC^uNM4a=$ zFpC>Fj^XYj+GlW{w7vtg7TS=q7Tb`vN^LN#38M{}uhMs%Y#@u{7#J{)S~oHJEsQjQ zze(KDAFqsrrxUm%dm>_TMNBEVBC51p5to7YlQ0$2aGc3LV||0v7hI%J3Q(2~??@3d zGKfVO+{W`Ll`XU;iL6ZH0y`&9rx9*OMi`H*&M~twCWE_hFOJm>l2$?Hv>^BKEi@o$ z6{LtDRsslBi7GGy4>TZ#3R2R7%)*=w#85$25M(t0gdT}N9>Tl^B%^|?Ye5Q7)PZz$ yRP;2P2=X)mgnEQPELhNhWIroC@ST&3%SFA@pGP(e5Zt@M4HuIcLK681I$|CNFw z_}~xlM~Sn$!C(aw@!)P}W@oRr0(aUEM>_c z+u2BRt%hPW)<%`Ql#|Ky-IR-o;?mafMYTA~<^IC$uE?fy%24f(MeBknJzqcf>r zTQr7^Y&;P8snE*$^I+9nC?a>Xl$(~txzwKGD`$HZydtDSt@LAemqIP(x;!RBeJG8G zWazXzE6z=I<)SWauUKZ~iciK{tF>E{2E8 z034IPC0<)uh5}h_OySuJAfu$yaYtUiO@_D7PT9`K7X{={FCYtp;pBg;3`c(nlg(}64drB#K3b+} z^|41Esnf?YXfXk08On3mpqQtsOMQ(_(|!fB4_=@>QKiA8SftrF>L}6dHa4lMrPC;2 ziz?D3u8iD@G?jXCIvL$%?Pq9@l%#e>(ySylg>+zH!^r#_s72E;kg)<|Cfz!%Yy1K+ NmLSFwWGC5J{sQZeqX7T_ literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/render/EventRenderOverlay$OverlayType.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/render/EventRenderOverlay$OverlayType.class new file mode 100644 index 0000000000000000000000000000000000000000..be59842076e1da349879f5a62626823dcd9e7497 GIT binary patch literal 1400 zcmb_bZBG+H5Pp_kd+l+&cwn&w->bHuoGAE`5>mjT)r*Z3NE$vJWvz$TYjeG8!oSjz zh|y^H?2j_eE{&AnC(~=P)7g1;=6PmkfBpXU6Tl*#C7>XuVHR^Lk}4i(7{$C;%s9q0 z3Yr4(Fpddf7vh){_K}Lm4AC{Ky#9t^xZL5sYaebMwm5@c@;vUZyLP+H+YB$Q1~+}D zZa12K;Iz#)Z?(dYp=q}qlXtimm_GORxo;MQvnl`g@@4w+<{4sE>D_ke1%t9t+AK1t znVnT@yI5g(wL7>X9or2B@7LMf;Ib;~&3$UknB{o;`c#E*7R{FFT$StS}`1!K;+pp<4(( zIMk;^#i@IC5c-rUk`;mYa?R}>uJ)xadSPREK!R3i9JER^^lN;>5q+GxI6d>CojNXy zu}q{!0Fcb$ejyk6CRL2e6)G-D_$AnlWVK9uIU89gp&!pxyJ>oc-&GogTym!EB z0qJ=D--H;J`Y%U5xqM%Vzf*LcQNFN1Pk5BxzfwpE_5fKDAT4PC#?zv20)Ygka0Lu0 z@@|n8pVkHYf}s;cK9R?erZpyGDZ)=?>5sFHsC}`<@TNhnT)3Qkm{Z|T#;K3i@ zj}j*zO3_25c$t|unR)YOvhN?SZvghNVL?YegA@uTR!tO5tTD`9425#}s5$Bj2D|Qg zLe*UE`@(0?gD892=n6;48{X}yK>Cg^`u)NEz~O!Ah@tQTM+xs*DCal?mr5OTtn^QuLwjn)nKIpcEYVx*AnOvjS;ckm78R8_V2e*=Tt4=R~ z7BO!`5TC4GDo@Y!<2kMMux?`p8HW9-e-Xp(q~2(L zje8y8y76U?C$;?PMKGjFlKw*Pz-2kaA2=l-bOp|Ceo+^X{s>Gw0dYf4iSNRz5uRvl# z;(;H)k3w8K0oD)%B2{eX`uKd@q+h>%{sQ13w%VxUMhi9EG{brm8%=C7xC@;yY)>PZ z@=!(6kHtaCvs48<6zLHk2iiY=u9L?M4H=~>eaEm~Lg#h9XSWS-M@1^#Wf%`i$O_&P zVwr0=W2jB^TrzZ~JRuSOM#sUN@0s`omsYDH-hVAlgoifz9vWzRIENO) zqyO(2!-Kyawmv2z@?{X@FVGzfXV{{zu}+_;LqD=&SLBA~Iw%Ux)9BIDE82Hy?uJ?U}1%Wtd$VA%_H32%pPvn$2E) z^byW`S~xJ|4O{G4LN5mtgp6daP{nxMCA4GE*55B{ZChP4|3J&o%TYfqH3~}%SJ5lD k&KhycMm8#qT*LJ$BWHS)8`&l!xBg(nbi{OE)ka_Y4(NaDh5!Hn literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/world/EventCollideSoulSand.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/world/EventCollideSoulSand.class new file mode 100644 index 0000000000000000000000000000000000000000..fb563767e6d67a75deec3901b5b817fbf456ed9f GIT binary patch literal 393 zcmbV|y-ve06ot=C^8+E!ij9#C7%&49R4f%tQJ13bZeoGKu_Grb&&7nqzytK55Z8qf z2?<*|I^U76j_u9o`v-taOmd8{pWz_Gn2=7j)%^`&baJ{R#4}eb!no8{&4*^C{JmTm zP7X^~Nwbt*2mT4;{!w>?Y1t^@^@D7j?{z0S)waX)AY`kBS}WU&7w1haZiAmWV|1++ zZZHdJ>uW;J-dE~Qhn}O~4xK;AwJZ=LAzb~xi*WJR@OQhkl`>#TRx0Xh;A6 literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/world/EventGetBlockLayer.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/world/EventGetBlockLayer.class new file mode 100644 index 0000000000000000000000000000000000000000..859e3c1f3e52cd75f3e7d710d4435ea34438845f GIT binary patch literal 1000 zcmbW0OK;Oa6ot+>C{jfdB&G`%sI9taMcG(gv?%+DGnAo@9Zl>a{uM|d zq%QaY{3yhov6}|>C6P$und@_ozkB2S{&VpQz-v77;9zwMHLRKCNgd5P))|~$l!Rvt zYe6hiK2Wg?wfK;7Tju-b<_@VM@kMHe&5|lhRg{a4W!#rKFf!7+yDC=c9>aR8TAhkPqEj{EBRL#q zXBihm#pSt-Q~o*8QJ=px`*$+6ZCtW7PKyFVv(>%>kD)OdOO4AWFub_tx@`=`Uzl3u zLEP*yBk@j>Oo#GNnK3L~@8Q)aaV~s#c-+@ky!?U6H>-U>>qAs&ou#BXa?aBk zSR_5EF++9p@oYMyv^i4bnVhbS?m30Wotn6Iiybulxm{ C9?!V| literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/world/EventLandOnSlime.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/world/EventLandOnSlime.class new file mode 100644 index 0000000000000000000000000000000000000000..e75cd2f3ff32d7ab5fb9030f2a25e7cfaa0805ac GIT binary patch literal 381 zcmbV|%}T^D6ot?2^haxTMDPLJsSD#mL{Mfk=&I;qWcHahXf#bq+K$iVN^s!=_)y|a zapguZfy4O@xg2gjzurFpoMAV|1lt*QGE52SmA1N{5hjO6OF}$%wIWPQZPo42tdzf( zE5pfN=_+ZK((AxKVcb9Jj&M;nN_hPs8|Qo7iB7fc@H`0FYN6K3_Tt5PQ;X~1OKIyn zyD+*@mxO%b24ATg9Xj@ZKR9`kYgr&hLOB0l2jTRu!LfBNZKaF}%i#bKe^EHZm)luW hCNVOQ9KV5HIf#(4rW^yC*kCP2pD^W2ge}$x#W%y-h;;q*yuRE8LRfy@782%P=ZxJ{j@y3odi$KenWe^FS1H>WcW mn4NDq&_8*Dcx53%!kF?24B0rs4p$l5*o0la2_uG#5wdTplViF7 literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/world/EventLiquidCollisionBB.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/world/EventLiquidCollisionBB.class new file mode 100644 index 0000000000000000000000000000000000000000..7f2da72eece8ebb0e3a930de3e56a30aa5b60c5c GIT binary patch literal 1131 zcmbu7OK;Oa6ot>^;j~UjODKU-S}3BB1c^a{9aW?{qALp_fx36>A)VIt1V2iD7Dyl@ z7W@Ey6ynarP17i$3uI|ty7!!Kj_3EEpT7XS!b2NXY^|b#`+C@}VW)-%4E3SP<3PqE zN1Zb~bz_n7NXEiXypI{rGa2&8%Z~ZMxl9j2If_N#IIkI2hN1FL->H=0(b6WTsG)jm zU&b=)Gn6~sBZkUA1%hGCC9Ai2G!)4PZy3@^%T>M?9(jq>`{J;Y9ZNFmyOH3D9C?vS zGMVyJjK}$D&b_hZ;!MOD|E!WQ;BWNWm7j7M3{)7(RI1oO?{%(6)pX5~$eh_+x}EOQ z&iQ1T>0EPfx$D(lZC%&a(`X<6!}p?!!mVq|X_Nh4<%us2rOtC}aTw1}yfd!>8}$ZO zu-bry8pHno_gSKk2+WFbXtuyK9gPjzy`-7ZTK6QF(pWNDc4CCubX+my=A42U%a ru}n@Hq>Vd;)+|VA9%OeR$lYl&S3qV`nSksO$de@?7l~||tKa(z?>p;S literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/world/EventSetOpaqueCube.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/world/EventSetOpaqueCube.class new file mode 100644 index 0000000000000000000000000000000000000000..77d5aaf2f51235557edef1941997165ec632050d GIT binary patch literal 387 zcmbV|y-vh15QJxQ`GF9)6Ad*TP+$rQ1c)YrDmsco*E_it81jb`AJ0XFM8N~_P>4-L zM}dSbjpiG9HClguy?+2W#Vp1I+YxpmObOwosZD=Hm>e7~34YqFm@v&u&2v}fZ0~el zO0t_Zg)W!cnt^{pzke_t;XJEYS#z(e#`dOD9k;D}a!R*G@tW&iy)?F5sq4WnxW8@n zv*Xm|d_jm8jk5*cn4x9w_mksCz19hQ1cbBy_7G0~8XcQcT^C%I!;094Cm%H&k}Lh9 ip^zFG2#(%BuM&8OL_>*zO>BrJqYs2)A;OlZhvXY7C}q_E literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/world/EventWalkOnSlime.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/event/world/EventWalkOnSlime.class new file mode 100644 index 0000000000000000000000000000000000000000..7bcd457391b4df8b9f972c2f4cd54e4577cfcc0c GIT binary patch literal 381 zcmbV|%}T^D6ot?2^haxTMDPLJsSD#mL{Mfk=&I;qWL#%DLF1%JN!#(cTnR3G03S-c zDX!cICU7|4A(z9==hyoOfHUmo7-2iZPKGfdz0y{96T;~5XikWyZm9_4Qd@P~*9+zE z<-%~XSGr1?x%4{lPZ)Pkx+PqcwGv)G%G&u(x1v=|)316V8!gmY*-pGTZmy>bvCV@){*HnG843_fAXnFw2~5sGi=N@HID literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/friend/Friend.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/friend/Friend.class new file mode 100644 index 0000000000000000000000000000000000000000..4d7c1134518674f27f807da7c1184dc059750f51 GIT binary patch literal 1257 zcma)4+iuf96dYf2ZD>mB23jbz1w>*f7MB+Us)UgG6qScUB_5r`ge{2^IX2$~5)~2; zd;lMXn6oxXo48VCX)nifW@cyi&);9a0ldKdDvG#MK>>GV*pXqkguN2(8L&ft6c}i9 zPW`XGH}u1ScN|A59K7PcBvE|>1%Iggse$5a6{`5afYoZB@bBAkpPluN3WK9$)D5Ed zes`$3#yx*{;zvsMS<#L^D{{0uqri*Qz#omHSWUfYFqtG@63?F~?^C3LuJ_@JW_Y`QA5_9o4(%wo2z9*>i# z7aS_dX(c`B6G^^?71U}dp6|;EG`xSeswpyY6Ywi}94VT;%;*Fol*YQ%Lnp z1&P)H04g(mQj*G`xP&B$%3>Zv!2NexfdSif{g9%U(jmOBG4rA z2DNTdYm*FHTF*`UXL`;|&(R6VfgP=EQPaUjrtEP}6Z!%38$l*%!H}i6t*Ir<^XW7x zpT>JYv=A3{GV@TP)y>MiU^7dwxqwE#2p29RU}YK zqO4*GMHy5SY|DC8!H$Ycs438sxR*qoA@Nl7g@3>hEtO9gV$Yo}XUG_$&tDGhHg}KB zwnZ7ua5|=SV!A@c(`3wlCp?CRVRPLTJ=1nvUwFF52ZP~

7U@ZaKZ4==bzim^*Y_ z+w^_z?$gn4gMgu4GTxgXO?~JK>teugdarrMal8BFuxgodjqlPnIqU{ShRuJ@GDN&K z!^U4Lo(+Z74PdA(XXtkLp^!AQf8wl3WNBQ+8pC>kat_CI2?IMzV;A=sazTsFKlyq~ z*aM5dFnu19W>A{Vnr+uSPws0ltjt);wls2hK!DE+X*|RpL+Wgb=KKkz9wAQ$sSLaS zf7=ZC*;&6OxzK`c(;N(Vzss;Qm12(Mg8QFcUUpGGy`!ypNhP@jTS!I4cS1!O)=CR? zUJf705%)Z^$5E%}tI;0-dd^I$LN-g0PM(pESH@spgYp%!i6EK6I(?_Z23*AkMI;sS zWaaQ@#1SQbJVE4ijObBy`k}=}h)<9>)skZ<6D(0x9U( FzW~xv`)>dM literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/macro/Macro.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/macro/Macro.class new file mode 100644 index 0000000000000000000000000000000000000000..d602df12af4eca272abf40904b33b23640fc2a29 GIT binary patch literal 1039 zcma)(%Wl(95QhI_J9cV9Z?vU_LR&5(F&7Jo4FYw8#D-87McJPOE1WjABgaAFtw16| zV!;FOP>6qy14XGTbu(u?p84mSnP0zu`~>g}cSHEtT|xu5#M~CM7hpfYfr6LmG*MXZ zp6E|H9_eftAD4y6hA$M{)8w;4Bh`Z;A|BB7kOJm{4l%|zirH%;Qg40W0prJ2N&WIUdpPGdbbv4xA@3L=Sv zVNxF1fi~Km^Gr;b{7u-bnL-GCO1zP|eWqHc$%t*B&}3}xhR6A|7$mQa(1$koM0VK1 z72IhdK(mD-t|wCLCGt$J3Tz*&3s~w?y0zs2QsE)tg7h4LvEr9 z`c+zt@`y(YhB&S%80NUHV1(m_f>Dk!1!ElJ3dT7m6ijg3l<}Cs8_T3O)^{1ybm6dS zo4ap{CWDrA9J3U&jdIy6Gc2X@X1HV>8Tmq~VwJ;XvskRYu7-`G70!!o;ri~$%Onv7 zC7sz%q!Zhe-Mf?6jwg2LW*Eq1rBa7Ubmke9M)Uk15gl)q) z3hR}UXcc*3yo|EEdA44!HTzkaP$nDFR82 zKoTU7GzlbG0!bO*AK){kOcH#!iD@tdiH#HTN3DTIZevcY(^sG3vAY}ux`y9#{e1fQwAT5Gu9zj|KY4ZxwE{Ic#d;uxnig}Sh1+$En2E4V?ZQlx|k2G;t20Vvo}Y5)KL literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/module/Module.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/module/Module.class new file mode 100644 index 0000000000000000000000000000000000000000..f7d53f23f37dc9262c359c15213cafe014cfeb8a GIT binary patch literal 6719 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 F{ROy6{l)+Q literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/patch/MethodPatch.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/patch/MethodPatch.class new file mode 100644 index 0000000000000000000000000000000000000000..481caf56120650d86363e42b3943df403d665523 GIT binary patch literal 565 zcmah`OG^VW5T5k4w!T`eFGLg%MG?%!nf zQgmx6cnF#KGT%2dUp~LyKLFqg_8r)9VAp{?22S9G9T6ad`q}xzSWE<0Li>DRBdPss z2DKZljTKfJ-NaXsD9ZpClnL}kGiIvM#Mt{mXK`gMEv&WeY8j%qiL?E{jFR4z2u}a8PlD-H`WM#}_48!Ct;UbhgOxNXetCJC# z#ogf;J#zCngXVV4{Ae)pJ4Yu^zgH+QC_s_25@q=q90FDrf$}0y`2&#JDzS602J3Vm VQnW#en+R2?!B!eR14Gz``ZurHlz#vK literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/util/ASMUtil.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/util/ASMUtil.class new file mode 100644 index 0000000000000000000000000000000000000000..a9805787e0d4229061fae9068ff96f8d1aa1eca6 GIT binary patch literal 3748 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 C*JZc> literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/util/GLUProjection$Projection.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/util/GLUProjection$Projection.class new file mode 100644 index 0000000000000000000000000000000000000000..1cb2288c782ea3514dd1439ae33e5e678a68cc2a GIT binary patch literal 1261 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 literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/util/ReflectionUtil.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/util/ReflectionUtil.class new file mode 100644 index 0000000000000000000000000000000000000000..b45f36369ba64468087f19dcddc710269b2af2fa GIT binary patch literal 2582 zcma)8TXz#x6#k~UoFpCX1zHF*jGio1>t+zZRJhr=m?)0?)Ds6g`_VJ&dt8fcYOPkV27FN3}-;~Lpx z14dERPoN~=vJVBy0w>s60w>uY8lo9%+&0{@!!)}7M{VxtFqSElovbOj(XeE08+6M2 zb*#q*9w{yq%{v^&n3fr{OO({-R%%Y^n8qm`r|}XiKmdn1=y(~g$gQfFXJeaga%3p2 z<5j#S@VbsS@TP{W>5s5!23<_F3}&Eb3!FhlE=g8A>tJDuUMwDYk!Y zZ%{*NrWa_Yso5~goVq|{sXDQ$qa$9$pHBc<37IYo&pkR<1UJJY$gbewZExX zPuX8rQ8#)Sf%H`bM+p=f*iu1wu;beHU|@TwCDao95kGXagtm5tojVpVYpI4#nd^a(9-0owjfvLjeQmB>hq19LD`DkRaMHw&Fp0YA4z@JVbt* za0%P_R!6KL9>yblBjb1!U3^CH2fES2m>=U#R?3s~^6ha-GKkDzHNpZ<2<#BpDbS~} u-v43~H@DC(uuGs{VD~>r%@BHl<_top^UO(wz>`5dMc_K5=;CSh_RN1&QJSs* literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/util/RenderUtil.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/util/RenderUtil.class new file mode 100644 index 0000000000000000000000000000000000000000..20007c2dc499caa022825d78b6c7d5e5a81c2a47 GIT binary patch literal 10392 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 S^F1!+ukj$SIxZHh@%%4tN~ik( literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/util/StringUtil.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/util/StringUtil.class new file mode 100644 index 0000000000000000000000000000000000000000..e7c679df524837c32ab86038ff1858ecf0b8d618 GIT binary patch literal 2949 zcmb7GT~iZR7=BK&$wF8Nf{Rv*Ahi_&f*+LHqErP@Y64Xhzp7$cdyFPhjMpTg`r|jAbQBMEq_EH+}$%Hpo}^hQy`wSY;&@hpEKRF#$1joElDSB z|tVC={<12aJL>Q1q?bz_jmL_QE+1hXo>* zH(~n%dUtZsxNZ#O411w`Vz}p$fFPP)vvvGt+AR2%WAm;cT1(Ad$uKt>r+p)REoBq} z&q$hpYI);1#~@Oj<&8PTAdGs;JLWh!)36!3+DpFQKWId8chor-#9+OabN+Pr0FQih+-lB1WlMDJR2 z=5^Edvc75AW0vO|cAC_^q$gtnA#a~-_S2Ufc`#ja=4F{eInqi?rTA2&xngE4f5SME zIorH3W8{i-PAm%4=M2wZn_DC#?RY-(8oErej|#-5ouZpI$1N$lcvU+6QY{*`V5^FZ z1{3q7psJvXOf)RWBUud=7FAr+kV9UDt-(Quih_nExEgk#L&F=g*)5wMBp9Uz559_` zhU>VY;U;cr_y`|sIE2F*KEbCNKEvk%JufYIs-^1V)ZC((X6|d2O7RJ7s-9wXm_at` z3Wn>M|6MHPHeO(5`GNS)x`xbuylSW{|5#wAJXyEuD9aj`)@r38xVJW2_aaqP<9MaA zwBTlC+EjI^RB-jd{{Iyp>o=M!*A`zUMp|Qp#ln&c8*@~R(mf$}8+<3}+%Vly!y^Zq zyL+B5J_?Zq=Np#IYujtZ>MHrRjes^Z*ky$kjKQ zpdqI9U;x_5Q}yM9N^!)?36-N>Iw#grd$N?;J(ZBJ5?*Sti*l-8#x{1bWwf$uScaBp zZeE4*(}m^Vr_ zw}WZ`PSeU65n5Kgqg?KxGw>b*)u8w!O zt_10eBlHZdDu(&{6q+Q0ADfcvBFjS({GKG?lw?Cb42{a{Z?RN(q+JH{0Dk+B5*~`^ z5xMmM)9p-gpU(NzLmbf~_c6?wlIb6cCfb$E3R-*Rl>K+m^{B3_Vlxl)vr}e=qQO~R znbM;}%AJUK`1cR(_tDTNZFBWbm@8igv;L}dCdmnKg&bVvf1IUp1 zdpd66C`Yo+?p2t-S7yEyU*H%<$-I33I#Blvx{5LJ42?qQPq9}#LBkV7N-g<5&SN2r F{{sZ>D2@OC literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/util/Timer.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/util/Timer.class new file mode 100644 index 0000000000000000000000000000000000000000..40cc546a6b79fe4ae01ebba85dfa8b292e31b248 GIT binary patch literal 791 zcma)3&2G~`7@SS~le%u3hEf8w6lj6e2P`DS1ymtXai~%_r0Su!jk^ll+KJ^KBwm3R z;J^cLfddi<#DNFkp@3P(3PIw4C0pP3?aVhb>mNVAeFtzKw>-Gmw13sl0vufPu!ZX` zZn(H9U==!10^&fxd8Eg>*b`{>c8_`TWOB-rmA)RUXJs-}*^wN^oOJq=NXEx9)26S7 zR`EjT0=N5#3Nt;D$s{Xu9_A`d%kwgnsSe9R$Kes>vWFB)WuB{3%JlYkPXrnX*haYO=X4lh6sa{vp3X U&zp0(oLMfXx_cAmYNfdG8-xRaZ2$lO literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/value/BooleanValue.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/value/BooleanValue.class new file mode 100644 index 0000000000000000000000000000000000000000..ef0c48300b89c8cf0e04b53140d3617028818bca GIT binary patch literal 990 zcmb7COK;Oa5dOAtV#jtVX`4VPuL1?fO=BeBLJ$%laf;eQs~pN{lP+P4V@G~e;y-cW zk|GX>Gd~J3yRlNMt%SJDYiGXsW@dl?`SBCLb3C zK_bU|5+|8VgH%kX`R6>~QyHA{Fc-nwI1UAm2FmF%y!84f{FDbFkH*14mdI$_`*1l_ zitG8c$0wTCB_xI_4<#pJYgd5MtLCIeIxj8o8SJsh3buMDM-)m+ zA;UXTBr1f#z|`wOoF^mkUaBoM%7b^+qv`BWbgAErQ?7HY8VCekM zIvKYAm9E#$V9{uWx$d>E8r~h2?!;i~MeToNXwlTAf`T|*(xTlIn9cH07x%&z{kA%N zO3>G%ZNVYwlJ|@>BVF~+z`l{Ogk_R8X;6Vd)-|%+c@kD|oje85AgKTjDaRmf`8%E6 zGb~-iScXXm3d5i06&O^3Rjg@T3+rg=juu+DfeJ-$Vx#Erg0!OO_%l>~!I+`?mE1Ye xntp1ONIDCWx3F12yrFD8kiYpIwHeHdEStopr9oQr#0ASbZsU$-a920I_ZOHw%`E@` literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/value/NumberValue.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/value/NumberValue.class new file mode 100644 index 0000000000000000000000000000000000000000..b069a15793384cf4cdc0731754389be931e7fdb2 GIT binary patch literal 3141 zcmb_d*>W3I5Iv)1w0IK7dxQnVI3coZM_CLw-r^8Ni9xX;b_^tJV|y$nXmQDsi@fqZ z6iXFeiU*2kif^JgeP=WpYpKL3s_dS*eb02C?mqYG?|=XJ6Tl31;~2n-n2*GK978|y zVjhWEjnk|}@JSp|d@AO#c-AA>h{M1WF`E&57Dq2W7xP5~Pa}AyAy~4@8v66k%>y%2 zG|Pp|+SYSxyEd;Owr&^7X02Ye2;118Cs;Cnpx-WUSFMs&u4&L0?6O^3;#O*6Q$y%p zWryhAyj`|d>!mHLx?ye=>FLi`w$0+ES+!;DIzzSZ?0pT>`I42X+6A*zsn+cM%)Yg^ zSO31AG574ufmy6u87I`HypzT7=~yrJ8u4zPCC~yZT4J=hl&|*nTGcKW=AX5@d>*$! zQg6?Wy}ws9U#yxXRb;b^ZX^w1vuK;Fa-c&{?y3Sc{P?;o+IhX6M@_HBUTS#q|8ZfD zoj(a5Em*Z&v0_p-R7;MIea{g}nY+Ss){IQL46`GhT`j; z3q$esmWvA;bM2XzUaHrIaXH_>RLhQJjG{Fe+wT%$EiRF=XJPn1q|j0<<1 zqxK;}@)9-e;M}PE0+(?`Ws2fmTvZ&RNRfWfmorLyBj*G$lJg&g`8AM~oQcpeg6Tx~ z5TSHJKV)r*$RYG5k71(0s4+IJmn|D&%SI`6;q=&v<8exQoRS`=q|1rlDTA0gfu^Xg=x2|5BQWp^`wsw`3un_#D3;7 z2pN~IwvxV4^|%EzMG2c9kI>WXk)wc1?8cZ1JL~|xzQk}H zHyEawAm$~wiCb=h7S_fQ&i&NF`tmEXp22%)s<=_@#yQ)GM;SjX95XkkgW0Up+xz2iDig`bJmQ^IcdkV9`ATcZm?z;q>na{o2BJ z#>Y3@rVa6kHXPwCG0Yt-yJ4U5DH_q!lRQwZ0-2?RZ~I8=oUJ`*g;*mYcB6=0^ zH|{JU{$a;5!mVX2oUx31oy!Qfma)t-?sh4|xlTKmaj~V0Y{xS6)-tkZEaQIXGJIE> fb6g*?jFm2BIKKj&%SfCmBjD;FhXYxd6g|%#+wsIWACO5MLK{-Iwa0O$gaCznY><#5g=CS6Mcd7bGjd+A$F4n& znr+1o=%!NHvSGslBp?zCen9^Q|Dvkep7%TqX);ws7JhTzn|seW_rBx#{jWD~0W4$P zMji`!jG(TgMZI`7w_n@1h9w#KTy_O7`-cHz4L32eQ zyQ%^et_wJog!k140@mHmo-Z)AsRDm%(BAcX-^$$x+^@MKqchq5*By=|jQ*KvCxN^Q z8a==52O;C89}Y(>FqP0kbwfa~ccJ)WoKZn{z`6@Np=><7FT2rwP7r6uZ*kE6-g~@D zmFkIBVk_A(C2^-J)db-JcK^LDCfPfkL9gN8Q^rpJa>Sy(iUJC_S%8gE9o^E)HwAo! zN)ERRxPz4fR&%&MWM2i^z z;O^m_@yP#iAY1*7X3**RcV(Z3N;J!N{7~?AH?*@jjtyMpHzv=Ikw8jc52GC80xobZ za(9pCDL!rY7{aZ+Lh1!~DU5L~BF%La7W4D080XFzW@7@A+_BD}(wfY<7-8`u(?#Ow}csKcTn2bUS?ULDLb%9`j3 zqnwHK#7C&_Q+yVw{Dqz9%5r*b)_sl4+b5XO&)KD|TKzS$j~PCDloC(>ewTX2ytKKA z8G}4Sw9A~=EcvgPbslp@ze~(X&SZ`qrO7bId!IKmE5|*R@wu63nW#3>e!i{bojqkl+ng>?Y~3IXO_+^a%f=>jjojKl`a748 literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/value/StringValue.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/api/value/StringValue.class new file mode 100644 index 0000000000000000000000000000000000000000..d3db5fb5ac295e1c648fb65e08df6e41731f2679 GIT binary patch literal 938 zcmb7C%TD7k6g{SCl7>KemFK_=!!VQ-CK9lshz$~}idlfVVdWO9V@My$1Bt(a4M;2y z>-nhBTsu))9ui`6@AdWZx#!sa`|t4yz#hsDEG(+et|Hz18yVe$dC|kVU4PzPk zk?8f3tHkF$>0k385&mf$%1*1U>MFy2xpv8~xgYROE8D7`zikb5em5>fGp;IyqZcyj z1^niOx3#P{ObmG*NKU$@-yx-4ElD{V9L@L{3M~<*Vi{)2n?sPaOX>^J08)C#i4vKk z84S*8Hwl~KSgH%07`lUBYO)I(1r>@eeqfyt13f9$#ZPQ7R6cRL4C^1E^(!#gDIX7{Mq-hcXCcP~}qPrXY-A zoK}jUNKp}-5yqfwdzG#22aLSt7^AV{n!`(R83&!f1SU1FjVVm)i8f|XLXNt#n9C;Y zP*xIc?;g2l7`IfXDox#=98zfa70zQJJAX)M<;L_X_sGB2S3;g&wjU%$ak3|8vgFpTEC;6VV#&rl^NDl9Zt5JiOpxlZP!H zwiEO+K|31tp1JjE*}guoFC2}A3g`BfZI$gx$vX0CZl$!PQQR)Oc3q?4kAb^acDd1Y z^!>@XbL!z}^2jY!Y_Cy+L9|%JO3b^i;zzIAHK*cfv{1NkteRW0FD`4ITes>?wc7aH zu-_Fp25+*f?IJ88W$%{t!ST=1<2*8T|TyJF8`~= znD@zrglwT>4=8GXDICT&H0*$7)3}|Afb95;R7#k9G2CH)WAjudut7aPAOX z#qTdU-Wz|9WQ@Geb*oGI>s@vu0g;%X2M+gSM~xWyfULm;zLZJU2(W0n5v`$7CsC{U z;zk}Cq&H>R!Q?B6ZYZ@0z!gP@Ccq%Sl2|)b?V5-9unn7phvqrc2ziX98QaB8Uy2py z&g~_QQb(7K+Nrbea_6Un$`!uCY0A(@nv#@CQ!k~{)JOek8suS!hBcZCB|@Wt_In^P z=mB1j9=tGdim-cpML2?(5rl9h#rFW#5wGJPp|RJ8HPB(q;_oeH4RhT5N!oXOL}?Ub z3de~CCbGe^z^ z(3#`08;Z9XbELB+XeK}~iFi|BypK53f^$uJYH{XToVgZfPI0myE=Wue&w!3sn#63y z#L|lMF4?ESK7*pmV(np;#ri>!Z!ng{(#7Iz$U@E1L*?!eso+%VqDXDoviS25w;+7V z^y)2{x{}#$1KyKu@QCJ=cRy^j8`ca7I}Ze@y#qGd4Z8wZ>ke4H9-7Fy?BX`8L3z~` ze%M$y>}n`jSuhi!7HLVj{ov2AulZ$$*8#n82eiD)?dEPmqgtX>n)iGe@m2z5#Jgo| z{-+EpScdO@NEthjv3rLM`2+>a7(~bWWjv-Q_~#eIUk$xm#;Z^=G+L#n%3Vk6=-sWe Y5Bzs`;PZSxTHeu6jc>3s{Gv|EgyT0G~ zzH{ca|6F+mz*fAW;)sHyDvqgmP{sR0*olW!99QvyTI_%x;xH_Sq>5AsJ{WQ_Qj0W3 zLmbQyPGGDK7BY3P;m9GY;NcJ!B3Fw%3UXFdF)oEq%Ec)K6Co_a2UVPw-w(;*!zvz8 z@evgtm8*|Q)gM>!390>zibti~CsjNq>5ofIPpJ5micibwlPW%=;wicHbO@it=R){A zzM$fZD!wG;zpUabD!!`Vtb%g_p`>N#xn9fE^8yQw4W7`)^{A!W>F7`)XWHqV0ySNx zZ5Db2{B7-r1p+ZAWeCh4G;JeM%nTd3gZi*VN_fyo>egXBXUcV%7$}UI)Vy&pV?=Xi zTF*GSf|-xzjcm3!R*agNtQAcm8H9Xr4H}hG`w; z6m%>2nv3931z%?ZnPNgY

vBV~;7pXs8Hgg9McUNfLM72{AqDVjESC*ON+^DYUsf?=)Ak2_Lzn) zbZdA9-_-Ce>>??mA%Sme_zu3y2sAv4=QNzhq=N5h_&$E1;D;K1gda0b4L`w8HT(=0 z1X`^>W#v{aSR3A4Ywi9t7({L5P7FZI~ZQChK0V=m5 z&Pe3y>KXsv#sBs>4555%Ew}7m)dyD!OvPu>jn36bq&mjTelZUT|0)E!7na zdF3lGSfx6vG?Cf0HJc)fI+(QdOqNHZirRR*{V0np%dS*7l-JWNveqhW?N!XPhZzqS zb&H3lt*y#_6=!HljVFc<_9kKj0xRZdGi4muTpH3w!K=spx=rVZ-L|&5x|5qQwmkA> z47*TnQDs3Y+fp6%+lsMCO}j8?=4D5t{aZPeG^(zjNnw=cbh4Xf2uvLU3Mr#{K4F}q zPF?{-CSbdZJEr*E`{Kax2_q>@DD>mtM3(spd5CxmEpFRJE@tWZyun1=H77c=y29^Yk4#DZL#50R zq>JyeQf7z|sXQ+V-nRmaom@IKj7Z@${{47O11OIUW~5?aE` zOIXoTLL~eiISD)qHN0{X!SE_BOITgPnn~1=KfG2>#kr1kHI-p_4!QxfCOWT)HJzR- z=h0eWq>akB(aukp(R+&5O^U(w!Of&EE@AyyY^)FN`c z+gKsDX|`PFl%A!o-_*Hf64yQAi`e@A>pETGi;Tfly&`<)Ezj{l1T_QNG4D;X1kBAopMSH}*Gd!<*QSf3mFpg`Hv{ zy2VQLhy&Oyj-pqbL7#XEF>wz4;yeb#>wF0Q9e0a=AnvP0!q<)izHPYI*M<9h58;qo zHhZDahYsA0y$I5yrxC|J@RP3<`$!AmO>x@YWy$%Dm&;4e2C<(7*5r%x<=oA}KERkC zMC1Iou}ZYfrGU1KHBiHZ9LC!i1K;<`2Bo$^M3)B#Q|ji literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/ColorCommand.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/ColorCommand.class new file mode 100644 index 0000000000000000000000000000000000000000..e2d7b79f894146bd7ff2ce46061fe82184cbb542 GIT binary patch literal 2768 zcmbVOTXWM!6#hhPOA#UoP6&jMBElsX2rhvFg%B=I08_^;bwUaB!p7b>BC@1Pa!3lj zU!e4UrS!3#X`bQ1blPbjcwnaO|L8B^rNgw-vz9X$VrOVyR@&Y3o&C;r_xFE(`W3(~ zTvu>V#vuiV6&z6zS1_ca2g545aa0V)6dYHv42gQ2z*8y>NfjeVsdyUC)Z-+cm62Al z5~B*n#P^igc}~G;F&P(tGb+yFc?B;hcu}Z&Ni3dI!7w3YGh&)m!7-^Ir(jBfA&xk& zU|NAGBQL{}5E(Em!ylAT*WGhULMU!$xrD}~VewQUKf&EmHeu3AG-+p;d5XD)n3oqr z{*>WK*pbZhm}}%%-gbS%i+S8}3e$y{k$22k#?I%Nm5s%1({|&*WIr9mXL&}#s_x`@ zHp5~jvvRSt?;2Kazu+NzM&2-)E1{=`a^@JZyqztWJT_ALkkYVWIR#&kU8IyYJ;yX? zv-xbb-8#}GVMW?!nduSclnj)ySB5P?P1^-G!;c!m5i2VV*)Gl@)ulBFO%ESSZlx{q zvJfbcHJcBcrhUQF=j?*++j?e-?B+UiT{dSLp08(wm&m0pC5`$(VA`NQaGcK$YUqWd z;bpiQJZzO9=^FOHmr>9#g9{pFF(=~{4Ht2Vm}__yZ^(F4!&`V;!s>_F9Vr-QmXoqx zp{za5EXyVe0jClZ-JaBM&rf!0cn9xlcn_E9P?}xAWexA6U&d7pAK*i>^Y%Q2b1ex6 zHt18#(8@4ZrRG7MgXHqu^2?qp14-G=>dcmeQ5sAd7S;KIY7VHuzgnY_$&%4Ihg_)!1_cu> zVOiXbo6Pe#74hzx#x2sh>Ao7Wt-rc$OQER898U}l4W}gRdQ?LmJT$@_hYRQQRdr5{ z=0R*5$QeThbyqf*VtMjO3)%g!ILRr#9dvjJ_1tyoHke}6kC!O0f^V4RTVafT$wtFV z+E$LbLKTjsJYVkHV`PULXC5(;O*>%AD?ms5Fto zaod_Sa{nWT9{@gj4nF`BcO#qObdN|_F0wft+?3cs&x#&;eSqEql4$8PZll>TMCcD_ z>y1j`U$AVvE?So!4@E=iXgC_V1^Gq^(nq6sMgWaigC=aJKP>#PX4w(27{GE!1B`L#po%zUwQZ@g|ynKo@QOjFscJ z5REn$(Lx)m=o4+Fp@`K*teMAe+rs@#O+TXTI*wL|udNVor+<`D>q zO9b>HHq7HY5eNc=s4-4vr%DMBxUy%f)lgnW|Z>adTH%?LOC kjbR!4WenWINasC_lF$L#T82TqPG6PaC+PwC+M%|80Yn!8mjD0& literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/ConnectCommand.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/ConnectCommand.class new file mode 100644 index 0000000000000000000000000000000000000000..2bbb4c055e5d8fc9054fc6d073e6975d7b6dae36 GIT binary patch literal 2443 zcmb7G>v9xD6#kk_GMiz@WkUcF$Z`>KAsI;!lwcHAE~`mEH$(%94ztZ>$n4BGI~x)e z@do+|s6VapHx{*^lstg%;Hyx6y*pya4pdpS)pPpX&*`sE?_ZDqcm&`ue#qd6j-wg8 zn!#%s95b*RlLm4)u9nv`m@=>dZ)EVMffG1sAdj~?aSEq(oH5Xivl$fB_w5YcQQv8U z!WjdzIM>PLd?((;dj^V_GjIX(8}U9qP}G8siw1V$l2ZLp$45FY3v?WJeK(#GXd4`w z7tr!SNeXmNyS|*QRj$Zr&c5Q2lbsG6+ncu|SM3v~7B9M0fr;sgv?8}`SAr;Zt5#Kp zVQr~qxs}kfoS;&%{gRard|x_ozPX)bD7hjXf&RhiYxc5jdA47+igD!nm%_eFX;N)5s8XnfOh-Tz1U408+gX~i!$#sd#srLFP>URS+Evx{J)PZ{ z3Mrr`T!EhTIj~<83T#ePs<}AG*}1BWmSrT+m9TTi&oY%M6MOKniBDjgxPraRDQ997 ztX>?`Q8FQMRY%#xB3vEUOf10@*t$OG$(rkxWTd>&M_0jLwmr9$Q)TA%n5cjW2@(N9 z6Q5#O2X(86P1LZgpaOi)dKwv1{#tz*zz-a(TU^)dUDd*pc zh*nMmV2)>3Lbf@@ZJ{u9kq`-q#`r?jE)yaLQq+c0!aujBTI_lW$S;soD6bZLf;9CO zFooX#FhD(7R^ZBnc2t$mHY475rnj}&yqI)Rm@Uqon9ZLO7}utJM1u&eo0_7 ztpzR3O;Ae1OdK>XH1EmaP>UipI%O0EQGU^83wEU-vD^=Jne>4J*R3DCr)#=xoRRzqz9tE>p`?+&C2*J$Dt=96)oSm zUW|7rHQw`#hz<6G?v&dZ+b2kgjlq_ttnsl%lOgv#9Wq^yL(o~YIk}0|9rW!678TjC zglqBal$8FqJxj(@aI5DCp~fRaP@9eyRApi*FfzEVWsO@B%azzF%yH$D5e7bc-*^`; zuGdaRRJrD=(NuIIDgDWH9uu7>=$UK%E&V zJotJGHKMuhyAAD^xT-fF=s_QPv7eOLw7~%k za>t>9;if-v6gt|;`+0bzy}b_oM`VWU$lM*tcGh9c9Ms0M8%fOeI)5M0MjvUv;OM9} z{s873bTx=gN3>tD_cwGsMEAmd^kjSM$Wp>J+sCDj&2{uYz?OU1dJo&`c%hE%zvD%L zJLp@>7Ip04{vmcQ2!2P~#{0GV*j2}Xs;dpEu4Cxp+Rys7klM=sE89u!zyNl!J2_Uh z8x!o-6nB?dYmJrO!a@AR_fhrXaI@B=53Cv^lnVN|O^q>jZ2&i5k!qud6}-%I&@fKR XZfM<)F{WdJKQXYMMu*AXfLHzjP_L#J literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/CoordsCommand.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/CoordsCommand.class new file mode 100644 index 0000000000000000000000000000000000000000..8e2c041387cd360ce427c25716509589dca9d24d GIT binary patch literal 2121 zcmb7F>sA|86#fnbW-=WLol@IWflzDs!-==o4XMZ@O|{de5Jm3J9>C#N4w#S2-U6!#M)aF$peQppnq>9^dO-XNuvCru?m)=UT zFYQI)xIXumlPe0KJ7FM2ASuD?DU9z)yUHb(F%Rn7B5uVi3r{%G4FfXDI-VPCg*>h@ zjK9FDcnl%@Kv{BUca=x2iWudv5j$epO=|Wx&a;XL<(?`ThE5YB(#ajendIpPTnftG z`0Kg><|qDflZ@wgvRExWi~S(&2YG$NV@`Jm2gG=ZamkhV{A>BM|n+Qglj+g?3ZFqkzV zPaLmIPL=-Ig!;EX^7w&>8K%2qDTFHz?4{(fo?y%CWLN0wxhtARJqqg&8Q7v4_r$i{eO6!D>bKY-w5N&PRgwnT1LrY< zVO*m(GquKbOwx(Q6or=O-^p_y>3%5O$Yh$(e}rCWBK!0RM#VaF2y^ua1C=A3tsG)- z`ZA~nI5P-^tkuo=S0zU1snt3Rdw zfqw2ep5U>^{s4bek9RgH2&BjAmwV>kx%Zjp&OUecuh)OP0G;yX2-cPJm5#3sj4Njxw{&b6m_S9xZ5?+Q z2G^t~qjiRXVriE_tN2a9Fj|$K*oxgf5$y0iha%akZ*ymt2U7XHpcWm-kYT0j3M-H; z?)pI_Ln{>Rc6=CH(rr7I?Yl1bn$~R@+P>!rJF0Xet8|+9S=bDd#p+M|3AY^XwXAv+ zNUyc3$e4lPjvMX;ve_aEb5&17mP^d+fbU0Ech}lZk~Weg!c0rA9Y>1rIZTF>OUD(? z;Mk57US!qY04rkq4sS8A9|%t^ml%fY5w{O(yq)x}<1T|y_v648ccr?ZsdEi3Dgu;s zvcWKRmK1$~?mqQ*k{A~D1K%w~2clrdK|u5hp$MLcz{E7}nfL~qChlW~XqfmGRTDLA znfOkb2Y9Gs+e95RCU)?M;p*vo>-F1;rFAcsH7>oH@M48b1-p36aQSpWpNlr}y-K`( zI`Is0>_oEd@L#&LDSi3>=!Buvzl^u#vATMiVwmmA==j?*RQrhS$Mafwmx$76+IG0x zX2|z}-P|mZfQ&W?I(igxrD3xrqJNONQY`(u7-wX-=|!Ry@JKZ4i43-5&!Z_xrk0M# z$*|I$Ez#WZy8}Vgp8A2)WLWHfgnRONtj8*|lFR|Azufl@-;&SpK`6ZD!&pWUQ998u zIS*)J1kK`*62E$VEztK^bJl2$<5)#R^ZU;hmq`bGl^iqaX&hm+gR$qhF{wSng_jtoNcLuWCVjk_dyYv;ooMtTN0_7v#d83P=LW{eP7&Wc z{RpNpO3@s#oF<;L#PS;PoW~U`Vh(HM-NJ|Tpj@Zr}1gaFu$^QT{cmP7(GFAry(hEVc-v2#wAFhM|qVMp?%KV;9G%q)fpSKKdIU>eey< literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/DupeCommand.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/DupeCommand.class new file mode 100644 index 0000000000000000000000000000000000000000..9350d01a87011943566b32660c7104881ad84087 GIT binary patch literal 1980 zcmb7FTXz#x6#h;won#oA5Q-I~m==U2lnz&Kg=!6y4ko3N(i-qKOvZTZ+}7lT+IN42 zuRi#UtE;$l>7x(+1K0AGxEAO>nKY0vR?S*DbIv|{@9*1}+4I}eAAbRG8J}fPR#3^{ zYzDI#oKtZGb1EjF%jLX^3%Ho2<&s=3XK@9uXYmH!%;GJ)tzsTmrR+zj*54& zsNg*XRfe&v+~Z<_Az3P~Go-41%Vx;cxM#0)-3NBKW8zU}m*>7PCBEPt zhVwPo)VMYsrIG$(9|8% zYwHaWa<4rvX)sQIgCWhmperQ$3u+7rmpl|}o-K5j=vtxqxzH_#+n&(tdji5b*bt_* zSvP|oYX#RC)P~;;EqjT}(DKhwo0B+1Pm1Vf6qV9MH}c;1=`p?NIQ~|rxb1g~!Y{VS zNbbWT_Z|`pKit;v5^iW%!c7g!m?Urw25xD1A2khitSGpxVHF=JxTB$gqJlLIcd@Qu zL&Jw?YPg5{3>Sx^q|=rkZt8(!ZtsO$U8N{(akpdN@B|k<=#Lb9tl<-U$}so;YQ#{E zH!uS}sA<2R3@3)^jTV8S7E|c^FBbK`NMwJcEyr}J0FyCp4WoRIDjZNVQ8LUn)lqBP zV$cx`Go|vscg>j0tsOGV#_LjjDam@2>(!oaW0krsAK6uXPlUeXNDo)yJ-A&*@JL&a z96U3sOIMZHti}SCRg>BXe}C*+eO$O9dHphP&+!#FWY44EzNwfrrkwV%4ftCOMj>5bk1_VBXL6KQl}v#gndNbec3NbJS8$w83{yDKcltXyO_8iwIh#uDLiq-n z$}TdGen7T9y94!CEG8GG^5?$ADLNjIq8(^EI5?H~9^>-3i`>T7N%q}ee?*u0pKz!t zw~tZS#bHS*2}!C#v_P@RFXlMKl_Tk4qI8T%%@Cz)^sJ&tgLbAzxc literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/FriendCommand.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/FriendCommand.class new file mode 100644 index 0000000000000000000000000000000000000000..bed615f9f9851a424798ecf626b133665695aa73 GIT binary patch literal 5414 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 literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/HelpCommand.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/HelpCommand.class new file mode 100644 index 0000000000000000000000000000000000000000..b5be24d5a6b0263e8896c81fda787aa8a72a18bf GIT binary patch literal 3140 zcmb7G+fx%)82=rTu*tUZhL;a z`s2?4*5O+bVFCAv*eN0+qEA9K`X#KvEWD!r{zx*W8iQ(D=W}<_YaiAvhP9D|rlj?_nn9>X4 zv0b-PhI+yZsD=@6J!i>K@TiQ(a9YOWSS#QO8BgLV8E5dcfM;Ypi{}J9FQWr5kkfAA zP7Kwv$!yE$#;BI&XRf6iUzuogJ!}OI$aoPi@!@6i^1&+;V*wej;4If|lkqBEV+a+_ zgaQ$xAY7SHWxS5Fj@ZTkhLY6*hT39Rh}tK(Z-d45wQ&lU(wiLD(%oDX@P>@H@s4xA zdKvG!XN{4&B^mE=?&t76zrY7FKEy{dKE`H@IgaA-dzVu}jM-eak8a#n3&y3t&XGKk^+ z=s;(GS2sg_k$Q7=scaX;HC`9Ip!-yl@Y4(%f}tXIj!Q_F^b$NUGc5^jU14r>+c8v3 zvxw*xFLk2eB(hV%e2u^>X0A{U1VhvwO4U?KGpW0@6!4!5lh=;idLX>z!SGz$qMgh& z3Wmkk>Ez)MfQM-FmNx@t*T@kq=Fp{GxBUCn1O-l+Z zZ3lQ&F($52zjlo4684I@uw6C!k~)2koAhZ`uG=*icl7Km97HQU(W>bg2b9pKhdy{T zw$iKzr6d70O@8M42_-`wzb886^?Rd!pPx;l^rB;O7mX5`0*kN|e%wuxoHL}C;XO2C zSdX?GDEkKs2o}uO)a>s;1U|~J67Tk z`u`Iv@E5K9P5b{M$h-(Sj_)An4&yCsz`gLH6IpCTJG|WCZZNpC37aV#b%fMGyCpRK ziY?emTsnzG6u!!Ub1!X({GonOz>aGKG+V)!uRxanAwh@q U5OfK8i5$-tMz8jIyt%dJf3a_N0RR91 literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/HideCommand.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/HideCommand.class new file mode 100644 index 0000000000000000000000000000000000000000..031c25d6277c834b9e97884387406e6de59d9d50 GIT binary patch literal 2576 zcmbVOS$ES$7`=*>NHKy0CoG{*1Oc)@VwMzIc5p%oB<|vbvUC%+;)rOgBm-$_>AwE~ z_yNr`JeYIZLr)J6JoGR0^cV2b_a55bu?%&H%%OeoXy)6$J9lRM>t8?q3}6J`t2m_K zu!vvSVtHKabFRCc2C@C-%%t&ZEXt`E& zSVF3Q;EV)0=aoze9TS#o<}1!cGng_i+LUA_yrN;BF#=1h>q0r2wL%FyCmb^ySY^ZU zg2)Q9q3QdTxk}b@d^=n89LI1=*^^eu%*FEq%wt|PixO7#Ph2uC8(G_M%h^H{SZ?`% zC_@P?$Fhw;!a$SQhHqsZuT-(k>}2i3pskkcS0YjClAu(EzHL$2bs74de+otvlxsi{pLD^i1V!_NCD7<>=w?_XV@EU`zEbeDhHpfK)V&36=SuqOR;at)6%ngsx*ER4F!MiF z=(gvU&7iL4c1*i-G zAtv4I`$==!sgW1o(-PXvAn=0RtiiLYS|RT%9{AcrLaMfhX7orR_n#O17R4R-N4-pVH%e2yh?Idbgh>Nwgs1G)z@ zl6)5}=TezeAtPs6@1X5g&3b^Nc*KDf=t2huIn!bvY{w3+xG5Np<4M0kMk_^KgWFqM zt59x29jrpVwLQ~bB^_^LSryt2d3P1d^F#M>W2lN1x6$zf`l$K|o#*agWhPTa7Zu(7 zWL9ygVs#a37VygurE70OkryDRs_3bOTUW(%LVjaWjP(sMHav>)`~t2u;MOeED>MDY|7OSxi zy;#qU*}%5kmfeo>}Z9`~<(g zF=DohHWH&h!^Za9W`Do8SRZG7H literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/IPCommand.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/IPCommand.class new file mode 100644 index 0000000000000000000000000000000000000000..33588db880582ab0f175714522ef580ade3d585c GIT binary patch literal 1836 zcmb7EZF3V<6n<`#c9ZSWKpM)6Vi!uKX+u|_Do{j9S~Qr1=!R;+m$}{Crfc_Yb~j-E zihsb*I8I=6^rIjA3H}zx@!Vut(59l3nVYlco|osG`<(OJpFjQrU{;w<8 zP;iG~;)dNg`ow192*@T^El*Qv?IdA+7ynkV%zs9X5Mn_VB6Lo2kdo?=2p@@1w*x)) z^?k~qr{!umfe$s*a96`eI7uKh)X~t;#65=jL9SQzPeDt=$C#I~W)*y*!9-ibeQYZD zRKsW3Qt&{-LwwFKGl198Yb}Z8B^X~|mZ7u}hJIMl@A|f<^8~ksFXdh3|Imb?JldQG zc1o&*QVehW`%^L0M{w=o!KeQ(8cES{%i(UoaAHK*TCMzmcn}bu^##b$QSUwWL^xPLXGSy69PTyhQLSmV*P7K0f_ljAOKhna#qqn< zT~5u*3ppE7#wA+cGqm4)BJ;i>!~r_c&TS)<^L>OiFROkCMcZfy8l{GK0{ognx?g7YM;L zWj{^%%h0LHv$%?LxP>`Xah}%Gn*+QngsDt^I^Ac;sz5e#gp_b5HAv|^=BbKlTqCaw YRPh4ctH>1oz!e2$h3*zfGlr$V05}%&`Tzg` literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/InvSeeCommand.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/InvSeeCommand.class new file mode 100644 index 0000000000000000000000000000000000000000..db98c1f9206128f4c221b31268252607a36fcf36 GIT binary patch literal 3113 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 XiV&oL7oihR(NiK%CMncUZmj$dH`LSk literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/NameCommand.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/NameCommand.class new file mode 100644 index 0000000000000000000000000000000000000000..6c5f013bd992511b76ff457fbb71336eb750e863 GIT binary patch literal 1763 zcmb7E>sA|86#fng%w(80ak$jBl#W#k2`$ssdIeEPsm6v_4WNKk55plDn45D^`zZPX z{;o@d%dYkTd<);h<#L}SxR6X;`e&cBFK6#>U(WvR&tIPcxD7|e4Fxw<+*0w1irX5d z@v4SPcukVmRlK2L2ybe53kwAziyDe}TgsLcyd#-+C0SOnBF}08cd)A9u7(M`r{aBi z)+G5rBh5V(b$PBSXejuQVPw(qon(n2H(TCh$XA0s!BDI_zG$T0u87w8u1gZ59@yO7 z9cr8x91sra{!0a1$1bR#=T7Iak~;35h@=_CE;U7B zrhRBK7ae;LI`*a87G|jPUHD!aC#J^}yRD-w#qCN0^Bd5hXUlVMiQ2+uJ6&(7GcBmBf#J8l(&-V(_P z_R4Iz{_judCn#~Rw+vIKj8Ar+3`fcN@l-L4lkd~LCZm%0D&=lmYxzMWsx+O?_+wNA z>F>VFABw1Uhe0K7JvbCT!@Z1x495B|64{MQ*@MvR?Fb57Yc$uF8`V{Y%g@*&eOpRz zgomN<_ZY5cU>qz+fB5O4ngqS|LIrn&R<+G(ffPg(1(CetChgj3+Q*>1NPe~@Nfsp_fRVxsE_81LI>K~wfwDLF!~ep4$gFN_B*T+`xwQo6N=KY#dC&ngt4EY z|A_I&nAkePq;al;=gF362j@Gu@B>CkYh3JLO2W-S!o7+D(Q$%3fwPz-;OB{6#4M&z xr$QW10U}CYregNs_ERC?WL2hQCh>r_*c>H(jjS}}ihp2R!F7dn^CTI9^%whe%*y}( literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/PeekCommand.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/PeekCommand.class new file mode 100644 index 0000000000000000000000000000000000000000..9a8048d3c8a26ba58b03c35a3768851c0954480f GIT binary patch literal 5764 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 literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/ReloadCommand.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/ReloadCommand.class new file mode 100644 index 0000000000000000000000000000000000000000..6b4213fb1b14a8d805bfee5fe69bc882b7ee3d6a GIT binary patch literal 944 zcmb7C+iuf95Ivi?v1?pXOh_+~G?ZJCLR|`PMMw~V6e;APE|n-xTW6Il^-Ye0_!j=6 zJOl{|K7fxx%-R+bG)Ulw@yzVZIkRWy`;RZ*06fMc12=Ru3^WaFnOH%~goT^RY%k*$ zZkuH87`Utc_jI&%bQmg6WGK_84CQv`m_h4BBf(G|$WRPt!Kp}&_^D4Bdk}ftKjw*4 zago&0iJUU*4+7yNa?FD$N#)d;ia4H~%^VrTzT-tfz{8PqDEx?zdU#6&?x zVf9ZqqB>NQ5mjC@ZKV^@@_Z@6)WT(SE$raFg$JnW*tOtb&%#4gNu^#^)XMwB$ihDA z4152p2193Y3ydr_r-$z(!%J`ZAswFR*Ke&>Y2jOkU<*Hb>GJ!mYR z)Xkrq!RQa&qi4h33x=(~tVK~vJ5WiorC`wgXxy9dlytRdbJbS@Bk`+bS1Edq3VA@S zYcuUDN^i<`*|jyBea6yxR(*x6NnN1+tJGSd)4kl7MQ%KfinjFoWeR&S!8Ti;GzlvM3rDM9IJaM)fk5 z#khekOc=0nDM!m>4pW%UU`Cr~^>W!jAFdd4mQC z1fIwJRlCMF%WaWR)8f5w7={X!xBMNqUGCTInu?@fzoA)lOFwKV4Z7!;4&%_3bU5%T z>9n_|xU*j6VTYno3mTCl?o0iM{y!upbYyxpSr`uPhGAeehQhq-1{<-p88j>vSh4U| zEpDyKNI1%J*0{1f5y!kvk$WkQHCJt`w@eIS&cscSbQ{AI%`#!(P6qQP7Em^E7xyx_ zZ{h(SGR*iw*&b!wiTE33leQ5=>vrh!P1|v$@ReO&rdJ77CeRLuiA6jz@fa12b|QnS zi6uN?82_(gFcg#hc_@F^u2VRMNVh(aNolqItT)udB6IM=vtu;>JqcYAxMw zi^aW_V3EO~7h{bO;a}PT~|%7@`vkr-|;FRxH*>#(Q@&0GPtJI;J(8 z&~Z}7>pEtV7{(h(ynr{=a!SW+5^cyP@fPMfXgS@1xA9IV=J9SP-a}3;3mWno&Lpu5 zXO;E)9XN-AhVx1E;ew7u^}U!xN~!zsL6X!<%Ht&+mvwxojDMbQ3!c)ZGn4r1T;+0MQHehAz5&%eo>s33as8O#U54JG3c#rhVHHT5*$j) zaOjk6yX%3u;a1JiHG?K>rX#q&ykR!dBG7wU&die+0^vKnB4!L605`CVqJa_)5{9OM zmmoA;HBiQi0f|)&YX)poG&lxac$B_@Yw!&OAUO8?2jUDPk=h8X3{-L5z&dVd*f8)Z zK4a+LTJ&sH+9g4e52$3j^6q-8ULpad{yDxd@TKx|6JrLx!q-&NFi~dMl!58Ep}8)J zf{y7EcZ7j&Fvc+X|H;UZi9W;u6{FWmH3HTl1mtdFc8Kxd;|V@NPR3x9=$O z$BQjJqeI#X5Axy$d89!|@W!0F(A%=FPp31>t2D%vHG!0; zj-yt8#-KUAC@pcV%I#pj?6|(j@_;NO=Nv`a7froFV~En!n9mo^pUP+F7>1rRXq&c_ zSb}?=aOf(=qZqM`Yt06vgL>#TlBeQqx13$!1Vv9E!gJ(K_={4kH(+NlN48uuG3cqO ztmxYzeBbqz6HL&%HcW3H=%r$+(P=$I(kv462lS4nSnPMSEw!iG3#nKtejkaub?X;t zRqq?njUIaJ4%45}ID-*nNTT75v4%gkgcx}Qei|K%$7|4TLm#a{zdM%ds3Ez)^1q<- z9*ld~@c=s+reo>Y19UOm!ZG#N&F~PrrsL`OCWh1TKaskH!8AGQITD+!q4ySybo?Pw z`8!D5`Db%{6Pcf}`#1D0-A8|Fpoa8#4TJQlVNVTvDHzH7?%=>vR{Kd^_m)l#wJc3l zYdch}vs5Rrn`-XEPV}P-gY>r-1K5ul3?T~>ON8bX!gHB06oiN*B)%goz9$@h#CRQ} zDa6VCAdZk6SBNyxQh!Hb5ng?`P0zvvVLN~yFo~BbgQXm~}#F%7RC{~K+Y MAv*9HDcf-TU$ygG;{X5v literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/ToggleCommand.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/ToggleCommand.class new file mode 100644 index 0000000000000000000000000000000000000000..a6b82c85fd12089555f26ddb168a8c56c64d3c55 GIT binary patch literal 3581 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 literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/WaypointsCommand.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/WaypointsCommand.class new file mode 100644 index 0000000000000000000000000000000000000000..d52ec481d16fe5f5b7949ebd0492b30ba79c4565 GIT binary patch literal 8524 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 literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/XrayCommand.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/XrayCommand.class new file mode 100644 index 0000000000000000000000000000000000000000..acef5cca2a9d1bb14a1d3b57019196e40223d4e5 GIT binary patch literal 4522 zcmb_fYj_k_8Gg^qUM9;xU?D(+Hd8Jo7s67m7AU%G0$rL!nk7IAEe^YrWXSByGCP|P zEVUPCQG0;`wdsXYTS;xL3c?awTPrGRYqi$4-tnJ*{O1pS>?1yYXJ$7nu!-p7!;`aT zzVm(Oyyttr^Pa=o|9b6B084N|!e@g}CG3!pl#r63g%CrRgl-8v6<7mZ!cGaj5)27x z38n;#n==x2Nw9f08=}VHO-@2z2m<;mup0v*YW4*2xe)HgUOs$J2%pEjA>4=iLwErD zc(Xr*8F(;=heDW*0}{T#f4|5_zQlVE^GP1zK9BO|G2R^HwnHI2j>8g;NH{9t2?<}8 z@FX7?IpgZ84CDb02vx4ITuY<$8| zlfA8K#@%}m%~T*kyvz_vSUEeXt<`y&CYEe-0S80taubbQ35_Dxt0`@hp4Bar-1rB> zlBi)={aIze$|;VeBzuTRP3iAZ9mU;zR#9zD>7yW`L9tB5+tn7nh!RbulvQqawzsKi zZFT69HQrSCYIjSaj9YPF#52arM8>Ung{p(5rd&s5G@+Rx;5n0>I%IDrQ%s zrltmzq-8p)Ze|JYdHh($Pw-P2Z}a9IY>@FYyes49_=Sx35SQ^wydT7`WPHFU3Q*p( zltO2ev*~dqo*SalpMGwrOVP86X*r6j^r?oP@))MoW2)(ziO#5Q7b9hS$d~(wFZ^r# zCWzn4_#N71{2uSp0v;uNt&q}XTj|1TRqj?&mXfpr>(>6HLZSAaZjH@`+>K>yEvuPy_!f*oY8i!Ks4E|! zX7mw7DX0lU^{67j&{9TW%4p=(!g0056{e)2rZZGOWu}eC>+YcBXGnCNj;z{EXJK9$ zx4JURGhA1GzX?xDiQafyVq>%|MklIf6a_2zl2%RZ)*Mf`T2+&P*bK{S>qZH4RhlH4 z{L;i#(L8HiI7 zuCI;Pjd_txApdx3Egf1nibss$Uq>rQMNOhi)9eH_pk^|3Z80>Kro8Y3sJkjv1-&a2 zi+j22d$bh4HW;Q*v0U2u$TLE6EU(WHG_39zT}mYP^!V^V(7j!uXPZs_Kp+!6C!{L0@UGA${?PK?E|do`8t0d$r@mB(?wia_S{ygglQTxIT#+7x zblp-<;CHF}OIN7-%lJhFhV}Gy3<2r^sroSUzX73B42y|QU)Yxj`@?~=2-X*@61P?) z&LC7jG2l6l<0d)L=?{-jbOyo`5}m;EBw{|^Vro`?H|SsdCVHbY?}Rb%0XQ7L)`>N`k`+OJ*ot;U=;ZDr&>LDK0XO<_Ry(W66+k+8tgxjAbi))xPuC zSM5868?biIlk`#W5QrJL$;ZGNHyo8_4A-FXgr6lpwFM>`#+k_74*B}H1 z6L146F^3f4M$APm>geBc(u61)NUi3Rc11`57SdaP5w>A5sl-zBU>O|pI)a<=ELPw} zti(&Wh5jF~nqIh3{EZawA829>Ync!0SS7utr(ivsiQCvbw6eu$V+m|v+i*KeqMdbP zBg>$J9YrTQgRN{B+t_*B$=<_V>;r6PA7Tf)fF%1fH1-#CvA?2+{T;d>Vy7UZSC|Y# zmkE&Y$ENQ zDjuhqn&~E)D;~lYbP|tu5QA-)Re2H1g4i0wwu_Y5Anu&p_%UjPj}a99iCOgB;2CCK bM3fIV)?7YZ;~8dFPM#B_mF}Wh1#JH}BazK0 literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/YawCommand.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/command/YawCommand.class new file mode 100644 index 0000000000000000000000000000000000000000..e928024d2d8b6850dfffec132a750ccb4c06feec GIT binary patch literal 1938 zcmb7F-E!Mh5dKbVN3yEKLHQ|d(nO@Bv7Mx9ODU9uK>iE{Cxki)q~-6#R-Dtwl8_}r z9su3}UZB_QfZKtA3of|ek(hyDk8PT!7MWo@v);42XLrBdJ*z+d{^?f$Hxa71q2Lu2 zH&wi<;+BSSyr$t2UYF#yiZ?X$U|z!l-qf&&w=}$sr8JS{G*+;x5m`&4fYmhK!Mh5I z8V2#6iudJzNs@I*HZ)RypkhxLdQzVIbVvyv!ouMs)^OU`Pqqk3t!~%aD`}-w~u7 zycehKD~G&txX%4nvI^!Hw6Yfk6}uoLqRdG~SEX|bOA>~G=OZ!n?2`QAlH+(s4fEKG z%+NC%b|~4vJeHSqx@s=8E4HX(0^2%v@R5#>VG z_Hl>$Ky1kn$LrV-8sZwqiG*^?a->z)2jr0KeQ^2u-(vF|5rd`RFg`? z)_Q%1AKL-LY`iUn5aF@4*81CQ*_JoyUOv`ytThc`;DtOCp4)mt8A|hxsM2$8du5pD z%Jh^Y3O9N>+$lA~rTCdEw>J&-q_|PuTH07yqfq~`jXJinBHZ_Fw@Q;AHy>S-*LiMq zaV%TNouO7kuf4<=h6wM;40Ki-gW`C#l><2sX*&qKK=Qawn|_?W2B1w(>BA)Y5}lUO zOB^tiH(2r)T0#jUQ8toB>M?pBwyY9#*+AW1*q z+x$!_)r9gr)O-`_!xklQD@P0g2!i`iKq@l40~?gs@y7 zI!cuoqwL3VjViK06)6&?Jwj!Z^c!SbX!C^V3Td;*kvGED!7aHwW(fHREy7vMQI)Qe Yz8}fVU%0Kn>iH9+6QsXJ(jHv@2YG}2?EnA( literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/config/BindConfig.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/config/BindConfig.class new file mode 100644 index 0000000000000000000000000000000000000000..9af6b4e595ea0beb7855753b2478b8fa781fefed GIT binary patch literal 3092 zcma)8Yg<%R6n+oPaBw&Zg16CB6mKXniR1+@DHnx=(F7qhv%|~*j?Ar@GlE%J-ZHha ztW2%6i_yKb8Xn_$divyteo|TXu5)G(WH8T%z4uvrt+m&B*JbZN|NZTE05$kk#h!e$ zdGI*eRqXY^hYk;1XqTZ=hG%5xl3|~U{VJaIK$GnP9FXC;d>r)PdFWHnjev(k&;tWK z9xO%g6!gK&$01?p7fMJ(!YU#j%tKT~OvMWxED(M35f{Nk0W2g7a2NwJ45~Py;zbXZ z;ixEhNmeh*>J?cX6S-GqcufXsKCa?~g1k*;#I&|3$X!w1p}dfb%%G|^@CnF$3|En&kKH+%JPG;Wy*U&4sRlKn}a8IFZ~foP=1 z?Df@|kzl>O+{jZxQ9Y=@orr}@OF_y0mP7hs-51g$y}mXpZbo{^lpBtcr+gCKdd&2Z zAsI4!t@b2pdrUEPnxoB(`nL0*^t`yC2aULbIiovu$(|k~ZUpz(JGM#mSlrBFiNcMU zV>TKG14hg;qY=tYZL{=1f2$s|Az@D90rrxj?n?`hmLypA&(-oRN6=Wt%bo3eTfXBEuK@Qp{2=w&vg_BU z4S|L)WNU&+4y+HD2N1XL08jvAH7qG1;p|L1lJ!u_|3-PSlfer(%m9v@HWh z(lSH7W~QTVMVTBkSBy#RboEIqPz}P-A1lG;k2C$8 z^vP*2qqVe-Ze>5h4&0a`94AO+k663o#O$UPVISO_4S-1u znUJVFT%y^2Bt|Gb&H>Jk)*Oi#@%oUSNEnRE+DV<8pmWK6HB?`n9g>GhF@c(z8yXt@ z3ThtJk@1HXSkb+)7|quc^eZo6SUZg)yjB9Cs1OQcyh$v(KexyA04ZbAEZue`%_MOh zXIhxgtddOP+Jz!CIylX)rcny>NE*6RL9@mQWGYKQ@6!{0V~{#s5qlb6NxQla839{4 zEod-#8|p{=dRTnX>6e7PGHci$tn75x;fZa0IqH=9tw$l$_Hhu7-1anEBhf+SQ)?g7fVKEv|hBhogKptUyI1Qp4N3jaW zP(>{jIDtyuj6NHOCaC1E;f+?yS6>??Hd2S1x)a!pEj)V-TJR*c62A@Dj%}!;6(`7B zPdUNxOd7*RuFH^j7o{q;-$k*C9e2^7qABMd@l;ea%kY$oLOVynKER{g6ukcbV9zJm z3({aO97buYgKY|nZey_mf8}kIDY%TCTr5%W2bR{lyskS~?{#JHuB;frvaVq)7t)Fp z$|XwW^20b2`tlTrcm>g~9J+UlQ`Pt&T;lbf3Bnc>((W1pwU$9xNBVjOVI$$%j1B_V zL(t9>whIL8BB8p39h7dwRf2d8O*Z&7^u2??3*;_pIyVY=kf65`@~dNjzRr^*Sq12& m8KD2cA{BlWyZ%P&Uw9De9PB1@4xYwGoIQlTkD^z%djA7V>M1w? literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/config/ColorConfig.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/config/ColorConfig.class new file mode 100644 index 0000000000000000000000000000000000000000..cdcc4934e5f615be8ae958a1c893d9a4dc85bd91 GIT binary patch literal 3257 zcma)8>t7UA7=8wJ85~AM@V1(YcTiy!@dj!tpsc}af*9JxVHwuZ-JNxIRxr!T(o9V) z%gVBgW^^~L7L~Hw@8^g9q_XTeGrL@5G3UcMXU=)A&wDxN&wp>-22h1RWVGaCyMjuz z%GjY`37$~kL8}qDC{MMOrn>5dY~-kG;o8NbomCb-!hVwWw*?M#7)aomgtS~Fr=wa&VRY9glAA;Fu7M+{p+@vg?b+5ycU(PCkLvuzo%Fo|-bCTYq> z5U#}yKM9f%-QVO)LTslYY#rlDGfe+R{&PRi(zOoVk}$ddWJ9vEQ@8YvZO(~f5?vO4 zX0b%#!Gu8v_1z&oZX0Hde50FfEwrymi#wPwN1QA;;o!TUCMC23rp*s6K?@~le0m`OPbx7lq{)OQdv=% zK6ay$s0ek2RV>9R3993L8aWlOjEgEh#78PV#$_3ws#Rk zNF&k<8~f`{VnU|#Im0!mHlzDG42vA2L#$F;59(bmZE@NLlBSDPSddSm z4$++$pln8F?IhE(!m|$>q1~iuS@4DQ$?Z7()wP0dWmn-uZctec zVWhB!tmYwXPM?dhHLl49zzBv6OIs=z(QG*wCzOh-!2MAJv6ybvMzlmiXIz$#=-e=w za|Xmvd}Ve>9>m22Y6#TT)dwY1J**=`m5v$6@J2HhmM|)=Sqa@;Ps{>XplmY}Afek% zt0lIj0g-3kP{d3SnXz%+Mz+)ATP!Waok4k-Zry@jWV-8pBMX3KmC1Ccvcw({agFQW zp_`1X>pjDO3J!xgWB1w}c%$i2p84wiFNI0NI5 zha#-tN_EMw607(pp*kZ%YKNCpz{x&%+7_hX?L}VW!W85SDCCr%!l)gbl^uO3XzPQT zrWxIfF-?n77~2-SgZlEK!W70;d#g<_v4w=#wC)n1?X4(9p1DNMMIiB~Yy=kZh) zO}c_2pI0mk3vXcZ@f3VL_ij+slpf>@&5vAjj6H&*eCOpl?rfwhz$CiiLoudse=17& z^jnIVSdCez!)!ET4nlm}MfjjQgfbk)LO${;C}k0jp&TdRcc5tC#aYKy4LLpJD#aSC zB?u}G;8Coj?xom*_1HiNS0R8}Qs+{F2ld$KSavcE<0jfP8+mt8BBS9hiev=tVv~%` zIrj*uB;zqLGeBkfhrR}3vPf|6ZWzc%2TM|%HMPEDyPLm z<8T2N`{S?{V`+L7v0BbJtl<7i#-WCYtwAeM>?DF`h~YV+cb>Riz$S9n^YyY3m(bwg zUq$y@NiR_MP}1ps)WZl8`5aOYV10QI)^jsh|AUz_w#sT~q)7 literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/config/FriendConfig.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/config/FriendConfig.class new file mode 100644 index 0000000000000000000000000000000000000000..4cf4e56e2dd230ca4cb2fdda001c28f5c5eca3a1 GIT binary patch literal 2918 zcma)8>su6M6#vb#%iuC1F5XsC!7C`R0+zX$i3nbT)dV55tYLRpM)v0HtdQL^G%YJD zt>|iLXr(>&Vaa$NpFa7a|EM0*e(%gIF0xi%&b+sC-gADxbIv<|-2LqqfQ|TBMpp^C zy$Ildj23UNrrvofCZLJ`}gI4s2TC3wLL75y^8Uic6ZLYsvF zM742}sgEMvrrRd`WYJT68r ziP6hKydtKr3Z>VCcwGpZeM82Z5{kFz3EkW(p{Tm1M}oUG8PO!n>Ch8eC=>73jBd3* z#uZ;jGOWgWR6`eYXVGmA>S+lZI^tTu(4%TRX_$ICkk(SE%uptv$5XLDIGGsGqk(oq z*AkIdYtqbnVo5c^+Xt*=2{jKfp{DeJea5jsT~9g{(@hB#hdPd^$J9VfO+*7-rlBXI z!t#JF{4KNh^kkr&bFLQ~ni|mz35%w7wr2(gG((H*w{|SA7`BMDfL)0j^Yb>^M#5Uk z)RPJ7&F(VQ@KC3kvT$K)Smd9O(M+N(q?2?ktsbL|;$cHK3;WS)?NEnIza_!jmCP7n zP53WiZa#qZ!aoU3{{nklO{h^Vt|iQX4SJ`w!1$}WYKhvC8=Y+j-gJF$@pBs7x+@aS3-P^2BwMSg_R^z zoGJK5Y|Zf8X5azO?L~3(MFrpDJCdW|k_i7YzL&7@zI{6hw`cSiGfgNoC>R&8UBOia zKZwzfLi{AeHH<2_F5IXu9Q?z|M?zg;1%Z}RZZ_u`!!F+P2VKlXm@)NOU^mlIHIqz@ z`PF#|?o^cM3UX94_o?Qfgn899GmkK-wGlmSvK6q49ArIM=M5&GoxJ5at-NxK4@Go? z8neSJOj8SK!}i$<#|IvD>QZ=6!b1_!l$a`ooGjQ13Z0zky%k_uGY@2RcBG|+p>=A8 zj_eL~b+?3C+axT1NY8T4vM-bq2fJ>ks&5maD13!QcV5{}Q>3x~S?$x*Y%1)f4l+dE zb5vN=i#3`qv+`qVg;6q%OjS>ipJ_R8|*gJ zFjw+;bo!dbqv(BhvMreANiGTLjXbEPL)r+PbtkOP^rUlqu(L9x#(7tRNKi{mR~e_saXSS{%%q+B3~yMpWNs$3VUc}k;F}-d&j3&aK75=@Xyois zxHtmjbw1Ywif(Y|LKCHzUtlhZ`4Dg9NU@Jm;W5r6Y|5FCF2KW6!1YPE`_^UQnLu&J z`Yhxzl=D-P#jIX_y}gqt?VE(+oS8j=vd-Ep=JbVbW3bLwp2ggt+wU%Fyp0~e+s)73 zN%;E2ikMEIBIxnEZ+R}E!teHQTk&)5Y0P5YFPNXjf-DyLJvXt)g|P>g{4Vs4-#gFS z7LTJuIQPg6E1t{ja7ze@h&Y4_%7u*7&(UJ8FF_@LTbfXXEm(maSc(1oBMD$ahdFqwNlSGTQH=UB*rsyJYPC6DwW!NP{F} zj}T9}sogQf(LUbpp@p&k=4dH7TIO)Hd;*o7Q{di2m4r~;O{|dUej5iXCHxLw&|N!; zRecj!?RRIfCX2O#%(Y@tojZbE?jxS@5k08qE@g`!mnS2Df z-b_BW60vRQAx*qxP literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/config/HiddenConfig.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/config/HiddenConfig.class new file mode 100644 index 0000000000000000000000000000000000000000..4914ff3e8107d306534871f38204d51968c8ea48 GIT binary patch literal 3192 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 Z&J;rTPi&EKTt?sz99x2JKk+O=@Nbiw#Qy*Q literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/config/ToggledConfig.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/config/ToggledConfig.class new file mode 100644 index 0000000000000000000000000000000000000000..d933dee284b690f0ae8286b7a88eb8f86d8e8673 GIT binary patch literal 2909 zcma);`%@EF6vw|y5*C(KBKV?e1s@dB0D9Dmjy!dPcIo#~7}bov){Z0+~%CP*Y$XJ_ucd+#~tp7Xiq+}%I_{q;8h9k?cA zpbUcw8WEInL_q_ND)1sGn&(7wOf(_U49R$2#;^iaELUJeG%u84RKanaD94L-dWf-TTQGggi;B4VTq`EeOh1&?7uh9Tpmf(^phdQ1wfSOwxRE091^G^b=(LNO%- zY|*4eLlaXnG7?Jn7^Y$Gli;au7?$AeNknuBl>>&U2h;H}-5S!yVw|ZONQAZ6ux1(J zJvZsKCybPY)`7Slu#Bh{Pgu5*3Z(R8GCi3N81ZB*5KfrmMl>*#h(=?2q{n&d;zqHA z7LnjfC1Zvyq58zYNo`6C#56M+2-%ilMk(ZpCn(dfgn2D#1SpV>>48C~6K2N^;q7wQ znvn<`B^@fv0OyRS9l}w%l+vcCU7E2BySN7<&PtbanlloVP$F%Gb>TU^DFD|ZT$9lL z5Z-ak)S`M^H|>B6d(fF+=yf6YTxwfeTH9LMa?AOXX$g-1)5ZRi6&->W82A-`9o0gl~`Kjj|=tzf80so&lMF{ z@wJR^RD6r?WX!1eUhMn>ew47SIO9c0r{X8U=V#2S_(gaTD6Y6w{eq0m6_qG*IjY-7HG4wB%KC=IBFt5N+DO@~ zY+ee-nc$AR#guY$(x2B_P+#%Mh+$Dp?x^%2wxmplGhpga>65iikUgoQpYG z^fuT~98)f65T=i7O)~%cAu&Cim8uua8{}tN0eq*)1rn0!12o#Cj}H zbM7jW*W2D=0G4oMQTB23awFAeio~ETak4`*Nn%yp&DpgwKPA&EE2c0TR*D{6!LXNC3!+i1@&p#^qNjr zSVu?3PU>ODI6de!_=(eIf?Ax8`ZD6GrvX#Xi1bG*e-;|~7Xf%6@k(l9+swBeDB%c@ z8>>p@;JLwJ30l}H?12?1MHK=Zsje8Fq$zORmNy}V;G-09;WoUZjam5SP&%+Z3;8Pi z?8>qzA7QVI+(yOdZKye!Wph|Q*px-(Xz&g?o2&d;tmyRKL{%2mHC|6!7Are_HNHDo zSL4fK)m6^2Uwsp6uAxi}*IvK(2lZ>NqfBhK?uO%G2DAKQ@i;Mb!%x4~(Dxctb9Nn{ zT0G7VLLK&C6MC^3A^x*WVk?r^h7=)X7}qROohGF7L?mKA1evl;)awxcSNsjyft`$6 zrRFX?#eLhkz8jrnwj2Am*i) zPH&Buc&`vMdl#?2NsPB<@dWv9yMFI4cJ+mr&oZPu=6$H7cWuPcLCiY{c_%UNCX_A= z6NNzx7C}s5KW5O)PkbM>d-#Fx#U&hc5O*-bVQLAmURpXe5B4x6o*~$a3vga8hVviP g$v7mVzx{7Kh_eKT>0$|<#mDRw;tliMKiXgOA0xBy#{d8T literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/config/ValueConfig.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/config/ValueConfig.class new file mode 100644 index 0000000000000000000000000000000000000000..84241be0a16bace2fe8873b6f433905aaf5cc892 GIT binary patch literal 5337 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 literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/config/WaypointsConfig.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/config/WaypointsConfig.class new file mode 100644 index 0000000000000000000000000000000000000000..de3846ee193d95207d5499cc52c1b789e84cc1ca GIT binary patch literal 3722 zcmbVOi+@w)8GcTCl9Q$fC_%s|O1UU4(#8f*Nfl=skYF2~#nyszJ0z#+p-E1boY10f z4ySYMuA7^>n>r@DxC_pu#UhiRxZ^TQe*@#6}7M8l&RKI%ui zoV*stMB-zu_&7cxf&s;T{w2aUq|T;pc>VLdfTZd_m@(6z(ap;b|Fu zQO^C6kS`0N=C5e@ssitgR@QQMDroNL99E$A+euTwvH>e=#*3MQW`3V>FwL33fSoYX z!$#hcab;3<#;t;atpgb|l($kw#?CudAyhDPx#C1IWMy*cP{PiRS*g&7aU^G3S*OtN zj(e#pZ5v4ioeyw#X!TgtdXH*$`pS`_`8oz zB(01BeX^n~YB&amRo#_gESoj+{b{36Flqem#f;C`$zs|JP1^Z%a?XW8cXng_v100& zC4pL6Hr292yE*2(H*XqAGq2#%+Dcz>Y|PA?$vfQ@Hx`UHUEptJovXX15@yb^>?}o= z3^_((V$jIBu_sntG%|_LXy_yO2qoH3Fb?w!?_}O`8mk;}S9)E*J*&V!WEb-ZQ%qHG zN!6oDlDZ`!Oz$Gu%@|oDWoFE*6DlWm(4C;S8-~g#Xz%In33rDp%X2~OPK>2=?7(wO zkem2Q#B_WO$8~%i&+9mWZ|L}@aNol73RYF+=Eslls4j>f<)F&Z-`4R0jx($gMoGsl z_>P9}Du^!T&;Ocm4d2u8eVo+rqK+TnCDHdonJMX*#*BtjI$p-Cj?;KW!xi98!qT@A0h-ecGE%3CQwu?M1Pm1Q(b^HwHG(4;0=Mt_r@TP**bLW@q zsjq0IiA32D(eajq`4{-5j$aA)Yn+$iZ*=@txZer+J^mnbf7J0O;r@)j==iG${|(RS z_`6uzvq&%-m%f6o#(RvMRqYmKEEV(R-qUumBh@$*9V;D*5$T3w6LKp%>T0LbLZqo_ zDbu;baK?%7j?RT5tQT|2DmZKgY=Zk)YOZ{qpf1-%TXk1mQD-KSR-QYSBv{^#88;`( zvMVY!P_$CrVu6oBN$IHyHZ?M`Veh-XahTk$x>#dUuzW6Hv8-dJq!svbM!sNj_zrQ3 zDX5Ec)GoShzt!DU9W@MaRKYb3d|DXiSTq`yV618&9qXiiU%_8XNqafkjwW(| zwmHx=jpmbNn{XqkpI=}(ynL|TL{2Y@VJB|pNWr_RM>K8Vn^EW7*;%Ngn@jLa!#i+I z3EIzky*5k&O)!qESbjA!7U{$8;!q?`?~^dB`lAqLA5y?@dQ;h9PtKK zPdK6lRc|=r3#wW;(h^jC;fQ}0fzhBR=neX3up+3<;F6$ENDIj{Rz_Nb>X|n0aRh?o z+PvYmwi&D{VfBl+w1i*@mjzo-;qoSooVf514OnvmKC$=8ldg+1nC0WQ*$u+ISWU-P z)4d>8;4)m!zjj=StystP^@w5v_F^OMz*QLLd-fh|!a;Ok9Gh_rTksgV@C-sYiEHr^ z!kA&aXSw?{ANjB1IybNnV+qg6@FCF0=louz(9f}lXByZ=&dZYzU^h99=ih}}$@!?| zcI+Y7LR~TbMVYW;)VvpiZaQ8-oDzH{;SrwnZYFaF9>krLYo>M;L)hnfd$y9$yXfbB zc;805hT*pn&@gfVY3Lg6<^)F?Mm6krDVh5J1Hc7FN39o?DK8XG3Asn5uJ=>{qdZFQ zJk)pozXN710n=Uq%(`i;AFSo@6gDV`cb&pU1yA7tGFK^#X&|C*nZ?zk)7TVLOXw(} zQ;^ju17dS-z=Ut9t#s87y6Xp_60WU@^~@m5GfLQ6!Zspj`-uxj`MGXBfX?B~8h|2L zN=JJMpqm(?orKTL1W+H-5@lL<;T0zKEK~X#Q+N&o+_{%epxgNF8Faz1je#1*gqv2C zr<|^(^$FaI_cE<-)g|+MT{73hQ%>f;uujAKG#LNH(TkGOL>NiEC#YE}p6wnEwFmzL Df`Zau literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/config/XrayConfig.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/config/XrayConfig.class new file mode 100644 index 0000000000000000000000000000000000000000..7526f7710912928649f38f213b86cfacbc56e41f GIT binary patch literal 2980 zcma)8X;%|h7=8wlOdLkVASkZ5qXi;ZMFBT(i-l-~f@rrP8Nx_5ClkRgw%S%}E#0-% zwstSwTWwFM<(wYB)DP`H>hWlwJCm?T(2~P@@7(*Y&%4b0edmuq0X&S~WORDbrC>b{ z%jj0%#}NfC92VrLAdd_3gdk7KcuL083RH1j1Wk}0FG32!&}X0*5rw4B3q!#%^vj4U zSc#Z|GQhIq~%x~x7UC84G@ru$7JqQw%XWu*KmJ(*1Rr~O7O8TE$}@m?e1KWu6z zTkLHktwa-ASVDn8A_XM4Q^}}dNhmqmdQ3Z^`J-Aq;%~Q1BOVdlgOru9@qSifiEuhf zC-it&H*I5W_K6VhHADcj9Mwj`zlYB}_n5jyW(o7hZkp4*y}GG~57{@iqr^c3pT{kU z7o`&}b`OU1q-7-Hl$+UZX`%i$EolSAQn8ESoDF)CE~T^+lrEVd9f(_cL^p+B1Eyi+ z_p8gkX|xL>D&tiNN_!%0hIA1Uvo;QLjc{1PhWjKYrp2|09@FEN-$_iHeLz5#v^xo` zsI953tEtOg+o;xrdLt@oabALIW0J*F#cQ~r;&lwEcmr>$cuVZw#*l=v9N%PgiE8db zc<(?iRKKI*U0h&cG{`uoq7m=OxTxY1-dFJfE)zWwri?2pKEy{4h;f>-Q1LOYs`vz- zs`w0bOoi=>U3X)7RPnjEn&Q8cg?s#W4u$_;sQ40J$@p5uFuq}yRD3JI_zvGom@{rC zn{f&A#?PFZZ%!LgR;Ex!`y3!Y;71id;b*b?Ma4A%^>v(A@vC5{x=)g)bf1Lk{OnrN z$n~mI4r$Zr{Nj7v%SE2HjHo}rQq`=4$zG_OP|n%r6(dEC=+;5a>XR_Ha_v+W7Q8-a zq%6)6j-Vs#9h;w>Y&lh3oRgZ+y0QMSVNzmdh)rziL4CmCEy?;o)@%<854>awi-{&- zO+F{{PMyX1Vam1!l?H7=7jE?BuHid zv#BSE*<&!yal17i0Mj@kN+RZTkfV&oy-CeX>8#yp63%H}sD)|BRT&W2yF<}LO3bDt zr@3X1#ST*o@nk}-vU5%Fdx%sZ%+&gFX}8O)l@&tkv+PjCA@K*9Sy}vgQ5!x)6Vbki-BW-N2`fDBuo|*ZB%YP4Wb$+QG@3RoIv0ZyyR1{1r0=H7dacL$3-0ruoc^g zf(irMv4fs$Kr?pozku9LXd!nYb-Az`du%^XWpUg~y({3kjS3n2Zo?-da2tF`N2CUIn)U_8qL3@u-YLGTQ$|{S>%6Xs`f}{Rdz? B`!N6j literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/fml/SeppukuMod.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/fml/SeppukuMod.class new file mode 100644 index 0000000000000000000000000000000000000000..0d37c84d56486b1d4ec0bfb6b7e79b96e1ba4218 GIT binary patch literal 1125 zcmbtTZBG+H5Pr6_Tq%cORS*=B7qNhHl($MC5^PFrQc6Nezi;pM>f+sAbGzk(|4Kh- z;s<|#Kgu|FG-8a3iI?2W&T})*?7ZC9Z=b&a*haa49G;9|8BYr&N)}cutTI^b+F7f9 z+GHp;F8C#P0o2QjtkBX$#L7>@?wPuDn3RWY(1uaW&vt3o3o%hTK&0 z($54`f1wriV^eAz!-O&;?Xi#64OKnntOzSJ~^7y^ZbdUG8u0R(5>1vm;*6vs303e`|Ah ztKxf|JsSm#T6k__9gdCL7-d-b=kYU4T(9M6=R&x~!Un_o-&f(+E;7viKIMLYtv7R7QmnL$TYNGL+8jtz>A%%E+sw zo=G56m#BgF{;F=yGabg}wXe!rEw6=x|uX*^f;Q23C4DDPVSC(I1f7@f|bmJAD36t`1 zaLS~E-V}!@(y!!$(JZ5a0wO}k6dA?npv7KLc&4;~D(y9jK!XaK*r2TbRYv^g3W2U; L*rL@STtM>^u}X{` literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/fml/core/SeppukuClassTransformer.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/fml/core/SeppukuClassTransformer.class new file mode 100644 index 0000000000000000000000000000000000000000..8902e60b5b10cd62ac7033c0cb08ce7f3f9b37b8 GIT binary patch literal 5939 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 D=Q4zb literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/fml/core/SeppukuLoadingPlugin.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/fml/core/SeppukuLoadingPlugin.class new file mode 100644 index 0000000000000000000000000000000000000000..8a0ed7052cf05e9a9c829a0d6a10e68df6ae1f72 GIT binary patch literal 1827 zcmbVMZBG+H5T0#I&(;>Syjf9Ed9g*jqr50ugpewR*rKtdiQ&_7UCQF!UUM%5|CN5x z#6*99Kgu|Jca&?XiS*0u?##|JGtV=(zyJLB1puq?JPisgD)2-BH4PdpDNs^iS%DP= zRtY3GxZv(4fq0?VAdsk7O-5j($_3l=%tL1H(?bI-xvHg8qd{#h&!I8l9&?Ali>k>q zo42TG*)Df9hqc?@Cr{&M+t7|oL(?srY4yNbwP=%z)_cQiaZx5P(PHj)y|!;t;T&1E z$?S?j9Yh^36c4H=^pt7_6)mmq+8BlbV;E4gniWg96stVHK2|99yPd_`b>@2Q5H*%rcbsmm>a8K-=JGmUnP+MZ_^vSG}d=Hi6u?knn2q@xfd^IUFdHQFxw z?ZGX`<%eF?yDQYG1_m$^6pUPFK=QksXA{7>UuURv))t6e}c$@^OAdA zXO453{&d~)Y@O|JseZnnc&Zdffi;vW68`#3H#{dGG_xzt1!BnW+p1u$W};}iO^;ku zyT$zZu$e(Up&v6_+uf;EyGCTTFE(;8bV>~mYnw5ddNF)zIDD!cJ{5;gmBXjNQzWfc zX)s%sMqq28QaS*bK3P&r%j$9lQjjKaqjyjVl&|np_`?}#RDow1Scg#p8&^QNBqa{V z6~en{?`kQSJOV2N=tp38fT;ee6L>iYR!25`*e-Mm9|Q&efjw$6C_xfmN&?sL*-YY! zy5jdbo-|wuu0spofqcbH3^L&*fMLkuJ`-HP(+HlBJh+Kp8N3Av-bkhI)E%UvJn9`2?)%`M?c zwvx;ZAxFIp79(XQ!whk_@8diGS@0xgpF@QC10W7Of(5yE;4#diGl$NH$nwm53JSOu H=TmkHM}R#5?GGu3GB}~rr}v-=~TSH@(tgt zR%0#nF76!Y@di^ zTe@Weqn5z_|Ju5v+$@RrVFmL$+ho4ZT2MwyXTx9?15OaKP*>pi^Scvh&j+$_V^UV@AZ@!?a}^zCE#D$^Bd%KsWMEZXRydps zOz9YYV3kTnwc?m|#RyT8k(OCB=A~P-nR$JMc821F=|;TCS886tJY%Ud>S_RZP*F(7 zD@c5K}@jSVxV(Hj}y&B%v@d4;_4h0QG9VSW|$~p#7(lL*;4oj_E z*Kq@`hN_Ma;py0i{Th570cuKE&~XzV=~%=qW*kOqV6Kjj@rjO4v83TM9iPL{@rCmL zr7Gl5^Fp4&vvncP&s{eQfxyn@Zt~H`NoGw<dY3{ zo9=6Jtc^M}+x7UtH)=3%ejeemefWtRQRVs-g6*iCGO_2^@QFdv=!T zi#)pQ|44!7v%YB-Y)f^K$%kE3KqnLpqB``aoAA&Fo2xiAJFw~vD(uUnVKf>feCrmm zW^ZP9iZh}j!9-s}U#!!BeX***XJ1UDPb*TiMh*oIG!M#htYFa?3;&{yn4f0IOw%fw zYLooF=@!GTWBPtbi`Iy82~Jx$ZM_HW4mK|N+WX@TK@{#*7;Pg0WkkIR-pWJN4j-C z%I`r|%3BAou2wKX9aX_r<#7eNz-q$n>zsG6R1l6Ndg*vyL!w((6Ftl~QA`0N+NqtO z{!;%kI_{wJJ1j6j*N=GNE;fFP?o2ehhpyGQ@u8k*zDeL4jH`Li3O2{^E4EAx{04(7 ziOuL<#*1HLZ)m@5U>Vz$;=l@aFk7XujGo)E2e)J5`v-Rv+;J$lkE4TQA0JWuQ2Fj5 zv>C#2jDU<2j&nGSE6jclufxF+-WzZ5#yH43;Y3(zhSiKyRshCne}Q^OLU@-};a#H5 sQG$7lk=n_DzaYe)IQs`r`Z$+bxs~OAj4stU#6ap*C-?%az&^R{AK>M?#{d8T literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/management/CommandManager$1.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/management/CommandManager$1.class new file mode 100644 index 0000000000000000000000000000000000000000..07888d5311c63bbaea040785a9cf98805395a134 GIT binary patch literal 6204 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 literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/management/CommandManager.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/management/CommandManager.class new file mode 100644 index 0000000000000000000000000000000000000000..e9522212bf66326f9e45faaaadf241949520cc33 GIT binary patch literal 8278 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 literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/management/FriendManager.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/management/FriendManager.class new file mode 100644 index 0000000000000000000000000000000000000000..daea7e42993b97aa014ed4906f19de7f0862243f GIT binary patch literal 5590 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 AW&i*H literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/management/PatchManager$Environment.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/management/PatchManager$Environment.class new file mode 100644 index 0000000000000000000000000000000000000000..10ec3696d1c858452848adac186a7835ae65c2d9 GIT binary patch literal 1289 zcmb_bQBTuQ6#nj7)~zcr1}dAVps3rx)geA@Sw?Usm??%K3GwMN>nOH&OV{pC;E&Of zh|y?x_D31dEsK=si!TRMu)Apx`EfWp4zf=GtsFi$<`Uj$myIl@DODUYYesV=F7l5 z9vQfSn+7J4HZX%U!_>tw$;uce+D=!HqPct_QuX%1k=6D|_1eFSV0avDet2Ojk=(z> zfw?>1Ta=tHnih@C?3i zY}as0O2=Y|Swe#3E{%jdqeA3U`U-VFqba9IoFExGx*9sEiEk8AhBT-9>JX{c37BL% hFHR>pzPWGAsLuA^O!d;5Nca# zX~l)^v_-9LZ7W^01*$=$Qo7OBw%UDf)wXt_o3$&7(*MrPBNGfhXuo{9XXc-K?>Xl` z=iYnXef;G|j{=w}6ctJAQSe?B1=v%94S1i*=KTuxswl#q!MF=|E4W8RiR|_P6@#U` zSH%!1Kd54;lpj(tOv(?d7%t^~Dn?5A5f!7Q{HTgDDL+Rn5nmXLFXBtG z`LcqqC^)Vnfv?KuYbE$P9#`-U70a-v7~hogTPj-cL@}N$#fbi zq;)UZl`u2>ba7&n-mS;8o@vD;Qp3;fW~Z%tS=SJ#J?rzlM9PS}W~ZKVT+htJGe$a{ z-JFfz#(QH13aU@!#DE5f?a7(LB>O zy;^~WN&oL;6{`ed4NeFB8=5d}qcxk_V7M#v4Hl8ogp<^*Rk~}+_YjPET_%Z}`9El; z>BB8Y?`YiS8Lq8czKb#ng_EQmgM8KmCZA*K0g2_Xq@{1)E-);JkEPq40rQgb4$~F5 zDEMMJ@g~zU2n#wlGSap5 z4VeT?m*@hUBB|GqLY67ow+qy{uHGZb*3gMA4ex?25Pube{0xq_a3LjKePa+T1;5hp zYy5_5Chy2b+cUkM<%Zp1xQ6RnC{UGm*lNeMI>O%hm9!e(R>x(E%e^M2e(P5#k8F>dS%$n^<*D&mQ z$Ju<|7IIXx&As1fa@8;xoBL9|p2^vmKYc?M z&CbxPX?axzBNCRL($Aarx(yl6)sx;L$30_P{!Fj8oMbLY`HAy;bJ1Jvx}94eQ}cSW z#OSH#R!`bOXY#KNUr`H>QR}SW<_}X{(lfh_U|6%g(Ft|tH#2a~GE=$8=8uyn8Gxb<(0tPyxnv8)?k^2?FCy) z=urM3)tgSrXmBjYU1V74aMRS_$@4<<&x^3Q;KA4))Pd#Grc9eYWqMG@85w!FJgeci z_??E|%jOR_q2P}i{)9hk_zV8ZGDE|2^2^`wJgc$3V!*FC1S$u1aiFS5!{6}_4gbXR z3jU?x-}sNf=)MVq>Y_etT0CY1#;*%aUSHniWbKY}BdpKL(~{hB4JYw}h8J;ymD3dd z$61YNIE9xqyez#qtqI`S+{x(|FlQ<%O$cN)Y=)(Y0@)PegeGEQkS2=cnfPj3<~gci zR_cAeEZwllNV0gZ9hjZ-EfZMm`g8h44mW96_Z(6aQ52BIGO({-P=*!i9UUwuqs3rg zR87V8XW?O4=a)FfHr5qE?aOXOsm&}^`Kkmp9#eWmu9E9t5mpcEs7wRj_~ph%i;S?C zUCAFZLDA@EkdbNJCNLptXU?8imXXEg84gC}?C8f0D`lli&$KdEWR>cR{uYNMkVG?6 zm&wQv<KtXUyo`fr=~&PB*)g;)wUTZi3_qL5!uP*iyc zqVfm|)*eFP!-!Q@^$g5h3L;iVLth07?j`QD86uEeZ@Fa8VQ(O5oxsFpNNH z6c|omL=+fFU{n+sP2e?App3wnC@_}5B~f4;flH&ncmm~7;4%W2M}aE{Oo#$k61XY~ zOe8QV3RDoNi~>~zCP#s40#l+uoWRs5Fpa?UC@_P-%qTF6!0ae6hrrcQ;2HvRqd*OT zc~M|Kf!Zi=ErA6g(2KeQey*h1-j2)Jjzo+XQ$u+PH3DOJr8E|^aS0ak@@Wk&WoC`X zc9i1|UOwH!{txo<=_n@PN%njiSMea5$UT3O7>)`t0hMAFszehei`A$WU5JYwOcl3d znz$R&#RHfj9^-}D6PP8Q!ff#z<`f9j6b!;VY@sEif-HrL4Bwcqem3*mk%w@Q%c2&8 z_y_Dhg8H?k4To@Df?3>n7m6vGR#-I) z*zUwl9DM_J;YQpE-KS$F9Zm3#t{Yn!qS;u2ZRp|rDg&||ucOXg#BavyeeJtL+TK9D zWhgp@Q3~F83YvmjUc~y7D5zJkBgU?8!kgK0U%)fuTXMNZy566%rW|E0lCoK3YUSJ* zyRAQn8}7##zTbEp!=>oOP4}WiKFy6)Nuu<<7*xG~-|0hQKj#kUsHD+gE{($`=Fw(e zSf;p(*}OS)u!zxK#t665%~feK1XC=ia$<&beo9fBpXP6TmJWXOYEf7He3~(6W)iJ(M!YpsaQk zwY#r&n`vyNvCS}Y#XmE!DnqL4%K8O^_0(;<@{o>7(qJklzXm3-aA&;BFl`4 z9tUkUgwzGpCUtMoxeiAuAC!!$JAQTcq|^86qUx&7r$W|1_Vy+J#BGctpN3=O0d{OW z#G^EJZS29ekyFdQTE^6J0Gna&zZ@bv6q(cH?S}K}>{8Sv!$Mm~r$z5m_xK0t)SIsI z_9#q{CDce&ng%k)!m@f+_!LouJ5}FQad&@(t{(E}Nv)(#Z@8w72~N z+`<$^3`KMKh``n5xypAWt}$|rj+YsgbTl6aDsXOFm3ML4ewN<nwKfZ5EM7B(1E1GE9 zzi5bx0TClXA^fudK4;(~CS^6iI)QFP0CNT~r}e7Qn5W)ujtV`-7ZRSJR}4p`9Pv11 zJYFzr4g)n-g-lHiyYq!?A%*RT5X%U$OlOO+Lee*d?8FLLiWd?YPhZF$3EBUP5cPt} Jk!9Wb${%9F6>9(h literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/management/TickRateManager.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/management/TickRateManager.class new file mode 100644 index 0000000000000000000000000000000000000000..932c50b26df35542b7874d3d7b26ae4c5f2a1d5f GIT binary patch literal 2303 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 literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/combat/CriticalsModule.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/combat/CriticalsModule.class new file mode 100644 index 0000000000000000000000000000000000000000..2981efc2c90437bcb0e82c12050cb80cf01ca529 GIT binary patch literal 3915 zcmbtX=~ok16#oq%lf3uT+Nerm;aG1I8<=)?2-@R}C`1ks+09N990NZ42 z51=l99RchNB924|6{wfd5I|!9yF%EFWB^S8> zeSIg%RIz$0gt_Pq;V_<-@r;aTC6pLe8GJhh|s~*Im_Rww>w9sG6;--C8=s z)CQaDmZ_zi#i~+5>3ZGN`9=xF(S^-~Q|;kQjO!+=&ls)DY0_HLgdC1rDIw+PVx8SA z;hnlGVciH?b;C}pWLPH6)RbkkYFw>$bgmPSoA9>DfbkuSCm7diG_FY~i!O{G(z-P@ zt(hHak~_NDK};c+nQe_)s*7<6>!Ty+6JD}zW^&bJyvK67)LOAh4#`#u7mJLPgh-rN zRD--sIa)hcQ)ykuB?dP{WbCZIm3h2_;C5Q;9Tcqgjoah0T9fO%m*mHJrbt*jW@{x( zNOCeFq1j%*sjy@`Ct>>T3@I^Kv+nAYj4IQ#xF*s{x!4%zOfyuM>+S8TZ5b?Wsa_s5 zpNqArotoK}W{#TOAvra!yPTQK5ur|687IZI>LTl9dHGr*aw8!)v@Ky$e!9qW@iW=7 zs)}=F*xZe9D`GpW-ExeG7D;7mAkx!GN+O*)=al6L#h+?}kz7fALw&7`=M@~q3kp=c zC}HtE6*gf|fsq4JLdHu9UdAi5wIgHLlvh7h0{2w~i?Kw(YgjGgbp>zWEg8oYyn}ZY zyodKCEYB^IyGgx*5AczUj}?4^Pbpst`fyyq34A8wa|K`EO9dzKm5fsgzQ#8)PAfQr zvkJb&IR)S0yo7nVTD{2hs(xj~^=^vR7R_Y}zQ+#=e#BA*KjDImixSr4N{(W0BULYR z${Q`0qHdWI0=Gz|&ZJ_fPHV2qTm_f#vx0u{xGWwj24q}Oum)F2Vd1>o`RGenP*_x) z;%w9Kn}mc}xnAWTR!Y-dLY4c7O}#eNMrin=w7Ma&rK(B7%2AGMj#M-rlzk z+`e@;J9T5RKy?gV;^Ukt7CTgyrr*Qhg(S)Rsa z5muw`tSgxU?aZ~A8 z<~GO5m~Avi_6s{TgC&_at!PS(pxMnbsN05dkEppIH(iRlSnn3yZ1X2ptgw$mvO9fd z|Ed%%=wSg~Dk$A0(Hg6Vx<6h2$i;DVYf6*5OA2c=GHI^+kyrN$&T8-4MBardhyHxp z>R5*N8{G?|c`zQjFIkyiwmBIS874&PQJ!UWG`tUa!#k9+Xf$OH!HPWiY&IzXq^L`+ zXMDSV)e!|SWU9Cv4!ijcatpWeZgYO!kZ#*@_fZYh_+*R!qHxL4nwpyZqUSBk1-%PP zB+Ska&!8#U6EAR=+*^ynGWsZ~pw9#v2I6W%R58&imeO+>t$Gk53aE{RrIKGz)KVNS zPKHau)+Wfg$-dSW8^w zgw#wCsJ%^y@!U3o6&o~v>k0~dT;^kANI#uIoewxSA<>fRfX83s~ zpYG!`xZ2ONxWSyj)(}e7u5J`cbU% zb31nkt<_Sjkz%c%R&b}MVUEq(-SDh{`T%!H(d|BX6<)z|ozPsb@%et*07>`)?h%R? z`uQS$hlqHw#+Ueb17GT6gM0mCa@5a#Y>H<68gG>Gn}pXUcjQt5aRu~4u~-V|w}NBR zWwYqF#m{k02-T#IQ#>G?F4H*e=L~24w4De20AOo?FXwGO-p*G@aiwVUPN}_1<9GY% z8h(%Tx=LWWT1a<_)YnMyULRk}*ZEQG@bmS2gQtP)Kc0q@?23$hpP%2)H){L=Ki$GR z1&*6!$OnCVGk-{Gw*>fB{;;2K)^z=+176Wth$#hjT135DzC(eS>i`98D#9jcm9ny*-mP;*r6$(QbW!JQGvN z^NskHSaRdKfj%P(X3f>(P!zDut!6SC1~}Wzbht%c>|qX#HP(lEQ6|tA%VfJ#jqy}; z3llfzTP$4wq)mjWW>wP6h5@k|O&k5$FlffI+w(lEH-|1p*8v4oM`6t=`iA5i2g@DDb{+hA8POPLsT5y*Pd zMqg|YWITP2k!T5HTQk(h#1063Pu56pH02c%VN@c@G_{0hG#*7$95s@#kf`YxIMdAP5_HFyQQ=K93vtT}Fl<*#}Kjg^7u7J^%WxyTJQ%eRGbX;#n7xszZvIa3=tGqL5eP%KPS(tRE z)@4&FA52;_`*KQ5v0g{%w&GZIE0OH-R65=l&XcRR^!AxK=tiqjIsksND>ayonyoR> z{P($4#*Z@1ej70h zlhkR4I=46uoj=8o!LSPow8m3LRtP_?(?{uJn8Jt^e>ONVDqz3nB3AwlD-3NqJtSl1 z98IE;Q4k_oi;Br7;8=BypAgZW6hZdr^f2uPq}G?59DeJ~5yP8%(dpyD-w*G$A!lPg zyyWUG)Zr$jC9zSbPe^A^n-ghO8=4*wRx`$zzYt_08v&$G(xW*ADpVD|( z=Y6~%u21Ku`G8JO^Jg^vtj^EyL5-i)`8oca#-G>u3;acm59$0ReqQG<(@%8%3csN9 zi~JJ2c5$pKEV*2u(D|#hPv@^m@pTjc>Ki)!g8onEZ}PV^{;dNBm>BpI1R5G)++}-Kz>oR6r)=aEUT6k*w zrp|BiVNH>)SSg^XT$*z0s!VxwrP1TC>0%}hW-$W@` zs+y*$>AE_NUe?tNDQ2qEb#(^4jEGgNMgir>wpb<-N7iZfH8u(W)w-IcYIHSQNY7Do zMW=b13d6wEd|fS2XKHGpuFg`6bal2mM^m-BTFkGEn#d9#E2Qgm`aAtYSM~ggrq0#X zd1{HSmZ}C#MRe7unl#m{s}|L&t7U4rrrLD1Lao%)DqXd!4o$7r)f)M@7B;6kb=9T1 znd*)X;dtpOV&m9@B@;#7AgQgL2QZydj9+Os#k6#MQpc3kA`7>?u{ATW(X^43%pp|F zcSPdAbmsUhi=>}nE784u0I|(K@1TLC9;~wvelPH=EIH{RmqB zQ;SGBseqFc6OnaPUpP`;ryUa4{kIYeCoeVz$jxPM>9;mi&dYh#vyK3_vM-!b zc&*peI;O?r+uu>fBWqaG*}_!+KZt-71*##W+xt4~vY=7%YAIc%z;e#mU5Y}X9WA=n zpnJ`j1jp=+JSLWu9cwC$40vt{A7_XYP1|xEZB}43yO_}tyEBzT^Co)(D&Y)y!zkUY z2qhn_jTtzcRLr6HJJt5^bT%5?IQ`9UNB+P|V8)jX0*_ zxREZy881-!fc0|Ih-Wt;UXQ(eyX>1wHrxz z8-%WNpv2fL?EJ>+mw=^*iw1(&!vA8JAf2%ZF)cshMzVf9xg@;xTS_=0K^8X@gYm&K z+w2!HL9_wP03NcNGLmuzXd7fRut#$zfH2c*44ft!@$Oi33+7}Z+HuqqlLL>I?GkUN zON1)6!a`z}+hiXhN3lA$;~Z%njsP*a*jz><_Q_FWDFUU0kHUABoIC|Z6X%E~Kdp<8 zd0I<`0?b9nHnAlGAxI{d!{IE*`Q00 z1VSjMM~wlaHx`GR5f?MRL@{T8L)y`4#0cm#uUMy}jX=zcWt!3^4!5?-u_;_3!#PSo zu(uj{&vEPlp=hAMd~ANBXc*jde@xchxg%qtwbwaf07#77_<^@CmT5^!{tHqQpp>=# zkW|TC#>!HYE|_M1nU-3wy@f;6$eQ7{0x@tZ*`trs5rHlz1^mdU#bJ-K=z?U)_ED~b z>|ZX;5b4DNZJfpg;t*un>F?2)!NL%MIo`=IYXFzhx zoMD^i$8f=vj6@n6Ted~xgMC=Q)+Z#->q}vEY|#E*x&{hz6`f^Zk_*X}lbvap%fx`3 zP)~{_k$(-OtTT2irNb8f$ZU@xRv+PBz;;!Vv%>wC%yf}@g(LjY_XhTvij~GqWI|3KCABS#c2_|pB8%Mc5;$6-}z>QxmbV9Oy_PlYDWgRyoyJaLN+udi>a_+Wml17UlxrUi2}C~l{n>>TTS-q@kLaM@otRgxe}3+MrQ5I_9z(j>Wv zLT!>}pFnMbZkgq4`ciZ0sT|s>xO$e3;q?{;41&U#s^b`f{u9H1> z*C|5kxUQbE;PG9-%EF*3RE35$CWJ93^aM|I$e+~Z-bW`7(m-A@dLS>lbJ?y-IU9h@TamOku93g|r7fbsK2YWL9Mhsgb8&0acni0XE!3s75t zf2R#m{mvmecb96#TM%!pfm-(zI&X0q*J)hmomuOv^v&FQ+g<#`%vyh?->Tj{vo=r} zu&Os4prt)FtA&9X=rA?a=`|sJn3{L-D)edDORf898IEBmgeL5# z>%0v1Pb?pew>fI@|Zuh0v%X6L8GDPbaSA@!KnH%g! z#C|l&w_sJp6gvNoduVc1u&NBtKxkr}w<@@}Z1>@nA@3o&x+dfe_T*Vu9Cqlvc@D#L z;e=%Egc_lF^nT?v!*tP|qy^tmTV6S#(hYT{R!+dY)L>q2yNf1QqWN}6Q8}U39n$Nx z%7ETq8`%BU)=EDr{@ri&R{Bu!?S88xq#dGorCT5|h5MW#x_F2#IY1kFLRuaX)VghK zP_r=^rc3vcQRlO8><#%`^Fu!O{2_8?w(kI$psJGUN@$8WMIoh&|PZP01?jedhmUsI-EEAlkP*)Zzb4=skQgeuSLY_nP z%aBKgKSVzad4xtHm;^8{$;(4@DCDv1=9!R3>_)2zX#n57mr^%NIbfBS-E2>eH#a%s zeD@V51uLP_3pV|g-om6<#_ymjlB5Mazk{A1==m-5Fkn9Zg>vhSriuK(aELOfW#vtV z4@yTsx%+V0?zaw#qi~Uwuh9~e=U}PVQaRPpG^(fRXq!VzQ8rL3HBuWjQ3o~CT56$g zIF${woHnC%kXF!rvs*9rP^sgT|$?sD=4F`rpwiX zv`sxu+tugk3iTVh(lv?R>8hf4xz46{yVlcHu8ZkvmqFLMw$gR38)=8@Zo1y}7~KH> z`99Yd>HV%3=_c3L=tHh=(yf;JdxJudbrB8IKB|DkA=-~x5PIB5PtyUK2+i)J&(LS_ zbJ<;V0X;(pX#%954|j49h~0-V&(Y`LMiab~K99Bl_3{I7w+Dgg`TP`p5j7w5m`jJ~ zOZfR_tE#8x(dMEyRZCw+%}pI@A$2TzZlb71p=^JqN-^AQMN>kpT z=^B0OFr7s{jlQkXckrfgxlZ5J=zAFX2Kklzdy|%1ZQp;L_P$1Vy;!MNX~t{hwf}pa z5{D7VG0-6*Lv@Y5|0XqR^aE55(+A0)|BME^*($%M!0Iq8%QLzI(SJzcKl&jgmR#XS zcq;jI0_q4>_@{s<(Rm0_t7gOK_tMtAbonkSb3JM;nr*@DLv+Qnw7q@KA=0t1uC%^k zSrzh}g^GbW9WhVmIA^lx7!Arn|8$?!_eDM`5Hqi;?cs<0mf?L8sb`9dOdR~GI%7adiI03c=A@`m8>0L}6 zbNA4@A0j^mbpe>q`$7RI|NbGmapz)vVwG=WmA++hc@_R{ zsVa|7p%0{{&`nz~e#^w@O*?8UDl3AsLLNXoL^lu7hjwh=cVtD}Z}}p(RTKYIhQD`NsCvNdcKQR_H1NC;nEw%WSdAI` z6MT^m{5R5{(H4Ld=hI)%rbCtv`YUSXkmxM>8^%_EAATreqffVhy6{>u6ZqY>WA+}p zeTY7?pYC9~c^~a+ovEY!&N=(&u6=a(jzAE3?>)hLll_}pWx##?$lmX7oms#pXi@t* zRbt*3(6{Ma`i_M`jm;&G!IC@%OX#2UFAIYumUnfb{%=U6=vDp%oq%H2~ZNSXj^+o4&lhnz3IItAa=EO zUw(ie`=#H@IM`{Yo$1&9gZ`Gzbo!oq1Cp>5lo`(Qo_BfP<-F(SuYZ621Hc*l5XDIY zr=mC=#hEBxjo~a_i(?|5$Iy)naa_cu7!8+W=s|BBeMrV}1t|mlaiUz+!!>=D zHtCo26CE`kE0zUdNpd`hJm*jA{V41)g^}JuEV1YElIa1 z7`9}jBL=GFapC3pxJ{I{j9cLLDEFk^*N81@Qu++%GG$?Tvc$`-r=)NBqEe|&RV`Vr z*jCvsR&8Mw-10bARzLSupF5Kch}~q!b#8EbN;;*HN|7rvbfs$*ZM-5aF)bWrRct;h zJS(L)p;%4FP;k(#9cd~T7!nyrD634q6g)nmtb#4Ie0G6A05%0G8G4`DD#PZS;)SU! zuhhcRK3sK_EQ?X;OA1=A2ieQ6n;J)db7tPRYtCkAh8!?x!>`bPfw! za9{WdH7OF~?o5LFi3v)Qo-3{&04MH&!2v3{F%xg&9TWTUu7TSo-ov@Q?8IYa>$D$M&8St^ll20k$H5k5BXiHT2f-^6ElpfP`L;0qI9;wy&p8&sY5W=DLX zftvUl-)L>$n)nV0Liu#H&v0mEL0#sxI}_d#hEwb0>Cz_$vwgjJhBIqaeI1A;s;TzwcV!wYs{7V*(t0TAr$L}E_~q4uvaT+{5G@HsH@2jM z74(wY=3>|3H9&>RpYZE;*!g7JZQy&Vum1!0M4&;Q8u8F@ilO@%ATaE!ukXgb$6%80 zi*1nMAi2D@2xUDI_FaZ!EAvuom1@>X1ygt>b3-I|WJS#@ax=uFquaXc%`zNsuu~HW zVOZ$}#?TZQI$CdNO?HM>3PG~!dBmnKHoX?hg0R@0g2ql3_S9RbKc|jMDnnhnSJy>q zOzB^v=H6RSa+<1-p5B`b+iSvUhgwaR-%YyodIX1QD$s&UH<e+N25ZZiN#QmM=QY=p_gqJDyPp?=XYatW zyad82r&TWPL!^kz=Y7UpU3^Nn|*%nj0ZQ@RhWg zf)rMvt{8^>tA|H3=sY!QU5sDAppm!w%B?KbdSYYU5GS#hzJm2%69^L$G#;Q`KMYy{ zyNV(#j0w(2195$M7-^5r@|K zHzH`JSsk56bPlnfVE;mI=dnk4?h(v+Y@SE!pV;ycBbqditq*ZMTs-ezdL2N9*Qop5)c6?+KTUivYx4|($5 zCjWgxuKh?5e=B`%b>VQ}p{jXA_;CbB$+Kg`wF&GW5;;!G2$4?E+ypBaU%@S!J4lUI Vf3v5Zeqb^gw1MsH^H*d&7xU@S0;kbuE}!5|CJYGkxUBZL9l_-XVcJv5tV5tg&s zPMpPYHpfonG-YnucHV;}t)??mhAWAc$K0 zx`uCfk9-pFHof}lw}M!UZz{;&@Z(iKzNNaq>Bn#R@!P8VJAQoIkKa|@-wWdR@dp8X z2Y(pEAK{OKocogidw;5ie-^}_<1d0Zr9OX&zY5^5@!cRle-p&t;_tl8+)xewK8Sz7 zKPqwlNn!kR0RMvTsowY1>c0j^;0NmSZ|d{!LHq~)Gl>7fe+TeC_}>8G{!hbe0sIg@ z3gG|oV}*Goh)zLJL_C_51<@;BQWYQ9q+ES83MqcFDuI9mrJ_P~SyCZOWtsXc*JK4{ zkxB(xrO6FsL{`Fw8=%A6Z)YzT$ zX2vYCd0+vCtXMJ{iY11#Q8N@t#D?YomnGsSjOe%(A3dHNHZt6) zt!@EwN`>Zx8P9|qZHL;`z(I3q^x0-;RFe3pEXBCzbO#3+D>6<_h5bOph&N|4Mr54h zQ(Q|s{qrn2i0~DWY$`>Kw2=Z0K}(f!#6XA{52!g!wlM%AV`gN$!-{6i z6m?&BRhrvq%;k=byQ~R%REv=&*{xSYDgY|OImqNBrOX!$C$g!C$=yk%s@QXPo;4;6 z22y^OJFA&clwKDKXHwjq!K6H0u%$VhNyMmU22gae*05sfT57V^u$?enOZ~+x74F`i z-kx?%>UG&6J9SJ-NU;6&q!Vh-i2xEScY2!a(&ZM}t;p@s5l4diblWMXjE#<@n$eo` z*{9s;>9}9b`v+%ok*n78({~d{&ZTDD*qI&8tkW7~ad& zP|#>cG+|_v2)F9UAWOztXL6d)?&_FOyL!WRf-6hMBRbC6A`HyrI!`94;{hZz*{sVx zxlNOUx-`n|j1yg&M|munvCgU$yr^-B`VlgoQpU*mq?A3KrO#;+(+%+G_*NzG+vFil9@ga% zdAla>(B)BiCnHyvcPT}@TizpBTfCnWV{Q`E@pJfjT^^J73hL&COWGOT1$SiC<#BnR zChynf1M)##J|s`*@?m*Wuwh;bF{U@Bk5DJwU9fpxn52HSP+ORsT zlsUwdw2)F9ISUz5m#3sfuz&u*Ui7eMCY~Qto$GFu;FJY|!wW-RQw1PcU#x@DV_Hx@ zFF=uZI_?(k6Rax+E-npN9NC#F%Q{UJ3@Ia%pzU@qEJKmBn;fABCX+m7g0lyDXPjQp z8l`ipgL$IZ zb#d>AU{&3zZL_v_A;|i{*UftGkSd(*O7Modj@eZ0vxGDszFwNMICOWpz8R$tKMO@x zZmO&g+U2Y}Xkz`eu>UwQP=Hq@`KH3KQIn6bD!*=g7C?Rd?SjUif(3z2(PqkG!Nxfi zVQEaN3d~9OEPG0dHWzl@@Fd!UN4ctu)e23mD0Tr5u$?Ic}lfZN%wp%uWXubTB88+i)@JJ5+*7g164k z-6Du&B%Lo;@-%4*UtLFsiUh@_vRXecf!D!h3F@_TS%Szr$1Fw|l^o4vD!LQz7}cCo zHK#f3TqBuE&G=|$jMXRIiqyiOCKKtqcz2^Ds(aFDsG)0gkP?bK9cCOP zzr>VK*Vfji97Lls97U|1lS*b}C0DD9<61p$*w=VEn6IG18oE412g0c4@6n1wvFN^V!H-ZwS7yO!rW%lq5A+MC1e zXO8pNIndtC(x`-^*GZh*)fRJC$WJZNL}Z+rr=oiMJMZZ1VWKSAZ7whgRw*}4q^t*3 z;Tr8QBKGZf!yGHkxVHmB%tuOH`t?e)ID7L!sF-niP@Yv%nO}pAnHSPLZk!t!FCGht z;Q-iG$YPHd?T)-=lch*=)>l4{?ecxb(TAIkm!)(aVa|`BGbeO_2L*1Syk~U_fd&~z2?Ty>b4S7iWxy3EQoOG$)4~%$(_0$}- z6%`MSDp4<2YD)0|Z+Ipj?kDMMJKl;A$>pBwKvVLk9YTVmrCwCR@B)0P>(huWM986} zG)BRCj2N|0tSYzaXMmgcXYJSKm9wkhe9_Dl9#AoD8c}tu?VMk-!h39?^i-87ZsDH< zG5*sLzzX%?#NG<^%w)HGRiSCYeg&SBWtC;&N^hmlGmY|#(CS};|72yrT?&T1mr!vL`U_a%tSog`mK9c( zJ1Z;PmCC|Om9uh#&)H~Y_@uXTRbjc>SzhfT))ZFOaAobu%60C_jp54mmvB>MZH4-7 zP@j$bT*S>UV3R{+vkSVVKxC`4Qs=I0E3DKzD-G_-_HbEV${k;%#yofvzdKREZwS@6 znO50^W7rH6Tkv*l#V4>0-#|USiw6FwvR$gN3vVX0?&ub8!CN^JybTYL8ujkcq46&q zh^HZkozn$FJa$7?=<%3a9fSHY*&rf zyDNtSl?Uyq#vE=Rxy@I90b6runnIl-z)`(D3RL?h&cj=g!y*02k3sXEhrf&y-hJf? zZW@PkIC4-U{0pR9C~I}dr$7Th(32_8gIy<-vJCO4VT#(z7v(~@1;lHilx|(DjcA; z4^roiID#hh;4n4VjQ64qPoW*3#Zf$mPF%*F{1>YmKOn?w{P#)_wzc0+4Ttb;Jd8)^ z^*wl=wt5GAwiO=5J5f$bS-cDHrY)B8kFxjRF-?3kH9W@+90Tm8!vcfc^e(b< zib}Z~yKxUqaW4&UhAwZQA452f2q8vs8kVi-LxettCHNVtx11PT@Np{8rx6Rx6{q8C3)j51rPYfyFt>)^9>LUlet?R*kwe2v_Az^6@DB_}xYlJe!UCc5hq z+gXhA=E%6QP5|w+4kRi8Cz$*j@4}Lb5?RNau|9VKCePvZX@eNj!d~zRrXXB zr-r9sujGNN?UglLF`vc?HX~0X$YwN;x@HD-%vrJQ6@r|dLRG_Mob6$7jaN|lzOtru zpQ8+p)?2Wg{TSs+(8-f@@-$s6LrtHhwy7KeX-Iwtw zUZy@(vZ<$Do@bK!1^l9NUb=ykc2w^fTlXHqK1;{<*cx8~|BrB3Dr?qDwXEXgc_Ml6 dDcR1J=HMnVX*g1Y@5lk!&-RD>n>c=?<|pMTS-k)N literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/combat/NoCrystalModule.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/combat/NoCrystalModule.class new file mode 100644 index 0000000000000000000000000000000000000000..37a91440ce9bb0754cfb98f911163ebfe39046bb GIT binary patch literal 9902 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 literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/misc/MoreInvModule.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/misc/MoreInvModule.class new file mode 100644 index 0000000000000000000000000000000000000000..a4e0300f5b96dadd5a1640e9c571c28370a7700b GIT binary patch literal 2590 zcmbtWTUQ%Z6#fngnIs)(O{*;}ZKr@XTt~{K)=&fkwXq3Bf>2s-LvjeG%q7lDVDacb z@YOe;e7B1QE?v6x#Rq?s%Y9~sYg4S4hjY%}voGJ-x0ApA{`ofmqxd?BK?Ore=t;br z#BdUKQW(K#8XXvu%Xk`h@m`9SdvbX{g&Zan+?V@g3Lju9jdo0@@geeQ%wRT!2lz;y z9;WC6eVsu;!N&?7F(f90E&NG_ShjbGA)a@toZ);?*nF;Gt#WtKST%{0DLNIyTrylC z>4+Kk*M-M0UbMLGike|Lt}i^@`-7W+`Ch7*dWs zBfQW-TiG`%8zrM2*-m@huFeyS`wSD=SGX|hLg$;@_H~>4TaLS-&q}I%pqrDoO4K7e z<3$o9EHxNx5xvNJU($kB=^SRAk0+=p4 z4Y$G{h#*xntY`#KtGY(5CJE1UC~@(*$8)m^iYgvsUd2^>qT&{= zDOgZZ#-fT(v7}-dPZX@Ec#3BXqi0ExiqG)5f-h8jiLay|L&2(wZd4RhRdCc42o=w< zp~8fv!iGbx&QiAwx0|cUT8yeatZ;@quPNCRDlBf-snya)3AJETg7c=~d7SDbUMiIH z1pJgTJO<&2VJebuvc;3B&pmsY^*WrwSrEuxym36eQPY+7TarPoasLR}mF+#zv?o<$ zds6G0RfeJFqE^H7h3s)^pJgeT4_ciR6Csyjpt&Zsf$+EW*GB3qqdq`4!q7mTkt?mrA0U3xpfnGv>}Yt)i?$My}1mdnt6!qkC`ejr3pZykr) zM2I1|6%4upg^(4f%CZHSs^R0BQQS{MO5U<3K<$f%Q#BaJcVFEVr_OT1Nwq=mL``-{ zIOs#-J{8Ho89kJj4^Gb^nNv`w$$n;idOPPAW*Kt-0|LE;bhZ8GPJ5~5PehU7oX7pV zVOO}xDQWTSQ<<=#|8@rq;|l$skiQrh4b5w`b`tdn3Y~!KeHqsJD_T}!nOJ!xo{5(; zt(ip23n+U?{zw8XxK3-Db|6El7jc75YN(8x(1@a%I52D?9()_@+e7Lnq<3)cPjm$b zbq8&~pnYYZIKP7ndw63P8R;k%ILeSZaGBOCXd~nUWcbkGVC1kXkY@wrsT)0nO0>6AkoN4C!u>A?*u^^i!hO6lE@OI2;C@p$xwnAeYCfrKUfDaM|+0o5xQP! Ns)PQytz&Jf;~$7}@YMhS literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/misc/NoHandShakeModule.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/misc/NoHandShakeModule.class new file mode 100644 index 0000000000000000000000000000000000000000..fc286d74121cafba8b1d04b57181871c7299838b GIT binary patch literal 2524 zcmbtWTUT2}6#gcpoDfbajZjN(9uaMT%4sXMv?)l5)MAqq2}PmahGddVIhXXD2{mi^ z;?KYz;JaN*+NDdEzWSqF?#T)FLTk;#oY{N!<(qxW{Qb|be*hRqkieJ$JAumyTuI<+ z0v~h{`@(wu1nx0C3_Oaj>?V))p=Y!Y|yNfLdy zo4}m@e%eJ6_YC9=$RZWHrH*>DA16k#+A1E2xp{UmzYYkhvb;ox7a>Eg}E5njq@b7Z3T&(dmk#Dgx z49QS<<#}FO6N=$h`VdpRE^V8z2S)g|>msn8)CiMR@;yp}YB`A)?iXea6ij@E1rz5` zG_Yvm0X{ddY+?luO?-*37$*1RujSXSxQ<=&U6-!ERRq#gBJj9l-^u6Z1OK~blv4v= zoA?Ibn&4P9Q9_yF+8&GB7G72nCIl)BiG23^nSkB;ESzA?q?d6iU2j!Y;#9u0N!6`-?C0@F43|ICHOqK+lQmhlk|IAwzXg6^fd> zszVe_poo}E4<7+0GP)zLN9fQFNrU_`4V;&O+ELi2Ps4kDVU{8DKOiu4(bb~*Ww7Wv zM^!lG@xtEo_E61lja&wk?Cl~4518DqLPmRJSfoMW2;G(eLW6T(_U>g zuKmEP`+mz+XT)JROSbom%`}yuRwvl!(uW>uq}@*fsl?Wxo!AW{VrGtxb~I1OPrS?( z&GMlmbF(cy_TLH$S8#?N8TuCk-3jMuy+G7G7_BYO8Idh?eyaWa+K#2Xtpb?GkM7#EYat2iTsb#=`yCgj5; o6-R9FGDc|ENt{vo#>kpp-^V`y&m@Hrl(?y(xUc|?^T)+%Ik=(3;D@9zzwE~g30@gQjLwsqkKj_&$fZHMcwh-|&?H~rX(c`eaZ7=}V_bFs%8mc7ekhQ;!8LRo>( z`5yOT-Q)2CKit(I0{23b;CkK3WO-S-O|t3wFGJs#?2nzunJ9ya{Q z@cmsvHJD^#n13BGbU8C7EHx|WR%^J~_G01k4G{^d;gaXcVhG=(5-u1qw_H7n#rC!y z_%3(+w0u@-#kcew%iD4YbXP-ux*?*Ndpsn}MbmGGHeVI8S!WIwdipzS&tk~;v<#=D zMt3Z)rJHdmycS(L`AUJ72xQtOhN(uF)FLW%{B~(O^xaYr`ZkXu@+qZNEQS4RWb1e8 zD+;PAmhq{IH$lRxiqEj7;I;|_H5GN-VYqs{<|t^W_!3POCe{^vrD6kjReUYUrX=6s zF2j{$jU&Uwqy6OUb*DHTT!xufv>Zzv);j@prMO>E*F0+6vSURNr~YSaYvwY;>qy_M)XM-P5#L9IM@@Vo5@x%6ti zHO8P)ynW(@XF?u!p`bar^mxcHc_@9?mQskgqpu`Kx(&?+`Ar-N=16OX6TLmKX+2(9Z+Mt#jcnIZJkrraZ(e2i2738x=JlesgHxz7<)5bz?!KTDbs zLhvDFo}t`}IG^Atk?jaRAlvf^(rOnO;Xn!R6T%BgJhn(iK#mk+bPiA;Nk76ZIyK^^ QD8*8Bn1X+S&#S}#0&7KZWdHyG literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/misc/PortalGuiModule.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/misc/PortalGuiModule.class new file mode 100644 index 0000000000000000000000000000000000000000..5f5d1607869d7c355ef2f6dbc4401f50f68eef70 GIT binary patch literal 1796 zcmbtV+j7$|5IsslodlOlD1~wjP#`T(alZw6p`_56v}6dB0iHynrlPj&v1OP(@-w`{ za2sae1NbP0wH;_Fr4;aktX=InTAh{GU%r0)4B$Mb^EhasoX4R&4(D;CfI%EBVhfHH zaU7KbhA>>j37jm@aH@b2a0{m`oMGs>rnEAn4B5)i97Ar>YfFZ$b*1HO^M~>vK3R}EE>%zGe zshPxCrHwrOKsbv^ckcUbVQ8b9mEW)lUvc?NYQud;EXjb^Vk3ohIU31AH9p9uB$Q#| zzu6din?|%2XN2E9_Q2gp8|BJ56)F;ALTk?mqdZMojMj}5E)R{GpXa{kO2VK}?N$iWnFZ^0 zKubgIM$1+p<_&K-D()FG-yIA#oqdIQn2x+YgsR??_8f+jYsb|VHJA?hnc!2(LAj%B= R*|y-^_yGOVuHowVz&Eb>6Po}4 literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/misc/ReconnectModule.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/misc/ReconnectModule.class new file mode 100644 index 0000000000000000000000000000000000000000..f223feb41049eaef0153bf0be26f1032a7da0ce4 GIT binary patch literal 3957 zcmbtX>30)V6#u<8?WA!~hzNpMqZUXDWsp?~)?#U)nl3iAP+X_UYdbWViIYhc_kG{@ zy05r-~Ij%c_gf(UMHKr3$3aC;bcgmGu6Gx0F7QJ5M=LS5_H5$gCG z#4JNvQD!2L7;V59#?{W!a5RFom}o#2xd!fRMdhenUhVFRzzygN>gcJ9ic0Qe1b5>e z4aXwbhl0=VXdmY2>Uz+8CHMvd2eKe54@lOuw0)kTiU6 zyvjw&S~)3g&#+_|1b|y(iiFBuHj+U9mO*>N7j<_Sv@MnV#j?^jllflV;8+ zc-H8sk#}-3>lnVz%z#Q}45e~bx<&~@J|k%rJZbwu*W98#Xr(6v5=*<{00)Jw7Y zo~stXvfryPGk_VZkZ0x{C|We=thLxb$L%YUSkm(g6sh2+E-9zzre&9<5_aW+WZR;O zkcBpf7FfQpE}26E@~C6k%mts0@!VJRoC=;cb3hV9b?bPt7jwkS>j%)CgK+~BNxuV^pV<&bAY^u(1N|Do+ z{XuW2CDidWo?(HPP4CJ&rl&4{R>y8!t>HNx&*Mc6FY9;(uj+UWuM2EHhmz9q2Hw>0 zmX5bErQ;oJ)nTaRU2M~F6}D-3PsjU8#&+z`@c};6@ew}O@QIF3@tMGu`BF<|n=58L zOC=o(gL&5xG)_8MS@F4!D;;0s8-e(u_ly-S#m^in^XGqx;Fbp2cGoK@s2fdrK!tG$L6(k!;sHZ#CA+X~#)iY0pii_Fy z9*Lhipl&%8btahZbJ0NcZp}~IzERd~ysNoFl%Jhc^3k(avTx)l$7!PCuK$HmTJEkM zxYLd&j{7m`aWaglKnAlbI9wZVK8?$QOUv|X^fr}`2@T(JS}mninPCAxhkpM+Cx^%X zP=Otlrp-?97|oeqYCQP^JD^}7SCD)_-c^*GVi~%`qf1(=vUS?U+-!Y2wolGGnirR` z2r-*qvhP55FI#36#TH?rgc^$vw@}`HpH=AyOASZz_xGg+gV_6N>_4)){D%tbR?UL= z{$@V*8t0o+>T*4^?-v1`KC3uhaf-VZve1Gf@dXB#Xi7~lm3F1H6N}T#$*QcL($lqD z6~glJ)DJFV`#U3fin-2}1@+upGI4XW9tfU$%wS35dR&qIsi>9&a z2i{$Syu?A$TuY1|$VVHl<4K?$`^cemdy}x1aQCJetUiH@kHg?@ z%^z4hh4pIpJJ$AWp1~z2u7ss4{28AzE=`$%;CNe@HmrjwE_Y zcHBv*>{v}ZHvNgH0)Jrh6v8c`d3ppPZKK)OF}>O;v!g=x>N(k~DZ97q!Bz7l*PxHG aYS53z38UN{W?&v`U&GJfm+(USn*RV<1AvME literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/misc/ShearModule.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/misc/ShearModule.class new file mode 100644 index 0000000000000000000000000000000000000000..7e5fb5680cfb7792e824d469fd221ad5b84971d9 GIT binary patch literal 3313 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 M`f-1XPv%O00V+&OXaE2J literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/movement/ElytraFlyModule.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/movement/ElytraFlyModule.class new file mode 100644 index 0000000000000000000000000000000000000000..08c9e5ab1844959f7e162587488a310041652790 GIT binary patch literal 5756 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 literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/movement/SpeedModule.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/movement/SpeedModule.class new file mode 100644 index 0000000000000000000000000000000000000000..a13b095d50b751622277998bf18a5c404ef86041 GIT binary patch literal 6338 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 HRQ-Pe+gJ-q literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/player/GodModeModule.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/player/GodModeModule.class new file mode 100644 index 0000000000000000000000000000000000000000..d9c3d6286dff2ee50859bc451d7259757c16dfc9 GIT binary patch literal 7390 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 literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/player/ItemSpoofModule.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/player/ItemSpoofModule.class new file mode 100644 index 0000000000000000000000000000000000000000..55d9eab5d77f929eec1e27fbcefb5910c1bd002b GIT binary patch literal 5153 zcmbtYX?PT89sj+XkjXAnz!)jC7M7zS36O!(+9QAoA%QJP2uU~sy@uUMm}Yio-JJ!a zXsy(0tF89%zT{2_pk`~cnl}-h=xzZ&;VP09@X&47@F{@C?3P(BJ0z#{fuaOLZBx#d{)Ef z6sq%9CZ(VbD%4mR&-TU?ZtBiho{_dQRx)P}dq#jaI{nwJ3bk1`Z+o_zQCJxwEqJzL zq)qRLvCVOlqkV3k^z~WCOj;=)v)#^F$$)oxCEm_VA>Cyr?aT-ntB;ssT-Y98i4gAO zYm#ZhKEnaJ(N)?Fl^}6#vz@WMtqN6*P5UUf!%bNV3%luJZy|ly$_<)_9b)Rb-K6R4 zGjq1=i^yv4h@Drst2=EOIeWxRyE)I!8+j|6EsPcnJDsJ=ZmQr|1|1!Da>8 zGnF*ztjQMjZ41#(2^VXPB4bBjT%Yg2U~X)0-V!f%XZ);DTI<|}ko(rzb5nDv(&qWm zP`Go>0aLhcz+)VG%xp28OZy8f!vNo z4f1OSR94E6l608kB8GfMx1IN_jFpo-54eR~((1CMn(9M!(DI;p)KrL;&#ptsU|l!*2EU*-QC-%;VB)@;`2J%@C6ND)bS;JS;JR! zd=+2Q@pXJdp{@KZxc1u7aSJx-_$Hp$@jl$H<6HQ)jyrItju&uB$6aXE@g00u$7XEN zaay3Q0)0=Q_Y3rW{6NDGb^HiF*6|aZ(Qy_()iADO0+Slf>39(@>3A8hXgIIqRlKC( zf{xelx`vB7eukgx_yv9`ZeG&xD;+!VYZldl3JxTiK1<5g0mI-}mh~LFe4{5aEcp({ z%;zn3PEB8T`%q`Ubo#Z6X5&2E*d1<#)pPSeYsvwC{ls^M>}(swdynjyr`+pe#_Q%>$Vi(q1+bZzS5iqoCS zH6Kuryhg}f7R2f+Xe-VJI_WQ)3073*Dw_&4vdGP^u>9)O#nB)}+F+dEbim7>^T9NV zBf|8CQ^Neb<#m{uq~%x?Ufp<5ieg#0!{K{YK|Cm3yPSxwuqn*KC@l&Gg$_64CB;dhIg>{t$@Wkg(R~+5~2?N5{T+y$J)SQb-SBGdf zIb_h{RUw5X8lyx+JuAxfR3Kve9J4bi_gF#((F9AbM5M4jq@-wIF(Qen8!d2*>eiO4 zn~|IuPZn}=lggDllc|oK91YIE>Vf_3eKYz#MN4Bgl^Zjwl+vgm8XY1?A={WpBtk(b z#mDf8#Io>sR_=JGUj)S?8$cRvktZ)l}55 zb`rH`5j_=IMksa>^H1W<=5gpJ5pAxTfPO~MuVa2s^SVh~H-QDRE}Xz3S>H8*I$7U6 zfqGfrGl9jjUOz!&$FblN9$8yGiKQ>%hTiq#xRK9$$8pm*mMw|~@bYoQ&tipaCb4pV zb2U{4Z&tm6`9mUv&mul`eCqiu=CkA+R!`z)627y@z^#Upc$SP|w;Fu6)`%O_a0%J} z$J_=nx9%Joug$cklX$*@X-z#0Wb;|9J%tkzzvgvxm#FmYp7IM6{Ny0z~Jv1R$3$K`CreCXhs}su>$M4YhnExtndx2-Hk}F3-+)NhS&oS zumddifX$DyCrR-PKh4gw2mZm&vA6gk_Al1^zsdCPZDST5z1W9^y_D^69AIapHQV!y*mEjuL1$ z`q)`}7?lO6S@AYrTl_Xo@OcXT#MSWK0M`fx{olRx9Jqmc4>3Ydw=HF4p2JD5kI|Cf Hwk`c1_w*gS literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/player/NoHungerModule.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/player/NoHungerModule.class new file mode 100644 index 0000000000000000000000000000000000000000..61be8ebde467807b42a5788503097b3993ad7124 GIT binary patch literal 2758 zcmbtW-BTM?6#rcaY!VizDQKy+MhX%>WXnfEgd%AgJ~Rn22`E&pOL7yoYnmZ11? z*N+iDMgthbcn~*mFNg_D2Jj)Kg!GYw=^$osKS0B503TycNYMZuAQnIi9!iJ@5yE@` z3s@AxlE8f;;Zq3-hUOW~(41L@#z_AvgD++lI753vGkB_6-r!bF-Oy<#lrZzEzN%W9 zSl2dv&ZcHFOeM-(v9yv}HZ4c96`NNo)vc-s4`#GY>lEGH4M{H#iJrfr8ew!?PCG>fDkHjQw}GOI=*Y?BjorZ2Ueic3h!NaHgZUC2nt%E)0= z!WS~uurA{fzGM(dze+YGd?n*+JeKhdR0$h0@+ipQC`u^F*n}qI2{eX#mo{9Vav57F zOE6@ZsL1$M3>GLQldo6?41K2~#m%YJk5@1ZqnFg|@c_B)3Pn0tzmS&!{pjS@Wp>g-HifTw1h&cqp}UxNZefLuFhtYLEJ^t?{*W4*YUC-8Y@WK6cW%ry9Lv%va=ZtGf^;Cvod_wN?Y?$`;IW6Rz9aR#e2Zp|vb`Ff z-u-MYn#n!RrZY>a+)`>mJTtFjk>b~u%`K&8!+UKA7Gj0n?!Dma*&$qqL0zfu|o3# KeQ4@)UH=1-^*fsY literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/player/NoPushModule.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/player/NoPushModule.class new file mode 100644 index 0000000000000000000000000000000000000000..6799836ab86107912326b1fd73d5871bfb29baf0 GIT binary patch literal 1844 zcmbu9T~8B16o%g^g)OBB6y-xf3!;<{SwRq?h?EKmNi75j2E7{EfsSlE_($W-}V&OnIyZpc)Pc&_1xv|F` zsqBg~=;fu$FrO|6-H}JUU^$+2bywJS@wlkVf^FypD_1mxZX3KL96e)g72W)svM)jZ zW0SR6^fnJy4J&(0td)2j7`LS^PK4>5q1Ke4XjSfkr?{7i>4I2^FnV>K z5_jdI_;-V0=9-Zse!_0arhN)m8<7o@w3afs>k5)=%T_wMzqZXV``kV64w}GL}6<&&)Sz(AAJ$3PS3c1iI^8DH`EH;vRQQ??I z8$HYF7X&>AxJ6?JS?kbf2K0?bS@1go`%TfNooF!H9Qcfuuh2fxS^%9ihUp7L(Ti?$ z(JbQUk*Aw1hTFJ95sJA?UlrRj5&VKsEuk09=qnR?{HO|n;?YBNMyqO0FJhT{7x%8> xw$^e7h&x!9J8+3Ri2GM@!?oNY;ttp4KB(aa5TmLC7{UyF!?Zd|J2k!1{~KO)0>l6S literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/player/NoSwingModule.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/player/NoSwingModule.class new file mode 100644 index 0000000000000000000000000000000000000000..03310cf52d2e52493f721a11425c4684946601a3 GIT binary patch literal 1199 zcmbVLZBG+H5Pr6ASB?r;6s(F=MQK6UXo%5Zhz)^+QN*|~Xk=DC??c7Oi*_5;8Qco8=p+$!RB5i>>H8Nn>7E?nGo zaS!($%sF_#PrkZ1#hF8SjdHpOCT_c7)#+v9kUU%q54) zFg)`D$z#a3iCr|Gv*v5cxa^yM15s$QQ>l=FPD6LFwMB6kKH}8tXRVfZ=)V z92yZRE{~*6{*Y`~C*`5URaf**)o$wls;h?h9iiXOa=CEuADE*`Nx`J)W~FA=#KPdmj+vVQ*Yxj zM(76HCj*K=iPkIRZNi~1;Ko9k<-Q}cmn~;oIG@stF91jaCpae9$5 zP#z|5l{~uVn4}2HxklE;78Y|~P&~^pi9D{Q3{!)sAp^w|ew~=6Y%bYpvKjh=T`Q=O MbqSrNb^c}LH^z)n{Qv*} literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/player/RotationLock.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/player/RotationLock.class new file mode 100644 index 0000000000000000000000000000000000000000..22a8deb56c3856e59a37d33903c829479eecca52 GIT binary patch literal 2436 zcmbVOZC4vb6n-WN>?U0(Ni`O1Az~{_imcWuEwosQLD3LWLeWs)mSh48o85J@p{Dx9 zPoCpH@MqY=OOGD?=m&q4$2+?lh#0W#mzlYD?%ey#o#)=&zyAL94*)mty^Na@ZpoOI zF(c!)j5~46;{60NxGP~!#yuJH34DND0&y(FF@g_ed?aI0EI$@@pCpjSQk;fD9Lp$* zjr(G?B37k1R`DP~!&(BL;xpl312WsE&Wm6uIw;O=IdN@jZM97yPna| z8r*T3J55b@3~g68n_RnR+a}koH6hF}#2v${Yz2p-gE0!F^}vc( zwJqJMnv{T0Ln+YmM#JM4cPS5vlHGJGe8CW@PIe|~a$Dck8I(>P!+_9grfzL&CC@di zO=1XH1dlAYZ5c8`)5x^!X2uQSW@@&Zaa>-Zd)OAecwxDalklYi9UBV9P+^#O9*Pll z%08>g5~>O~YQoE=g4Zxgxi1R#5$B2uUdO0{NvIOG6d2f6ume*F0*Nys^zIo?pbn7WcF|wWW%y*F3Fa8lvu( z+6pR>P40Dwqw0A6>?4GzH)u=5`0ln8!th#J&Yyz5QYzB9Y*)`+tr^a>OV2NpzP1z= z#^vq=D+O(xTI6D(v^rOq&oPXg@?N1W;Yv{s+SR|LTlyw<8E#P~x(5mB#J8)9Y@Rqu z4$myGQxDPyr0MtWwnO55f}kCdg+4ax^kNMjHfujKF?B(ZtN%#rX9#c8S29Ci;~0{n zrO+xVItk4Y(K7s*8V1c#P-R1?V~@~IUnu}l%nmOfMP~yZmg|BH&kam_lesy>7AF#riJOBUy literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/render/BrightnessModule.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/render/BrightnessModule.class new file mode 100644 index 0000000000000000000000000000000000000000..889342a4d7a0730288af45fdeb3a187715e22534 GIT binary patch literal 4797 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 V18`&q-bf|9iQmkd-O&}C{9k7^-<$vd literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/render/NoOverlayModule.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/render/NoOverlayModule.class new file mode 100644 index 0000000000000000000000000000000000000000..6926e1942d59b6f5dd878e47968731ad3b07d772 GIT binary patch literal 2865 zcmb_eZBrXn6n<`A*d=Tsq)3Ujh>A8q%eJ(&Evd*`Xd@wM1EfNITaufwu-T2fn>hVu ze}hrNAme^FF5!WUtdO6`SQauTV@1fkjDnC4#mPr86tUWk zHLQzONvs}=zfWV>Kq-bzlq5Wn@EJo_!?In?V3^F+xoYb*txkaMs19#5n!8O^Yv^iA zGn!nTw=9EeW=U+)WVy|aI(HeOTZUEMCHal!a+@Ji)oo7td%CH+GYsL>Sc%XDt3qgB zPB(eJS>NLJnzm&SlE_(Q%_wQMF7^Q!akq7cVfqA8dc9$&b*s`eh%+}U+*b2ep~Y=O zd%EJmMDU!i31Ehq)Ct~1ioC^5_oc6l*c3g#fpuD>5cLi*r2m5-qP6O3<=qvn5u}QCCq#Bx8Q&(MEH){+%b5yGR2Q^&eb*sgl5vOc(ZjR7e zJirlNt@5%<<%{GC`HY0m6?_Fv!TZ=^xN@2{qb~C4ODHR-fD0#81#e@7RDNv~yd!qe zdC`Rm-t{(*MJp~HTQ0Zdr8zpPfOJ6WF$KiD2UByg(F;ir?`HIJS zh(w!f>X&D!+|jD1pZpto9VB}e24c+gA20|;E`#Ka;6jyQFts_>7CtyZ)Tyfu4E+b& zfqG$Uhu*2zRk0d(_k+>E-ekCYa&0;cOQK8e{9^S4-Qw@Esj*kwN(Z;2ZLTQa%$fPM zI}(kPD=aKC-2dO0^*G#J(9AM7c!k=J3Px4!%4Hv|XBR~~W{VkyTb<}1J4{b+=g$vZ zr;meS`rwG7UrY~L^^3XTNg5fRq-o(vniM1>U^Hw#p#RIX`x6qafM??g7Wo~ajc_8o znusK#q37s&0crd<$Qz07FsUNHAoc=1KSS}sbBDlQAM85>#(l8=5SZ}6^M}BJABjW= zDf%BKO27sB#c_qwnL`34oX0K(@GXWgMq0%ujd4uSj;1fJlC?z0pk?#RuC`@)^{Y_hq!%AIOQPR#iQY_QMl_A?#7AX?wk}ZguBEyglT+9 UGC`|ZD)1MxN&0LpVs|$A4=KJ1^Z)<= literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/render/StorageESPModule.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/render/StorageESPModule.class new file mode 100644 index 0000000000000000000000000000000000000000..2ef1ecabc9ce253bc37050b12f4ba8b2cfd8fb39 GIT binary patch literal 10364 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 literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/render/TracersModule.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/render/TracersModule.class new file mode 100644 index 0000000000000000000000000000000000000000..53fcb65906bcdb84dc81f2aab04a6f95ac1ae0e4 GIT binary patch literal 7842 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 adpCb;y@$^IVPvI#dkueneO3-{ulXCvFYv$s literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/render/WallHackModule.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/render/WallHackModule.class new file mode 100644 index 0000000000000000000000000000000000000000..a26a9b7c97eff5f706b3e99ea9d6c1685d4bca14 GIT binary patch literal 18399 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 literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/render/XrayModule.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/render/XrayModule.class new file mode 100644 index 0000000000000000000000000000000000000000..319ea4416ccb11e4daaf75f0b614418b602d3c6d GIT binary patch literal 6377 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 literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/world/AutoToolModule.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/world/AutoToolModule.class new file mode 100644 index 0000000000000000000000000000000000000000..72ff376e95c15370d86f0f132fda85dfc4afcd4c GIT binary patch literal 10307 zcmb_i3wRvWb^gz4cSl-}jgb+uz;A4j<;Q{zwrpWzS(fa@k}ONIje!8G)kqq9wJUa4 zHckwb08T=iq)7vfDdkykLWmPwTQ;vWv?-y4Jlck~X+j=N(zFRpleDD`u}S|kGrQ7` zBwL2~`!tU`=bn4cf1dZQUwQl4F95h)?kUBe8hEf250&EKQan5~ z1YgD1f@_;!{i=TWdT{N*gZBs5oY?wCu%Zvbhx*}15&RhcTE@#y zA|(E|2>u;EEyK_7hC=cm`ucMN{~19Oeo=;B;#d0gU;6F8_33}~=}o2j-!iW7e`WYJ z-cm-tQRXL=3Bp-BX{B<4rOo|TG-LP1`_q}6osDL# zfq}u@gVFea9o-X84qDOm>2%VHr?%@$ogkRCQr!Z%R!};S&e}OUof6DzPFcBVzn!uY znRrhwI+(MQ(f)X@FSV^DfU>2#2a{HG zZ#t9gj@A$6(w$VZ#Tn%Cle<*vj$Fn{_2&8n4b@{wT&$mu!p>R!(HJisxp-oC-NGj7 zLc9c_tPTifoqmEK(4P>@@lhp`HtiN|$sXEjflQeH4CO=^G)3q2NLv>Bx0lEOIpCC1X+%sGJpz zIU-Z3oa25u+DYxcE50WlO~zBbQJRTfMIg%bTeG#tB7wvVF_?y^e6N+;K+QAheH{aq zMc>^tw(_Hw^GW4blVD4aV3ICi_j=5Cy+h__kFqXr(@lCVqYT~g{&=tDKqXjTJ&x;Z zR1+UM&_FW2&&os_^`*^u-Z0FePGc_Im(F#?GaB*9G&4oWnJBpGUGf%GwGXCpcE7dV z&f1LH`cx`S>oSkfgV#3atayJko3nd*q66uEE18Zu0ULLztnO%EJk_0~?A{3HMVswx z&PrJsIzdG9QyU}9qRdyG83^VrCV|~95*>xPE(8M}pIVYLQ7t zxh8hvS|&nM%4M1<=ShVj=bKU~)0rbosges!xlm@9$RcOr{kYSRnWoH=*`~~qxrWR$ zDgV8E14*=ERgQ+CKThU_$1ny)j_2iwH`N_)M$$B-LLxlwL1C64{3 zbfL?Tgel$9V@RLLEV9eQb-3P?-9lrmD6Zvs|2&hko6;|7LnzSAk})N#!oCMwI46T9 zZUk4~BYRD`1^W%zXUco!eWvV}TTQu5ZdXGQtUFA6MBZ=8ouCQtGUaYLV9E#NgA{6P zZ#YvirxT7nQB$GU1h{3N6}eb%f2n2U6%)9%Y*g70ESunx^WBv@_YE-4A|qeSSc>Va zAsNqRE$tb0Y-w-aAh`TA$)re`5uBM5@2DPKF0UIsG?9_mJCQ)k$+^Q>!s{pnhSOng zVGTXM`r3sfmiH(q`s%Y5eM{FaE0J^Zx5>O#=#wny4O zn9SK42`oT6w0UfB8Zu5?d^YrK(RWTYPJ_@FgO?@Ia7*9G~o!}FG(OmLTk>wZD)xd2K z>k|pKz@?Y)$9dt(yn! zjCQBo@vwhZjJ%fJt)+Dn#b{(46Tl#S#=gxjO(4OK*2@mtTMa zH9eBMwGpYvgV2YD2ZNUgMxx>O!0}vJJG6=8a8|^O)J4T$Sg8cN=3GC;rs)dLo2=x3 z#SXuM5I6Sp*a_|}6Z=?)>>gXkN6F`@?dscX?_rC(KAyGeRGFE@OX~hT+LG=fU#4TN zVVmkZIvYvngK{9Pt$(!5xzUbO?5z9D6k+dSVVvVPR`Cpt7FEC{cc;3GIvb&4seDsU zCyL910?j=Qi~K@bY3g~d-~q=NCL&W>Vy&^(jW;&ccg8kuqw1j@^_`9F<860GB*;;G0fun*y#BRO{Ge9^I*K5_N7VQk#)(YG@aU*Ne}ALPjRUCq%*yi zx2bH>XJ;G3gB*9W;*`0J72oY`kN5hG>ABRqh@>W;701f?42cMVD0Cic#_!OaZSLv! z$4rxC#zQT^{82e+jOAI6UHux;DV{?lxqB5{;S+m|2E)y-!;@Mx(=IP|#|cfN0ExlO zdOg%~xA`q?>Rb6erLGX?i4vu{$R|~SCR!jG9TH;@xp}+8IXReH9rHI{!!wkG9Q_3< zFIv=Pp`C}5nl&AaVpe?A#)F^&d%+T)LdE_T%dg`?O+iLwPN&{^?&%|U%d{g`EH%Ea ze(@&J7Cc$>s@l}Sfo`@C!&VloJd=0Q1=#zHI<#;*G|JPf`w90v!F^dn(9Xnkm|o9P z=MTTu8S){)s&_n}JxyCX(_h`Y5P?S3kn_%CM*Bb>5to8?RB|l|dO97>Kh%%%o%}pC z@aax+=DRG&cujHqoh1W?T}S7Zwi`Dzc67FH*?Hso<}D4I^-%3yaiv(=tTH2c=kcn& zdzjApHA-nGMHQX5Ps&=khIlGrCA9?&ayP~;Tj^e&6Q%dYIO3~;h4_j#B<;j*cLN*j z*ip~4a+(a1r&V!X-p+KvKy@q@^Fc7i8vfp@IF=hn^rUrX%n^}9npq+>g(MLxx@>=szhx6kx@M+-d z;I;o+dUhELm+?2XYxo;x5a;TNA)f+zD#p9$L6&ppF&6J-9Eqcg*970X`3s=%zO1HP zf-fMjv!uMFqdZt13LHWBIEqNF$@wTHEFx6O#z_;{IbVE=zxP&Ky`JnDk1MX z9IS#|VGs7=7LL?mGxp)V2$S1fybt?n6~(U#;Zs;n{0!WB64MOa7CDJ|GG!fqAJSuJ z7f$+e2?3{PnN158(`V-HYFeNs9_fQ^d~2scIvs&)T>65*rXz@&)bvamAnhGAWC`c- z?A%=`a31H;VI<-hu4d7a3G_^8R!S}x4O$WMa z9kb3jg84&Oa1gUN&za*4Ts(wJNK{_Et7}(*aG^uE)uZB@QawpA`R@w%MhSsA{JVsI zOZj(2c};Ej5Gu+S>1|5+V!avVOKQWFp~~-860MSJWZE4Mpt;AF7O&|#dm1qpU@6J$6YvyyB*sNU=sOOab!Oo z=3(l8H#vmKC;xP~@N|sUa=+4Md291Y-Hz7glZGDb(9zylvqgc7~C~BQizRWm^RWpaMdI)vLab?#r)E>feZ_1h#!HOU!T{Om|wH3i3 zTveEIQGSZEN`=dK?aX6Xr*nr;uZh`>^wmtwz&&*5-{;dGFhPHqDf%O*#~(5lKZdRN zIMu$F8S6fp;g1;tpCrXW{!H_LV}!L-b2Bc+2Wf;LXJ3mC@u`HgmEIE}$OF!&d$Gf9L1ZA_mdbB!EsrN6S5r7 z$W}Znx8X&{(X{x!NjGyHty?be+-tdPrmKF;iQU`tjwZL$(LPS+(c&=~C6%Y}O#^=< zzb4^G?+WP8jU>~6J)d5ywYVp+#%!8erqMQa{-d}ikLxOpF^x>E#4llWRpfK2MIq=UbFR+rrl=-*=hzzegwgK33od>_vXaEcGKcw?Ag~d7Y)@ zrv-dg6!6(tz-LwgAAtMGIDM?XNuv`pYdH2 z#hB;^_)*3^Jyq}mBKBd{)yE%$KhpKLZ#-F^z5uSJLQ7<7yhc8C=8lELzcL zhI|(N7|76YBa553mBApmh1(YHFf@-VPw7d9WWIluAvNPyB*V#)^5kO8U6yWvdfO%*YWmR!k0RTZuuY8CNF20?AB#+4g5-1RFpNAj0`=u~)7MEZ#% z%5tIZEihz!Z&pR|8fo8q8dQX)tj$ectd?B_4iS@(H&}LlR5nh!q>ri=B zhD0%7XkU`9zb&I~(x)uDE0Uz4x-LFmoU?G(#(g}naT3Ee&Y;c0h>cN<*(hM#!i0@U zOj~$lV+OMf!^f;EL*Ji~rh1J75uX5tyGM-djR7k=0qK+7Z`ku5NjT$(D3Vl(rnSdQ zB}#tikkbE@!#-xJ!>fGhS7i&&e|H_lGk=^6%;~-4NzGkq!Ez`zG%q{K9QcLr4hFj_ z^**yF-(NZ$LL2L#4&BrnnSTdCplzb^9&;g*WmD8V@Ojb)FxF^lzJ;Rj0sBV zZ>)RqrvH2Q%z}kEx>k;jr`znw5-}A1BL#-Re_J1S&_cJZ`6WSDDB5T|MOG0O&46k7xU+<7r{HWHZxoCfS9v;-VkcA!Z^+B$1V_ohh~L(`SE>5{b6xJm!}-kZ^^8kzX} zeBZtIopbJg&;9SY=f2Ume){}Z0Bn(4{rI?sPxvwE#|b|ktHUSpsQ`}PaSc!Sang@Z z2k`6oj2}<>@suB@0`TK>9S-BO8b0U8=lys(fZxDx2Cx9nsQxb~iDv_N4rc=RqAI3T zaaI-6syL^L^Y~I7i|3Wv3jzEVz8t_;@Y_oFs{y=-uc^M@Q6j%vhu_160KSfIsJ=6* z`OP|f3*T0?@6=KF+X4JOUaG@)@dv8*hZ_D!!yl_ENBT3oqzwMKlK!45{z4VsSH%x% zJDxfJ3m55#0R9qxrA+;`D*i?l7gh0c0Gsei0Dp@g2Jm-yNyFdQp$9M5c6|Tky(g)t zTK}LV|52IvCsq6BI=qU1scrw^YiA#DBwoe8)^;qr>6MFY)poK_|7tr1hx;x%l`lubD|pn1rp@3$!nWcu zBYIG^whL-TqVafAu%V)6S3DjyjaWvpc83+S>~=wQ%i4nk(Cq-2*K5Vh{`ADKnY`T? zjuKL1Z#=AqOIoV!b^7cvD49|2wkFJjR?4C~cEw_G+fXY)Z?yN?rZEvr+1AKNFcF_H zqw%2Q3B#2#Bf&8v7Kxh4pw~maV6T<3&6t@~GftYZh?yKXY9^z`aT=^VV^<^SO!+{r zwln4J6{lKWU!c1$_nFZN)281lqZv(Gxlmk92g%J9k(AaI%uA$GV*_b>V5BP=50BH& zot1$k=s&vIam!%7z5{1xML4rr;7Tb_W~A%*A;UJg`{uAxg$A?Qb6lzN`ho@{k%%7e zjz^=UWjrS6xH1>*%2Rg$?YJTj6&MiA4=XSc^N?kaIqNnjOm3`jR&7@#lATXi{9Xr> z92Qi@HH#5J)kIj()EhJH-~=OGIBAU7!En@4(W5WZp|)bkHp1h5M#2er8vb1nNO6A+ zvR7?}9hDu-F$iVcC1EJ5>&#?pMeml==7xyJ4jIvL2FW`T5zglR_Tqa!_nT@?{lGAZ!KV;P8Z2;RB&TvV>IgUvS_H|X{o3RaHGX4%JsmTgW1 zcRTei%5nXwBNn&issiz}ZSh<(?6KfMGrT!Mxypw@Sy*I5D4tG+%{`VnC+FuJaU0Ze z#uLZs;;X{bO;Fn(?~Ymt!RlSnX#7~J>3BTdWXGFEqm~^WYqH0Z@$~3e)36uveEkFc zyEXiWj{m}sb-WEf5wu-Vs=yPT$1ib8pN9X|@jrNtT_K)F1e0O4FEnl?l==VF@mAa^ zSYK(3+@yjN-s2`CRePcuE~!CYSJp1;xC_6iU0T6y(YRYS4o2=^K_Xn3v_9e1)97`mxXe*E{jyLSe9tARF`G4T$2^Ltdx3P zu2GFux-`kPx?HCkt95CX8#HOrWv#U8vQE}B)5;G4neC=lI};DOUAMSg6x?!!8qI_8 zl%-MwZiJbtzCXspzB_89Qf5k%HeEJIP?tB$a$Pp6Vv{O1E8JUjxlwM?m#u0# z+f=a~574QyLzA649+GxVIt0!6;7accT{@M4UDBmXxAf?;8xLr*N0+^-d!Jk@*j#$S zXHDn?Yf5XW#LUYA-PBKTO+L=T$Sc@1M^nwN#oLc3$mu|Cqvp`SfnG+iEweSc zFfB5?`3RX#-CD_B*<6?xol3eTvsc0PN_u&xOMap{2gHTi*_@KgaU~-;2O@=j~h0_Rr7$E3X@5Zs$1O-rSrmXv1dJ8mBDvSN`?f){Z$&(iCe)xOOY zcQ5TNC7n`2meaFRRPBi$;{jRkjd^Q&f;rLhd?R^&;c6t}DXxYv#OoQTG1C|q++2zC zv|B1A=K)PuGvgmsXNhzD@ESY0NR^Dv$g2+|%`?sInvgFQ!_JICfj${Gcwje!$j<@6 zWl<)-YbxSg#v`r-snStty16l@#7)8tz6bg3Bh1X4+oh$ar$>d~25+tQ#FNL2B*SuM z&AWJ|nrZc#Bjj9WVGmfNV{FcnUpV`b%jr>wNZRuM%7StV|A#}*H}|^2DRs)wY~uVP-9(<`>HN9 z4+n0FTQskUIKvC*^mrjYME7M{b^XR+ux4pxOQ z%SQNEuEJt0LqAqv3{8lzM*$=tm>A(xFv>SB*iC$@cmCEX%%8^MXIXb`)jIvnIr{#r zzJwME#GJ_=G^sYq>S{)0ETq(~2<* zb~n&&u&mvCitHwlDrI+Bq20~2yQQpMyU1=DM@!jVUTF6g+TB{#?y(}f_u_adyDJLq z?xfxJvUcw)vinPTdnvms3+;B%Zg*L`_ZQjyW&Db3S1yr(M$07T zt(-)?BHP;2_`Lg~)p>D^XZ&GLZwl)^{uum@XvtSm&q^dS*eMLT2G_#ysyBw+ zYMcA$X!B)yI?rL(G`fnF8az?=F(bx(;j;Bev5wo*Mj)eQvVxLDo z-$^{_dU5}G+}huE0UvXlos)RPt=%?>2i;m8wWiR!5Pjo?{F=hRLJVfQXV_D)Gz3HS z0~xt2JstIIx2Nu5tvM+kZ8BJYmc{y$EY??xvAR8(F+81e^mmcno<+702QzfzD^4!^ zs>0;nG9J#b+*M@9oW|akk;@=<)wA8+xHCk)i&+@(F%tPv68RI1nWg)p~GH$ ziV^&AM(ii?HatZto?`BEn)LoGzJ||<;2Fm1FECa=E6eem1aU^*iZ99&n3C_|Y}I0J zfe5X)Gk4lc>%T_gSJTR)_%Js}HNQo}t)Zc+E<^sRB^mOwHja;a`5!N+EZz*ZIwbmt=ih#V(-J=cWdw3+SYot|2MNqb~hVhFu&i#oe!RhtYgAl|H~Mj%A8+#G zdKG@$P=>8Ipx{P7-t5O)RNRD{Rm{LaxqgcuZ}sDCe!N}Yy+hK!Q^mV*s0{DMdsN(t z!)3g@w+y%8eUj^Td3#40-j5Hc_#i$cAADHFM{uW{-R0YO>eS;Zj^Lvz<$X-byIXR6 zybSl?6DmH5PnGdT-&@`${AR$e|QMLt@(rGoz9pCtSI6np_+RPiNz+4smbfP$|m_^N;}ZbuD)U~Ak6 zCe405ZYLcx6-*h4M0y|{)DvcKpB_sa!H$Gu+Lj*MDevk9N|Hv(a0FIN$k}MyF+;b8 z8K*?;bZ^XPOd9%tKANIbC0=R8d&1e z2y8fWF#=P=jvg6k(-Rp#RCc8;$BY|0&6G*+G+37H=yJR0oK3Bcp~r(M$L#A1ChWKo zvxBZ^-|lnV+75l|yBGcw?c7O0;bs-_WE7tOj!p~+%q3`JePWMDK-4u%&Yo@ZSN zE}EivM4+nGGMr$X;TlQmeNK?Z%J`D;>n_MF)O+oH+>u3jq-n=w=d_>G3&;&%#uui;7jLBk*M zCk=nbUljaR!{6|C1y5=Chg|$8o>uTL4gbb}G(3a6CGC!h$S zi6T*~2%jcOM5!he;TO0tHz9b(x<24m+~MqK@?4jRUbDZSAi6pI*fnpiBV z8FrdjBF+_9TX-`jJcF1Eg*oMck~zG*(@Nl+T=Vnmfxwbn0ykL4W|cr?Av!mg1XjI7 zIMp7i?!g3uSIxfBS}YzNO))){GMM-!yE?jBLjr3~Q+{#`&63OlaBa=lBl+^NOD|=m zTI9Id1Qux_wdRW+VHpiKLFw%g(QQ z^tN6ROWFLLF+VF|XIC@(hL-_BK$8vR@QKWWm=@(GSALdqYswRDTi9eDkyox|Ly@>4Xd-;n~B}M5Q4kQN?bY2e-!e0V8ZU z4r?eAxvnrqHg_&T@Zv0LLaQwZtsu3)v;kwV(X^sFQbvno#K}E@vh5zd*Pz#&Uezcq z&wn$;+mOBAqEa(OA4u?-+9zoArilV7vmI_Aj_pc$j?%;?-HI@MqCDN1pR6F|k#y2k z;vML1opkzEzD`U=nHKlXLC)U##Wt!2AuI)lMx zcktAQWz@~h^|!04*-FQ^@lAp*Zfj_1-@UD&okf3s-ZtitjvFKe^|Fkl_H(Zqk_?Zk zg1zT32DgV+BR0>Wh7cL zXe}L{%nWxoban3zHHW*qI(l|DwsthJ{~ zcQBLnCGN)o`6;6yvg~5IOMXTe36HwT(6j2YFt{qa?FN%Izbcn~tT&madXx#Zw5Fwn zEyhITj0Yd%;Zkqt@dj2j`HdsQ7kXKfnDaHEP-q!bb1IizI6REyJK6Spw~hr=pAVu} zzSE8EFo{GS`5FJt9}}7$oBNog<-?@g^kmdBQY>fv`B=tNl;;$8Cxh-T)#p7bWDP6u ziis-lXu~1<51h|0co*}dS}{NS@hyzA8S?eX9r>2TQ2{$YwDa1*yGQx?O>n%iHXwWt zp{S=gP#g~U0wqO9QF;PO?St_51jZ$*4gk*`tUz~;iT>5t@ zDzFU8QH!;_O8m1t9U1-9hD*^ye3!Z0Vl6J`L;`*#M}aHwstmjx8F=L*Q2gilhH&nv z+G$h|hJlJzn2t4B>dHsdl~djBQFYVv)LjWZqb{CNS3RQ6vwXoZEDh8gx?|XK-*IGF z9)OP!))B&b?%4(`#>Old)gv&f38Qxu#^O8}5kx&0MOQLtDN-D)<*qC{f!f1(hAwX# zK{ch$+o2^~;jW)|H}&)H32&ej8Aw1Mf3GKL-BBzb!U{P%hTwx(*>e=)*iYId*qFF97~Vj3d#HOG)Q4m=MdKI;(Wa~->{43&2a

DUHLK@&r+nR~t!3z@Sa)|+;Io7u~Ha|35LF~e?Q zB;3XbxC=XRFSG6xW8g`~{?p(|fZamHmEtV)ib_PqCKzHH`h<>taTWH6>tKqT5p!c{ z4XeX+JOzWBT11Zh=*J$;Dv@&6m;~bBaHMf|Da=fy%|z+*Sg2s{qUX>u`&slnM_}3c zRwTdmkXV+3gN!>F%(ZTY%YA5UtGgdf0`1G|M%F@s=0k^}_>RC=d=II;0^nt$O}8Wv zK+=U>>q#31#*z>xY@UHw01GxFHNaArz^f@k7K5oMdI2>Gk_u8=_^}HP7mJX_H#p8A Z(bcT>U*A&6fBgI$KjnB7D}}nH^8a;*&XE8B literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/world/TimerModule.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/world/TimerModule.class new file mode 100644 index 0000000000000000000000000000000000000000..fb47f871431cf0d2417fef720068641c2dec714a GIT binary patch literal 2572 zcmbtWYg-#d6n=*!Y!bGGZjk~4Mv5&L%W5y$HU+sCG+ZQ_hE%fg&17gvS9tk!9U`a70m$zg^_Z{IRQbllAghQ^HLh){8f zui7LrGH#CB%iOmVUlB&-x>aJhaYRh3=-Fn`&6jOqK6HIMZ!TFy;m-yVik)zs39A(P zZzu>kD(Dr@5{(5q47X43hT%+B^4#Vu_bT;hTP!=0Qe3u57FB7~aa_rzUMl(wU0KyBrBvBV$#s#+*%s9&C9T|M$`48#otvMV)bK#ZH~3b^ zd-#rF-~?SoP=XK?Fze-YaI8{CRZ&gZE|xKO6>mpVrGKj`Z3M92Sbf#>Xe^*4_=-J z2Su+VnK=ytb-%P=*vzk~yF68UnS;|OkiVQ5^G7qlwFRHW|3xH&gW~= z4DW(D`%=K5tFcsNyJ;>RZ$g>H)Ci!9*1k`*EG;{nfTYyA*G+YgIz!#XjBpBaoq07rgR!8RJQ%(e zW{8USe_pHl>bKBSWz!lSG2A+}Jyl>~agrhZ1`rqqPZl2^(oepd9t;fU)TpCXl-4x6 zh+Zb{5xov*jA6RpV6i_@w-PZT*_Egf%^ESIzV0!!UBvsJBe7y6qv3u-*3h5fjB&O> z(MCm@i0tCrQy9OKuR8P+J&Op@^XNbm?xGoe#OYxy^kaZHrsi%1#~4{D98LYZIR6aI zPwS$jlZT>{;puK;%}njul+e%S9Z~6wC~{U{wFYY(6NKg9d!Lh z(L$v4LFBF)kL|BKn)raURHbs1PaS=`26phyW2AmX%S)UUzfJ{jq$dB1RNo$SQl2XR zme51RJNcsXxk}Nm(Ov|sliqcJf^&nub@(WtALDEK8pIFNQGPYjMz5|d$dR`H0M+}- A?%p1><&-4i)A)cf7lv8+!4sdt*2V;@vB}7kiPf zQ0oPeAE!YQE2uWFd%XCl+T-<=LZzF8$w0xp8pOeHO<|>ZINRZscB|D|-sUdrNsqf6 z>jbgCHHvop!3W+>$d$QH()Ge^ZxG0QvSWDxe;X`1x9UR|2bB`p=OcKzX| z7HGb?e7FP#q|<=o1w~7Fl448iD6yGmbFH;6YPq>gS#91vuxK>fS{;Udq`(k4EQWAm zG&A9N>sGcXhO>{e8BLY5_3T)xd}!j8b})1}qbRfTr*!KftcrF%?RzmbdvU4J8x z!<(NfIZ^ha^p}leXxKP`H*MH>$i`6_9>$!FM`W1CoP`Y=Z{e(s<7imeRA@bjvs7s8 zH~70dcl<7!o}%)An#K9Oe&CLVLFj7jZqidYN>$(Y;$9L>1if7R?0@zdF7X{a!q?V9 zNtB>h5;3%;M%q#rZ7GemR7YD1L)(C&kdJa);OrNanGv|){DzXVGDg`sKZfC)8bdh? z#uyc6!5qVM7OG=d&hMb9{jAe1ay*L~#|;>izJ^Vrw0Ro|`sJjSR^ zLUSXW#1pjQNdZcGQbI|4QbbvMQih>DDa6#Clv3q0r}5;Z0GC#BRGeQ?{)tYBn}gx9 z_@3U_&H^SID?Ej#xgyoCF;hI)%EI4RIsfxoXDc?qni_Sg=Y#uj6BG#LXf3m z5F-!r2|+%c0V2wY0%v#@Sy2ZSQ9rP{gNk^CAm`9Lq{vBjKpw;=$Y(P^ z620tbDnI5xfV&y^h3PDzjL99H;*97@y28g^h0&=OaM{4;V`L+<`+2S5K@G;2Vn(qkm r{R|NK0;xt7&+)h8e>Cg0e}TN9zZ)gIs5|L0PSMtxrj9r8I2Qi_pT1m` literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/world/WaypointsModule.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/module/world/WaypointsModule.class new file mode 100644 index 0000000000000000000000000000000000000000..dd8d4a1f4414ed05e076eee868d6c333da3cc63d GIT binary patch literal 5876 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 OrY3$K#SopdHT*wdBJ^?q literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/AbstractHorsePatch.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/AbstractHorsePatch.class new file mode 100644 index 0000000000000000000000000000000000000000..46532b5fd022682adb1d18c4bd7b315aea7433a4 GIT binary patch literal 3137 zcmcImYgZFT7=9Ll8`g*zs}@_Y2u2XL^-?cE3L;}{W(2-W;cOoE=Nz>e3RTLHMn6Mlxm{ic6I<=r6HscnB zg56om5xJ^e5Z=5|D03v4bxotZV0f17*9K$3isdUfpS6YVStY}Ey}y>o3uqw>psVL}%Z|i|4gnnBDD{e7I>gi5YY{M~1LfY0t3b(_)ccQ^* zT8g0ATlN$TzJXJ!C!93}Q~%bxg1F`QPS*0d{bTJsXKD~i*u8336dZ4d%o+tz4s}s5 zaIfkFmMs=6-(m=-9mfrfz;Yc*JJyD{QL$#Hd81e?3np?` z@dmT>)zQe^<+pOvXqA4nyj%55aov)K;6QU4kFOeQ2E}d8%sUm62}yBB91)D$JW!@* zEC=J!p2jQ8YHLl5zhaW28HSs{ag-DsX|@?=dp-OTHmG2z4J?Y71j__av66s=RTWPX zD8rVEodjGkeU7%Vu$4VL1#KX=s&=LBLYn-tGi}L4!aNmz0s+n@Pz4Xph1LZ`reDWI zQ1LW@ukb8^uknqFZxi?q-zV@K6ACWAjm^fWD>&PFX~%lTIJaK4eTKqH79JrLKPZ@N zjSs!NL8(%3GL@CtrM_s|`wzok2B-QgV ztmVUW*}ReP9Brj{2#lpN(#f$l;O#4h_mbuCHmjPo;<d8}P#ybKu4Kp3{}2iEekUU6+vcB2wn!*JQ* z&Ikp&ik4rI_jG7n!Ej@UqZ~>%#<(`bf@%3PhGUAbD4%J))lMmn4{?-lBKhk9cY{H; zC)m4yZhis1Bgw90_Xc7=v(tqkwi^F|eTeg=Gt93<1jI?C*i&!{V?;4~XlcmB+-Mr5vNU#K+`$#PAX4_YoyUy6DsVB_EfO_Ax=%SJ*}xX1QFNI=G4b z+}we=U-0fa21b6v!7e`v VFaX!Wb{41kuTkg`2#ih*`~!5zTJ8V< literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/ActiveRenderInfoPatch.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/ActiveRenderInfoPatch.class new file mode 100644 index 0000000000000000000000000000000000000000..08983a6f090d8747e2880d62a7147cd4b856ffa2 GIT binary patch literal 2000 zcmbtVZF5pb6n-|rT!OTTnA*m^Xev=4!mZY-EjA{NQL#YMB&K7(Etd_fa`!U#E?7VH zH+7~HGj*mvpg*e9vwJaN0ys{4nc0`K=lwb7@b^D|{srI`es=Ix5;u~#nL-9%JGhm? z8GPg5b_#cJH-&HUT@uA47E*9fHjnpa@jX_}>3#}pSaKXLB~uMN-r47&H1`29q1!TIxLfsw8_E{ZTP7##f<&n=7ZwaH@wQkhxJJhU($W|EGLi((x>AAWS_X>p zRh-}r@5%uTMC6e_xvCP{^{GO6<-)l@7}8})x;c0 zR+JW@;+?o0mxmpR<%cy6Tw^HbDno`QdOXTw%XpeMn+(?{4xIHyq(knJZ!z+AY%GmN zacVlzNRx^rdo&bni_Xwhgw*TViKdJRGY_nZ{CFGcuy3o}I%{;Sk9q%w|%V zv!pwHh!0l&z=y>{%$=CYSkWx0xQZ{4Ljieft`Msnm?P!5gv-{26)X|w6iHm6UzQ?R zCgT_B?JCJ!i|Cj$OFklHD-o`f)5YV6FB7l%5=WRfUQij+8V6eyQ;o>tL}HVnt%WM>mLAT@Uwy&aomjKB^8Hp zOTmbWI*clKS%rczF}SVZ6&2%{Q1L2Wi({Yx?RY(o!8qPfq2f&iZ>dNKAw$J3WEJF8 zG$G#rj!B`RpkPYHUYHG-#*9i2YYS{RV$N0IDY(N>f5~*r@G?VfvTckZ*6-#y!}g5n z@ZqAJ<^HIVwP+@hadU<>X85KUmnLK3lo>Fb%Gg}@&4OXOerN`Iz&)=xQ`Ak{vvki0 zb5nYs<>qDvxs&5J#W=;V+sNnpUCS~9({=jXyQ6N#3_=B@Z_9u)Yx=HZb0=ib(vHLZ ze#-~~PK%StjO!P4H#^O9;T+HEMqulq&$&Lt!znjEOa`PjJCJQSMu7|6x;)E}9Q()0 zHcbgCRC`4q!_g<$lsM$hEJM%J?#>W5oxl-%FdVM7bGif}E^DW4kKsr)WX8yHOY*|7 zbtE)$Ged?aT_~eKkWLY(pvcgCtLTKL&Bw?s*JG7ApR_w}VR)5ff!OL@WldNGO^Go054 z)l^kZVQTTi#G;`)G5Umo52NL8##qoYwFuK4Z98xrB?{ew;_euAeLTLc^E% zO2gOqM!~llzQgw#e!!0mCo1c%-X0j*D~qg_8rctIrBUz`!{y3&xy2I{d@8e5=v{3p z42`lrScX&3M?&9p3Jk}SQPC)yEaiOpj3^a#$#h!0Ybo&=I;(cE-fR&1MlM|Tsq95% zJKvCvk6J{5hmr(_oyoScQ^-lmvZjp|jm~?bxsznt3AyhWR#cN)%B_gx%QZ&EiawLR zGQf~ZrpvY~Ek4PNESaq&z42r+Cs(3f+8j$tzBJPzLW;Rk6RM{n_o)UQtID8YPS$Th z_tV!>QnJ5tbd5y!9P&kacx1G9xSz;5SfwNJdoYXzn z=9a6MV@T}4<_PNSc{A|D!GCFvEn;`1t%=6>7qLf-nq&0r_yf;$EudK( zzE&Q-osJK(IZn1V(IH#NgzI$hQM#w+(Fq^j)GSVjnlFtz6B$r4j!dC-T^f9kP$$XI zIOcH*r%C@P8GZ(55yLs!<2q^{p${D?PV133w@K_-qU9X<^MW+`P$Z8Rag}hS329s-?c$%yb!14g218QAFi|EV Mf@(ie*U{7bKR^u5?f?J) literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/BlockFluidRendererPatch.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/BlockFluidRendererPatch.class new file mode 100644 index 0000000000000000000000000000000000000000..e2332a29b0c976d8a49a2dcad68d0bc09541ed39 GIT binary patch literal 3505 zcmd5<*;gA?9R4l|%#fy*M#ZN40yMOgskL??bYZP&Ls|i;RI8m#E-)}lIx_)j>t6Tm z!6%RJdXC2zdpw|Wjt@Ti=AYp|;G^|-XC`4uQmekmfiU;xyT9%G?(diU`sYtS12~S) zBwUg4tc=kZ4q;5fcnpnrPQrwQt1&!}$rvPD6Pqtccrk`Ju1k0+hDY$Sgc~vrH{&U& zGV(IC7+O$}z$Hw{n3gdULo0L{vohu+7&1&5mJC})QNqm__6tW&3~g{_c+DtbUN~Bi z@QQ>*hNfQK(!H|`kyPgdLv+9{aE2{e-Qu~Dndi>9nm1@Ck+n6|m{1*Eti#QyH>0}@ zJz0}0jy|oLw&Urp;__m#G*?n|vuG$q)zfB_e#6%0hK-V580A)hJKVV<_R|cT9Dl=q zPr_~57_#Pd$F@vvc?|K4WpQV~P+gaktEp7hcBU0OKg%_5f#(&~H5Jd{Tp8isj9ti4 z_~{3QW2%-q&4q2nk6^@KJ8f&6rbQuQX2l-EfroHP739`D!}o{!${(qdms-?AjsphDyh^54%&8_xr4sveUZ}h)c9kK`(1i#B z^>Ih(FHKExr@y2dB+qo`wQ}4+q^+r}YA&X;>VlWfa{9}c=6q0W%q}?^AJ)Ys*;z;C z-LvXEC7!I7?&YFJily=%rTDumh3F2V>n=yvU2T|n&(B+N9L8%5d#Ww_m!hl^0qY_i z*MW^M7P){5l`x#FeVYZ*e15fN%8*zD*EzhsugCEQ-W1N>isNnEeQ;pHo4~$9;;j=H z^_y~B0{JdOdmUsTzE$vh==opki&{)=O-+bI-)Cs6ljyL{jY2t3hF!JE8Vg!5^^#0( zY`iZwFhpF`xxpbeEgXM9y?>f}KDA+MBz97rS&yqGT|0ehN-5eVH|&7^5JO#P_k$7C zdkVVi4+GygLq{qru7zT#*0gfjZ|LdH>Md%;x;vm+8aH^sA5(NS_tq&+rPtNh`o)r2 zESFDY{2|R4-3??cMw^5?aeRc{I6lTF45w<>_wPp=!=c(oR~x23)%<=b;ZugQweh~I zhZtKlEb3Hcbu==xtk!(Yb98H(;ow>#g3a_A9>N_l6kDquh}IEkCS!Tru~Z{y^zCbn z`iZV1H#90PL8i8^h*}`JyXwySzP#%>s^*os^rv<-l@W0^rZWEjNM?|9pRVPi+G+L9 zHDRmg-<}qSJLqtA&HUC}k*XhfT(>Blk`@lzCR%cb=6_q={6*g4GlGBo*guyJo==BJ#P9j22K=YwQLn5+_=yyJ(n_goC1-3y(5(+)V10ar)G0^idoFD`l zX;>soBW>MULF42ynsP^0AWd$?N<#ht&C7@_VH0h|CtK*<&B5Z4$(Cev8CzCYjq6rT z>sC@_)k1cceY=URUH6dq3UcDnuhE!zjG}+MVy&m8w{oPFj@(N;L7^nJC6de79-xG! zrC@tUV&}Tk$u*}1?8n3|ae8-R4}}~$p=_?M%Vxuwr69MuoDZI z^hxNKFn}g{k;T^@l}Q++-}_{1Jw)0FArywl;C6xzlkp2KY4RBt8C-P9OV-5*g^?pf S11?jlLeh-VzJ=rGlYapc4)+8A literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/BlockLiquidPatch.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/BlockLiquidPatch.class new file mode 100644 index 0000000000000000000000000000000000000000..5ba4807fd51f03aa9230f9726c0784c9fceed35d GIT binary patch literal 5082 zcmcgwX?GLX8GbIdnXyn7IL%-%r)92oiC0VvyH|;6MXLRT4-QVYZ z?iC;X^G|;PumiUZoG~$GqL{$v;2Q7}XoGK{WZ-N90m1|fL~65a;9LSpj2k$gz+zl5 z@SKUq+tH0LoA`=}uO_e*Uo-H$ffr1?XyRf5EAf(vOC~NGc-h1i6IV@KGa(JUlE6CU z=<5lr$2Uw|H}R^8*V^$qzNy@O%fPoyykX)yCcc}%_waoa1p{v;unm4YR^dj1j~^_; zTKrJ${m8(N4g5r4;V#E>qTK>5>CORx)?U9L1(xI-Pxh7FAsHOEhl<=u<@~%|9IyjN zy;n9{qfsXmcqHdaD{w|^*AF5mv_e@bmB-4K=hhuq{lyR;AaAh_Ic-=!1r9~MFPpJ=gFYAXosPszu|Pw4@NA1 z=#0!q<8sKdL)VG|DXqgY8ubf(%po&ZOs?(OBU0J6bTo(cd$7LFX+~8e;a2SlJU9=h zETi*e$W|BF3NEUTn1n%mO?EKhayQI6Q zf$$cKPBa_%IiV)dajfh`jw=V)8+N>l2hq*+=Qt%8*aYTXS;+@ zJFVnLo%3X5xddH4u!kdSNWsMl=~P--jUC1uv8mI=#{HmJs0eiD z^D+z@CCZUgv|Kx?An>RkW;z>;)I_?^J7IUx8S!MHr-wC-1CB#nkVeQq9hcoMX1EF=UT{x084W?<$YK zOyXDg_1w`ZmrC|G>P4|PrWw>UuIMugO6NtaWP8+p`7>ya5y z(fm$eeG?!19a$_)xe!=8d$IcC(}fI~?dw0@-PgO1WoQDXifl$X{ymR19yuCM6~bp> z(w(_T+Ag`q86LJuzAKBqRWC!p-8;7g8MWYq`kd2>0vpmfg+i-ndn48neN2%sW^574 zPDp6yWl?d){Y}bJlc%u#(`o-ma!2ndhp__fj(|cQiwmUmq{m#_0?^|zz0eE z5fcKB{<{EX<%}d=#Kj~o;c^mJa5af*U^v@mw>8J5MPTFXI<>P;-%<3@XJArb_w4f8 z$2=|}Jo=kpqIS^{SXu*Ce-x1M1s<*kV7!^B!(U}bU2#^R0zPah`t$Qep0y`f~Az34#HJw#)wxzTBvn9Ki^PZW_ z#Z0F&cTOr>U7uE4DQ}?i%$n&Vp*pA)2zyMYoUh!Q7CK%i1K#G=H_cz=t!{i;y{@Y< zgOKpljaglS1(tI_8=E1p{Xd5re+%s7ZyEKk4T99s#b<_ZJJG@w(7rLXAk{L7*7y0c z0K521@DuzwVPZ9&;3^plVmF@T8*jhZO9>iTaDy^!+(*Sj4U5;8K2jSNyVgaB0WFNi2!qmQs3BOQ)7?zJ=5~FjLFlMO*4_#MtEXcgws_f;t20g zJy0=x2kV&8gI%r6ZarNC$aKyk-gKrD@FtL+=!oV^9eL`E)MT|xfE%kS_)f+OlXV{2S#O`Tg*CuxJ#I7WEM~GdA*c~HwUE<9rcFz*Kp|DUEPhed1;(|DY=jyPV zt711-#cr;O-Mv-p_Sa$e5ElH;u-gc>Q&q5iNrCM&!S?JF*zngFY$()$P4)Bk#tB#o zK%cGFcP^Sq4w9oPoT><937Q9j` zDhg9Y<*GsmTvZ5x17vGL*u*m>CWMB8d$wAGAytDs{TJBa`1HwE@U`lZWFm!O!bQoA>ZgNVekN$S8$U(Q Ho{oP3AVppj literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/BlockModelRendererPatch.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/BlockModelRendererPatch.class new file mode 100644 index 0000000000000000000000000000000000000000..5230abcdab5be4c2212f8f055a37e1100cf03f8f GIT binary patch literal 3694 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 I*L|_|fBw16dH?_b literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/BlockPatch.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/BlockPatch.class new file mode 100644 index 0000000000000000000000000000000000000000..118e111ad86dae00cb5a9bb349ce53eac3a16c51 GIT binary patch literal 5435 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 F{{i9Az@h*E literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/BlockSlimePatch.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/BlockSlimePatch.class new file mode 100644 index 0000000000000000000000000000000000000000..1e8d8f1963f5899ab41288cd45fc9ca78c077a9a GIT binary patch literal 3259 zcmb_eYgZFT7=A{A8`f1ZUa|E8-XaLAXw@1oV8j|-gB1#hwe4gxgoVANyBn;%-~L4Z zL%-P51Gb#gkNwae)zf!o1LTl|qo?M>WM}7@_kHGhFSGyr`{!Q(F5zblg*5J`@jyo} zEDaBJbfTzXT*o7PsN*pv(zunzhz<>ta`7V#Q#y7@(6o+j%xHL`BZJv4JjKTn@l3-f zIu4-Ng-`LBP6OY85^VXdoJL-Q&~XGsIg~ZbX{a!4zwY=>e3PLgdv=N;l@H2-VYlV@ zqFD1vBAnzUm)>Noz~=504;?wLzf8sRPQ);5dBO~x3ipCAb|Nzp)oN|AW;$NgHLE=^TxoG|b`;m5RI@O=^HT^>b(e9UF7 zAgq`{X+hZWb5SyROV)Jgv^BIgf z?>grPdYa2;ylPX`PzD^OSPiYmYN#ZOb!fv3 ziO1ubfj%rS9Ba0t%5W_&CF}&lsWz}Al_XeZriMiWE<6psfdEyx`Evsyh}7{m7S_|6 z%CimRe$A_{xsWEQp0=VbnMhbo!;*pLxM<)DykNN8x~<8&*eXXfd}-h-d~M(xe5>I* z1K;BZ13zNq%}h4LnBjbDF6~<^Lx1Zn8)dDUtEy@ZKQY{FjaM#SqkA%($yzekOqcr= zb0Q8MzmjWyBb#jZ25ww+bSkTgh!r7*z1g!3+tf>{y93R^o_tZ2mlf?S_^}9m?k2tH zR3njOf1|}ZHCexf21jifH)CeyAv$=Odce817t?4dibHM_wOmUDd$hNr6wuKdq#OW(mL)F$t_NiDHJCrM~nF} zs-iY+vyP=G$zZ6aS-)TDexhi`f_r8ZJ9BepHSmNRn2i|Pc64h5!_Kl3RpqCH+Q@La zF~ms@Z>t@BB)uiITg>3&=#OLwYCe5?YUbC~yd%{dBQ^7_)I36J9&J+d*k(0L#M&k`#U?fHD%C$w<2}j_ Ona6aCU>*Y_J^uk}=!O;m literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/BlockSoulSandPatch.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/BlockSoulSandPatch.class new file mode 100644 index 0000000000000000000000000000000000000000..ec0dab1efaffef320c83d93bdbdef4cf23053b94 GIT binary patch literal 2795 zcmbtWZC4XV6n+MR8`h{8s}@@oe8GUiw!YNXpcN5nbO}@_2z{MwhA_B0o9=F)wqN@v z`XBnmo*uB}oPO+w{-~bbnGKK%p`O#^oY|e3=id9weVhI3@8ACba1%dR7|Y^87UMR~ z;-Q5J8(o;R@QIB_DA{<7Cs`D;7`0)+)tgfm$~KN_(6o&n%vku;MjlVQF^f5k_{_q* zjZ>KH#sZ$%G%Oy*5aetmiQqP-T0zB9j;6q3_G8s4mE4#UL$w!*F;)t;r}B62h4h$x2u)(>aO<@d~)&HKBDohR>9lN0(ZR7PUw0U`HRr z#WyfYt`usG;r{=%&XAQVR<4Zc`2FoHmzogrXXk2AXSmP~>GF#3jbF(1PaEXWcBiY{NLVXbB`XWM4wqcD7K3T26*ORSl+96i8U2GTs~goZcse7g=P zWH!A=o|u%n#!jb4X|0lxRlY`!?A@E|({+zhoWj*ljvd)??1=Hr$iFlZXP$hQ!#R+u z^Ltg9vf0if4Li?pxeY80y$0({vQWvvL)C)FVHq_oypn^&Dnnlz4LfN_<sVNKJGu+!BZ>+pQ?_#)8aCP!HK36qoHi@LF75A>_7T2?jn>PKF zI!{d`h7iMv!eEP-S){~0wKsHgFY5a0Ajy(SM5MT%c7n^TL{j-yjZJC{#X_mYP+P`( zF-!UooxECQxYqVs7^}od#69Acrmm^=0W!JwAf_I6($oMmg_1VX-v+#U=g>tZ6JlHod2br6}oOn9kF@-RO3p zXeNRO)IH_$vQrNO;fGEuhQ!Vtj9@rYm2q9);zp2Rpf$v44i#Ht++3o5C*yIhJmCup z*7g05dQghveY{IwNcz_aB8u}g_R;LNnFHNJ`Hp<&CNeK+u><`y+Vli{^JH-v7w9cV zA_T-mT%sqnIt&t`kKX?zOcy<$ZJ}#%6Nk#fTd)?7V6XK{r%4dN>Oix@@; z4yNgl3%G8$-c0#4xe_xB5mNJihHHfHAPqAZA*oJUAI5tmn;}`?454n&`^}il+=}r5 zZpZi#AH}#sXD?!u_WKCuk`Ar!%oa}3iB3QH1#fSlcjz~q>A(UV{GFd^H}&LEvI3H) iPf?u2-5qac>AUkT?it+2X1tFAJ#ErFfUj}oe(yg$q%Lj% literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/BlockStairsPatch.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/BlockStairsPatch.class new file mode 100644 index 0000000000000000000000000000000000000000..3e79967fe6a456e24f63ce5595eb7083905aa0e0 GIT binary patch literal 3377 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 Ix0eV11F8z>6#xJL literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/EntityPatch.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/EntityPatch.class new file mode 100644 index 0000000000000000000000000000000000000000..f82c1d6e41e3bbf238d92e8fb50295e3b5c325de GIT binary patch literal 441 zcmb7A%Sr<=6g_uZ`?9rl)RiA#TV#Sza8YqnbTx=j={_CfG&(ObnS!6?N^s!^_)+3b z?LyFv3EZ4>?#ay|AD?gU046wUq2I!wgB|QQ;Wu$WXk6$_+e<=iI9d?uv;1BW`k~I$ zO_eT{xs%I;6+g@)nJlEyj&H@fUFnh#gsBon$1=^0)ukv^QB+Tr&}or~LfU90t}?6b z^R2^ELT8>=CQ{ehO&P$tX%uSW(zflw+visVIi!s-wbw(1z3U z!NGGXo>#EqKGQb6g9<{ajuQ&PedU5suqJETB3HG>gfpU#l{k~gmJPjhLU&9#u1$u$ z3DZ@uGiwRWF^jrYc0AM7Tv4f1C##xiRZ3b#_lyZ`!1he<+)=Z5R1VV$;)ZTNDDs{V zjwq;jQNhXqd&+dmwk2$j>lxb?PG3oPT|pD$schLPYUQ!B!tkCJW18+-n&$|i4GC|e zT*%Sw^m1-kx~&(5)UEk04EbZHt-)wo0uZz2^eNbS9Y%?qu%{Fp`oGo{L`~bZv!=`N zH#f7KsfiH6&{?aZU`sQ}tUe}6J}wH9$Er+#B~F;G$@KNwcG=TCvuqRE?k0}w6|v5r50l%cyBQXo?Pk|uHm!k6v^c|`jjZi7u_ie#?{fx+ukvk!iFc~ zt2wg_AL{cFQQS5 zwA2QqJjprYyGv--HnKBNdhZP>^NBs+Yp1$czFc(-F=)z4x+$2h*Fw)(eTtDJ7t?#V zVvyC$P`fR>9*Y%eIQqEP6FA*dVQH9CqGwJWQP=fC936O7!KTIf{Bo)DM~ZbS*w#cW zNO?UODqf4@b(~l6MjUVAg4{eE$6I(?!Cg%>%+Zf!)I{Xrs#U3*kSgC<-fc+>DfX_4 zm*RL22jX}iAH?w?_6Hbga~RbVTf=C+{U})N3a>XaRGt#~iVy|zh>QuR$RZUV#qlvd zk!n9xuy^UECd*VMjRIt6twuSwGlBw*% z?diocvKcg(8TJnhwpMl@KVsHjs-t0>KgklkWw9S4=PL3jzO$vg9zybl5&WJBxzzP0h@+ zCjB2lypfY;sHq=|P;LhAzi_#8X+-kDy@+hgHL0sRB2c4gs_ zPX>EJw=~x?$H%ow*%GC4aER4pxNYO|5(-uoOt&I$W4>~xv60q6-J~0NU7O-*X1aa4 zZHSWWp1YO~b-BL53+#4Yh~+N=UJ202XBS8N5aJuq+L>rcgk}-G%s~rw@EPMjkVF(4 z(9O4aAc!7l94WY)_w5#6$)A*oaISC_kgeH|{}MQNoWZ>~KsdVipT>O%<9@EM zr_@2tKHyUIAs4-P&_y37`|IH=E;p~B=ycaQ%ia57RyNMd!T#33R+WI7yTykl}aA5xj^YT)?o8(?JHZo9Ia-!j#(SBO!A;J%`=&9Cp(+?AnR* z00wFEFeM9!T;q3CNX0`cGAbTM3;&gC#H?YCuNg(fk!x7F^z^@^!!>Dc_zOi9*@e03 zm$?~|xyg|h!+wS&zq3rOO!J1T*hu1SI`R|ln!)DIU$CVGC&|yPm$(`bel-ICjxn2g zrv3OF>7)D_Jc>uS*2-0x`vscYsCnBW&Fu>{>(o3(&4mS;^S%co{_{BDm!-!qJiLHi Hhm!vQESnr< literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/EntityPlayerPatch.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/EntityPlayerPatch.class new file mode 100644 index 0000000000000000000000000000000000000000..085213c8bfae6081efff8945e975c79af00f8f68 GIT binary patch literal 3203 zcmbtW+ji4N6y1|Jkt4(<1_Gf4!Y!DDMCH;8IM9S(z+jw|gxsLCvOKYs=vGM%P4Bm# z=s)m6S64!twffkHen3B`t7jy~G1&4-SN$;7jP{(f&pv0)=&yf%{{z5P{3Icl#Qh{5 z$T)?(goiS^P>?VsV;UdHc!ZfGZX_`#L&B_h`B=i7jC}$$FXI3fBrM8EVW|gC@Khi^ zmhenQ9|}GA1fR+@XnRnEF4js(WF>GJ$59YNNy4&(GDG*6VH?3shR*bbIflffQ{oK! z^M=g}RjbIoS*>W&N-FQ@nmMO=hM3nD6G6rB8Ls9nu6jmUvm7rleAVZ!TV1WHhUJ>7 zs|9*R&DwzxtWTTTI`^i!u8-eFRGevse#A2`j7_|r&J*FnRa9>&DP3X*j7Up55u{4w!vve z$RJyFdkklG;gs~__8P^1h+aXVk^%$ zRZr)43~{3RBGwIOVsu4Y(3$Q3839AZBSQ2an4qUPMGX)-q-aw3ndKJ=Xihu z>g#D|xZHYkyY9#^)Oyp-aSWSccp4@A$Z)eYK6J8+uE%gbofqY&nwni!X9CZ#%bDgC z(Hsx#;HJV(Og*d2gOCuN_Vk5@ZQ&wSeqVFeXV+bE)6mYGP2Jzt%&3Q)Ya|lwZ?ssW z#*j(p8XUzkZpJK$AUd^DiQ!`Gg)&j}15eY5TU7O7XBZ@x&4GkRsb1kBFpHreh57sZ=Ls<=nAIH*jri5L6H~&fVLT<;af#wc;wkOBLUIh_ z8sXnXg7yQ42_;1Oz^8z(`M8dZk1=w6gT_e1JZ%>m9@|161$X4ZFF3k^{-NJ+tON6; z!CNorZ6xYGG6j4{?#9XVt-7#D`hvYl>q6M^y0CxNgk6Xe_U&B?+l!a&#XL=(KwsNQ z%#xUMB*FrTxr7|aGKFWDr?2Q8As6aGF4Tows0%q=7jmRQ$YY_92_fXT5OP8Yc?*+1 vZj+kXR%#w6HBU6DdGbv)E5zC$HCNwI^G>Mx-Eh1|1tLnCE)-NSJl_8=H6L_% literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/EntityPlayerSPPatch.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/EntityPlayerSPPatch.class new file mode 100644 index 0000000000000000000000000000000000000000..6e5515353466cebc951fb88f2c00545dd007e0f0 GIT binary patch literal 9364 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 V{`K)wOlBdzr5-m*9bUSn{=e)s=s5rY literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/EntityRendererPatch.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/EntityRendererPatch.class new file mode 100644 index 0000000000000000000000000000000000000000..68a931327f9d63dd2efc60cac331e807951a4dc9 GIT binary patch literal 5682 zcmcIo`Fj)B6+MG(W;`fh3rH|&ATdkibs8XqU`jB?27_z}HjAMN8B1epurv~*kppR) zt)Y9HG~KeV#A%i`g{HO>x9OJBHtD{%e@nj7^JYe}ENNUwzxs#qy!Yisyy<7i7GsLc@LH zaZbTY3MLf1tl--UUQv*d@v4d~Vt5PA$#_l1>k<}jGcD8EE}<&YbXY=lS2}J;SQ0fY zqd%7#Hta!tILV%HG#%5EhjrT&ZNIbHNtjs)o1-a1v&~UGm9`x-t7VN$CO4MT%v2_+ zWppQ&(7G+hbj}ifLu7sF`I5Hv}!&>zi;tYO1ijgf&4Eiee<}hBYo>$Nw5EiF9;( z)L@`ZLF;x7XB}IQIU-;eAqiIvIC^ZXPtUl7x|(={@XPp~jPnv24(7;P$~bIhO|sr; zS!qXi%(O)g+5$q>Gp5hEx6eG+aw?YTC(#mW=_Qu%-X&dv7};fHV-jj2J$nW04Hb2< zC!HRnLL)uGB$UyqH9a|K#>NqyWq{(Y)xiZehR2 zi^&U!(h8+*ligmJ-0z5ly5cTx#jW#@QohFiB9}tF1L>R{GkQ#s?<=~?Gq(MtK2E+G z%5!gjCdQN_;;ok9w5M1+Vzxfww8xSn=yq>ohTT5bDRCaooeJS&xDdkk(NDxVT`Nr2 zyy@C#&eV42%wCHXhM`pro2Mkydro(=YyY@mC-pNj-VEUfn3S-(JVLiRxHW0Tyb5wKSVf=0vi}_;m>H;e8RwZ^YxbGJY4r z@9_s_NJ6*bA^Z`4V#0^;XZ+N0H2tt?%xq=gEz!x9$T`k6r%Rbyu| z?G~a$Bs$j*DM)H5-AQPNjo8L`$A1}a3LHP^uS8-Q6Z5q`5*<$PoD+{GK4a|LawRAf z=YJsW^B>|8nuAyLj(+#lc25Br|CF%3vc0>^WgN>qhy(O9d#tiFib|y=b!$``aBR~W zm2hLgw9-?NmXT=b^p5f#aR^oQ?&_AXzVePl0=wjQ4)h(O2q=~j(~8el3khd0=N{8r zzV_wxT*)<{CeqvM?njUFG;0lvsuU~tj#Py8e)mGgYZEUbF6|PQMw*JEbvr53tINq4 zJdx$X%<`;YP=%ve!$cF^#n0uWtEnbdtG5>P2kWItpMWFBU zu?V^>h?*v@kSA)-5zH63oV8y?BCTb(~FTzl&cOA{$+D;=Fp^6-e}KU8z(Bf>FX7T~j@UC6lNV&HABwOgB#=JdLH{Wnqh5hZrqy~+eZFa(2KpO7E$^;5O4bsb$69OANskQ^&H!e z1N447E#s)UggR8oI4EO4#vm5(zjTRHiu(9EAjvp%35zOs&#|udtvTTX^vF1jBV1`Y zT^{ACLs`OlEQ{m#c$S-}#hp08A;DB1wP{NY`nzi3PN`f1!C2$s3w4*#<>JdVogPkZfE!d zMCcHfamQ;gL{A8pK(1VJg$;fTP`6goUX{7z!b*I|@tBJf)|1C5*c z=spj}W)DE7?M<(9bb*_mi@5;sFav&s5`VM+q=GP#NO4Spl?PIKpLPq`H&I+hHi*Kp zF<(YDxn(5Zx>>X~`z6Jmqu4n$cpeYn1^#yUA|Aszyo3oCh3(wwZ5Z*3QjAmy z5=0T5D9|=hpl!mZZ3F$yO8-g7|IhMNQqPJCS4jb^nJsBCZUJofnZ<7YSE;UUd^-EaNJIqGB|PB3V(G#P}64MnsU+1yoRkd=9$}4DQZsW@a(Q7^C?# z#uzJ=RGG?aQhCUWsT7z{mB&2fN2PLlW`PatB9!pZO!wZt_uSLx-tK??{qrvX2k}tD zr3fzTh+#m(6&)2A)G(yub-bbDO}rJs=?FS>tj62w$9FWCI@T(qVI5USYDnp*hOER0 zMwP{w21`dR1}ia+t2&4D8f0LrH79~|8nQaJVNea6Ux=Vr!@D}_)lxki4X%y`HEB>2 zPlGS8`nY9V{t1Ed*xt(m741$+3RER5TlVBK!_w_HhtpiCNjOO}ec5y^HP0_r_+yqQ za5#~XhHH(Q8OQZ4&+ue6o4cAbtV}j-WKBOgW}L}cahnFR({V@Td9~Im5Ot-UlJ0qK zGt(L-1lDxe6PD}P8EF$-G;Z6{ZBLt?CmClXmf&u~86KBO|C$^&OfO^ju9QZ%^v9f3 z53#o{h9zU#=BQM@jQ~P-Fn1dYg0?Ca^vtY3f!#|8O8TTt_$Qw=xoNo{ip;AYm!pI}Jw z%*kn)WVVOLDWJYiOD`#4#1gjjjSQuebj=apNTw}C^=QsA`Y0Zmx+py-ol_xOI~C8B zM35W{cUQ&|!jTS zmgN9fxFaD}^;x^XUx@eU@(~6{F;^8`GEEr@E3LTrA%4ID5#cM zL5-;1(Gsev<^K+&*o$idI~Mv1`om1YD6=MkJtfRSjVohSG8*2C;yT{fa3hKja8qsm zFp69FNML6P53}{gzEQ&DY%Y_X387rxUL3YUqRj4S_&ADBa4d>X@tMG(;yqUt>>?GQ z;qxfIz}+am#61mPMR6ZrNAUn1Y~#!Jm~S4(pSE!^*)2blnZh_&JnZ7PjzClKZF8M2 zxNm|+r{Noc6UFU=FiW^l*dk&HrF0{0+M`CF?^^a~aLcTpTkQ?5G&Yt|=?CEjHpKQ8 zYzr1yRGSuxs{eYH1y;qKaod-!ZKlJOzr2){A=UrN%~VQY zf61GzxJ3p5rUaj2oz!ZXepqXFM&yA~> zq>3hw>MEwNo5AV?*;KHqK$%#YjLS#~5}og?&WYNBRvI z;N<}8!4OX#E0HnH!vX#)ID(_Z9l?3Lf@3JBk7oKf&gc27^j%A<6I^}Gqsx;X+HlH4 zJ2^Xz4*sMVOK`hlZ0j^?narkhzhUzvwlw{Lx-twf=dHi;*O0_@bOpMPFhDIG&kz|w z4LWg#zX^0Loyg}_mdI}6>LrmEm{%WBULuhLTp8pzv~omtDI(*F$g?E!TrncIk;v@} zh={{t--!k3rnC|z_nC|+Z0LxSX_Na85D4E`3lBuU;b}f+1 z?)j2=M65qhGC$6f%y~+tlFBbq)eZE#XMyL&`JR8G=b!2MmwBEq(sLQ>Nsaw%NUD_z L_TL;1oUHo~A^=TW literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/GuiScreenBookPatch.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/GuiScreenBookPatch.class new file mode 100644 index 0000000000000000000000000000000000000000..6f6b6599a0d0acc4a6bc7576742d6da12b0228c6 GIT binary patch literal 3625 zcmbtWX;;)%7=A7=WG0N;C@5NYz!8Mhy#)o4&1nZv2eH`AOt=hzNit0`sNMH{U+lN? zq35(;TaN`>&*=~7kE(rdl7V3ssx60;$-VbopZ9s+o4@}4<4*u5a9hIVFj8Sm$Y{Y8 z36nBHxGLcp84{+%;+lkKWju%HWxRkF!{`m8Plk-^5vWKD2~EPZj2L(XGswvFm~DWL zIk7h{Asay_j4;eFtT1w6^vl?Rm%T0vfNM28AHs|Jf%bLF^wt5&Eb83bsOo!WU!gQ^Hylr!n!n(oGFk~+1wq+W$ z!4OTDCbtK&s^f6-Hxo}$VO#NH z8THn7OOewafrf0X*kd^O5Kak3ZZ0sK`@h~9!n*00N!_9J_gC{w*m)v^W%K2{>FNfb z)E%7))Nh)WtGc>n5?-BEqET~tP#zz*LR}<7%Z;f9RXsvhv|0b1r5VJ@Aa^vXT|7Cb zE~rXYH8V=ewRJP&LDpQcrWdH{3~iNk%FPf9g%QEIG8YUXzTk1<_&P~>B1$H&D?>uq z=Uj#pOq=HUt%+MXKAkWpbXO32L&{aP`B63JaoTH(n?ynCO$oOc808v@4$7;4Z<92CT zos#aN^t;xWBXXvVxhPukGQ-|-dtL_>C?&+&7!Fhsqd_1fMW+eLSE6_ouQ9Y%5%>93 z(2($Y6mQ^732#O5Hr^2y-j#4OiuZ6TiudsW!_mqkMNqa%b%m9)5DS>i(>o3C-ghg4aCRPiD87*zskBu&%~sKok34Bs#ud!*n! z?I^w#F&?k1x$Y!oXs@ib+TY&j^x9j(cMQFio3)vD9e3`eRC{Qk7#+NwtPhhIK#1{HZ8_wERqrWx*fAW#>_4;T6LHmMDp z$}kqg78b%Qw(jeMfVT|bkVybwymk=3ih>$ zLCUQAzg9pLKu{)V>?-}dUccZd4$?QC_zQssBiiVBh*qajOK(7=JysK|T}Iunw5UOx zo-+LcjR>O&hv_Zq3!)tzw4ye^<0K)B{75o&^gD7Np{Zrmk9FRMG_|?8ZW-YvL}(>X zZNa_vB{bYaG`1nOkvwhkPe`sikn6aM&7DiwvKqop)RWm3GT%l)#K~bhddcxHeN>8& z+I_b{NE86&dCUuQ1jp$Mw}v$Pa1y5|%hM#^NM}#b`;!hC>2}bAGY-xoLPq=ONaS*r zjz!+P?jttUzKpHOJJ_~_#*W|7RD-J>OW6Jk9s3Y%Bw>MJgse89+l#5mSI0T@(^-T* zgU@4tj57=t0IO*T09z~pj9>`>6Y#CBb`X4bkK94?PYB0${)|wpwy@eIR*%JYFJn&y zsP`5_Ev)=j&|A++aUp6wE*zkMfdoC1l;|jxWE>Z933Eu{Hm=|YOcoVnait)OD+O6x zDaiLhL57G#RG=~^@%zc8G`^$)Vpp=-`$$(1r f($)}jtcaN7gl`R1QV{wQ6#A8ErxOe4I@kOUcdWLn literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/ItemRendererPatch.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/ItemRendererPatch.class new file mode 100644 index 0000000000000000000000000000000000000000..304da91f2ee439887c0075e2513529d016f8b600 GIT binary patch literal 3810 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 literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/MinecraftPatch.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/MinecraftPatch.class new file mode 100644 index 0000000000000000000000000000000000000000..93d6eaa9f5b23f9d3075a2b1910b7cd97531773b GIT binary patch literal 5493 zcmbtY`Fk7H6+O?AGvkTKqQnW#VgfjhW5*t{kU*TK3629!WXFx11g9x5lE?Pg(nuYR zoSK%>g>JeL=%h_>zLBHMHXy6%#7X zs`#>kXEp4QmcODgpsyQ*wH(9?z+AJu!QFYXw_ZoeFM3e;!QLxyV}c8sJM%MK5lPSm>FR4^s5wA-GroRpn3 zZC4=FW80?Fl`t|HleUIiA}MD?PsPT}xO>)&=|(20yN+qw8tS9}oeTMsG;CwU zl)81#mtJq|G?f_blt^gFf@>qM0=Ydv|@pK0#dIoIGky#!`ke#3-y>L@X88a7Ijqvb9?D2V)u6G2&j- zULp!y#Q@{uy++zA8L#SQnB@wdSMY*Bjd4g|Rhd;E_h3tp%)`LAIVm7|1Xc`LnRLRK zyfte@OD;uGdbs*7UPLPtw)={m6@I_^Bc>tbe#Q!Ro6(+Ituzbe9$@yYRE*)iiPk7%qo}(;aebco9F8* zX;iW@BsB`Y9m0$Fj)L!o@I8EAD)~VOKg3H4UJl_$_;Cn7!7BoXDmU3;Vi(-=OXWnR z1}nAiSMbvieuke5TvNrxd>IQgRgpMsnTer%3<5V_$+=>=mQ^pI>p$Kt{rW`+zr;&2 z^j~o!>OU48Q1I&zeuLkJ@H@OJu=`3z$`Cm2H!i9BObEY6#OHB-@|W-!mgz0`D7FB$ zJAcy=r$YDx{>VzJf(G}+JQmX0pJWiPD)@5NX}e$Amb%z?^VP@V*;K`W zLZx%Bsv>eEn@pEF`L~7Xm$|tJUdtda)|~X60sLLYuUC%0>iIyRwepJMCg&Xpygg3A zKe&HXmiH_yV#inTPi|^efGZv>*n?%O&=ZC|qDNiFvPalat1K(u47}c3zPvLsZ$>u# zkY#fx$;NYgeu>p%-ob}C!JWv%fZeQRYl#+bk_~Uoe76QB)1-7cSN7Ph>DWfXKMZVc znYX@FqaP?$cDD4C2&)2{X-^^=;@0N9PI1r zWiVA-%`5BUztrvm4y znkfn6b!PT!iN3a_$2-woEdfiM9UDpLmYvSJdhxWmBA=d|;=$1+NPI72-*0A`RKdB> z`n_t=tW1|-$IXPv%-B(x@`bvhKu6_8#dF5otsL9Y$rok$R|mnSzn|APa2hL z1!V?mxGt zvj}tDs=oGFtY$2i!u8=b;kDDadI}Akn-kx<@OnSK1{r+&6gK2m?+rEti|aS$*UQNT z6tvBtu^~8xYl>(!Gei(4mAG%<7l+-rl>r~&HG(rl=-!@3caTQ>Tn<>1u73)(;Xr=WBuAUW+694|z)OKfD7+s=Ge((%W7vrVF|+Ao8Y6HDSnedEcX=3rl78mP zyL^6*=1^_sGXpVdk5lguYA<620t$u{@ZDh;HT)Hq8GOkcZ%v_K>> ze{fi#4`nrRr)15_vo?nD9BYzb$=doEY&(y&dG6W=*G;3N$eoYNGOvIp`PuC4SjS8$ z*8O@Sl%yINA6v#c>a+_)-k2lODXAQi(~u*lyk_(~yEjO7x9518#ST{8&b>j3?_$}V zm&U~L+o}BvsfNwvOh+r&l8%*@m4%hpcbS# zPpDHM)G3t7m`8koI@*z9S_Hk&kD}%>vxRKrs8y(R2`?(v@?Y}lQOb9tIU-8A2&Fs* zC6Iko&aP%l1|7*@25tsf*8K#l+b_OTMBVGhv$#o?-OUl7$u^(Dwkhm=mekaE>Fv|_ zBo$mB7EgOIukn}TZJ4B79luQ8O_KR>1Ml$G-NS|e&ekyEZ{qNQ2Asw;-h80pfBG}- Aa{vGU literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/NetworkManagerPatch.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/NetworkManagerPatch.class new file mode 100644 index 0000000000000000000000000000000000000000..543b603351096cd121de12b457758d60fc134cad GIT binary patch literal 5085 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 literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/RenderLivingBasePatch.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/RenderLivingBasePatch.class new file mode 100644 index 0000000000000000000000000000000000000000..87d5e4c3e64d90214da3b0f36a4e0cdc3b3a9ae6 GIT binary patch literal 3093 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 VK!U4bd=U?hCYc>y#*?GT{{pGK-tzze literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/VisGraphPatch.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/VisGraphPatch.class new file mode 100644 index 0000000000000000000000000000000000000000..ccbdf9d6e8ef126dc72ae15417069702a5080ea7 GIT binary patch literal 2654 zcmbtWZC4XV6n+MR80GTI$zDG|%fE ztrV((!@UI_xoX~C%q1;1X1HASg&ny~?gvrg#&#^iFkMM)*AG2A)Ad} zTJ{|;a8_o6SZ6!)kl7f;sz~(e;djLGAP82pJQo@I#Hv=u%{@44i2X8%yoNok;B%c) zqr91OK^i&Yo~w2JjxtNje3cF|v{P#{p+gd*bX}r@m9`F6ay*wplp-M;A`(%_X{B1(sDofmKlr)Gat@7!Veg&{W1P3oe!!hP!y! zQUocx3*=$yhnpdkOUnFSv=tKt^9=YFBy0--NR-!iZwN|KdzZ(+3kwlq3kgyKs}^43 zm4(-sU?}bGv|E>97~S1qTiCk2Xk8oliQ(4ncpcz9`Uk`LVpR#q_PA`?b4ldNW_jm| zYBPtnaWlH7(d}=FL=$2-QoPV%rWZ-KgF9nZ0S=2bH$1Za=Ht6 zyYJJ-!j%*$b=nUG!{MYKoHTv^vs>-RnM=ea5IVmD=3=WNm7iE<=~b)5cPj zR55hhX@6m;LsK;q!F@YU+@&Qu41D1QS!-%z$n50a2>N0++&ENUPwkxHTxW?h4V61< z++Lz~=f+c9I>HlFtgE{pbuWqI3O=SkCF<7;B8pQq4%6(Ko&)`(g`Pt1I&yDlu?MGV zH0cQ(MIOg6LT?tC5D;f@mY&q(aDfoR^!_(t`sn#=1AWiev9C6^0ps~$yd7Ob{w?|o zW?_JQTWi?Afdhm%cr!95`wxTSGl>hU&;^fbxyIsAb0w}<`%hdlT1 literal 0 HcmV?d00001 diff --git a/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/WorldPatch.class b/classes/production/seppuku-1.12.2_main/me/rigamortis/seppuku/impl/patch/WorldPatch.class new file mode 100644 index 0000000000000000000000000000000000000000..bb11761d98e10a568835a1e7bf2d680628dab3b3 GIT binary patch literal 2673 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 literal 0 HcmV?d00001 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..04de9fd --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Tue Oct 22 11:12:30 MDT 2019 +distributionUrl=https\://services.gradle.org/distributions/gradle-4.8.1-all.zip +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStorePath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..cccdd3d --- /dev/null +++ b/gradlew @@ -0,0 +1,172 @@ +#!/usr/bin/env sh + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..f955316 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/lib/json-simple-1.1.1.jar b/lib/json-simple-1.1.1.jar new file mode 100644 index 0000000000000000000000000000000000000000..dfd5856d0cad81dfe7845ea6ff4d170d8064d7b0 GIT binary patch literal 23931 zcmbrl1C(Y>vNl?_ZQE9tZQHi(>awfLwr$(CZQHKuzrUHe2XoKNy63<9UAfkNcSdBc z%-H!vC0shN{0ssOaBcd!oDJ z8^HF8oOrBgOhFcRGX*k0T`oh1NzcikCA&Z(aiH+YRSs>YsH~$>i*-wVDtNd2NTyWiv9SCz`B6MBu72AoP_k^+@uM4$gIf3JY;0Z@ zqYYX}$wK&SGTILUMHPdqbuR6$DfEjgAaW9-V{0&9Um5lwsgUJ#Hq{mXnApSUbHs?Y^!8f$iRmxy? z=5-}WP4#h}Ul;rbfzin_0Ub;hW%IcKcXMm9Ks!#;eFHnQenGY65qSUs00@8p0ObFr2_XNN<3CIQ{6`QR;x7aJ(fQl;uNC3{)c=Q~ zje)C)E&cySo$CLsZe(XeXJ%(-W^H0*XKX@e>11b1>ttbLZ*B6wYMJeS)$;#sFT(%V zz1aU5roE$`y@{i<%s0SbUypC1B~TDiXD1^0lPX zGZ+=%LZxviv)tapOvj2Zyt~~$0#_VomJ*28&w?Tm5yHj)fVQSuPnNBsKsM4fZQJ%1DJC9c;qm2ZE zHZ0q&*E6t+@qy;P|;C@IjcKzm!8r@_RX!_l1#)iM0QppfIPJb zRg!Hz(MZDCgzXDLl23(B|jGjmE6V`=i$ zll7(O{j-MUCC=e2O==tg82exz1&+QDOLT{11%-umI3IIiQI%gaEbRbYw>JWGPazao zTN>}7rF;RWi#X#HYZ|wo8`f-L&aSb_pm>?RZtN*)FYs!Nsr;T5JYqkf-S^Y6m+8D| zkLrQgJ6Yi}JqGR{!6%9+kS6bARexaXAPYf`D#U*nWb9HZtT8Xdwm@DFdznwSAxs%I z&>~GqzAHhccmK}RXTLRMLB0eO$~>=pL^D=|uwOhxl+IkK;<%9;o51XekQM}lwpt2f zB}p(NKzN?;W5us$xjrCW!e7UB!gupOozP69Wyw$$-0_-K8gP%XTq}*zg{-xV_}Vyd zff2KhUAQ^G##e00Cn_Pzusz*PSu2B|vRr~FHtU**`@}Q#c(^_)t+L9COwd5biZ?wE z59LU?5+>h-$Fj@CoL*SY_vgYWpmxB)v&DX8ZR}cn2kwHIG z#HC}ZUGNJvPcIFyl)C6~a~l9}_F6dAG#D9nb>L`rmTC~aIiB<8VzIKL%V&kS=&EqD zt7Vj&0jZX<52n>4h~1)?q#@Z8@Y}R*C!#`Q3Sl3`3NVkYrR-cuF3aoM?;P7fTm1>6 zhV|SYYjrAhtdj%0yY{n`a-4Dyq&iw~aNukjC>>yMJ!=xDI?AKsIva`s(15B(^P%rW zNXlL4W7@FC=fHi1t5B~u&f~XF65QttsFL!K!%{uJ+3yxrINU21{u&Kx)0Gyw_$;Qn zSrUVGVeE^3*eR(Y9^2gy^uNHF#Sd774;TO-4EDdS)PHuYAb(b>ouk?R3OE1q1b^xL zg^2$vMTGyV`2PX0Fa9YC!22KcC7excq%EAB>5QxmoSd>$wVaexP`+iWWjw{LHWGD9 z<>^Re6axZ4+dwE4A(~MvY|If!Y~(hS<_iz|r=STaxC)rhv3WVWABVux{26+q4kEb@ zUg^E><-)A48alkvvnLr8O|udjUcS4Vy1%YmrgMJtet`DUd1DT$My(Ly^0QCBF(L+m zAAA}yiSKcTzFar}qJO>i{*n?{Bpxt`7;r|gN!>FDyfNjRbVxnXzwZSKoxrL0rMYJv zN%i1M4mcg;2&Kk>!inI{I}}^{Re_~FL<%b-1f5oqCd`(QAr+MjWomn!3s$4SgcgZ~ zRn_M>Hc1vTX&4^j9Xgq*A!%tZ<~hRZ9&=;{0}Cr;I?bV@o5=)alvY;R*ZOuQ?aHmh z@YdpeN;#DQvcZ^0KS_!f@ur<`PDf`FEgbPmBEV74OKduCz9$>Xc(N9klFm7%gZY4G*%jr4zy_819Z&sM6iX?tTC{idYKV=%}O0IVmv{$ z5q7hcxo(nbYasdgsy`m?hePT>hOhR51FmtVsn|y2%BBU`M%4is@8TVz?8R&9008ft z19XeaW?u={wPDze>|HMpZs4o57*x)JMD_9f9o!7=FoaEY0|pn|9&aeUJ6>GYk>!S^ z%@tOBTp6fQI$rQ{do+yd_>UYMD^Q7A170PZY4j+@Ghasl+%f*?R^529MIi|~RTrqX z%#!!1%_s*S<7Ax<-2;>lN_iSN)S|r6^=Y_Alju!ti|+MLYH8!c=dddl+zGP=7X4!< zqDU&eiu-+8jg@Aj&mwQy5~Y)yVsyCOe7<^;SNykMh8S2KNrv=aSOFQ=KbKFD&F9Eg zj9Lq3_R`#eZj4^>pn@od$UJrCXd+}F^3&us5evxMo3I=n=aS;wBn~;#FY+(g#174A z-ox;?18RVNQ^`m=|S8RSAsu7~Q!v;@&D; z*3WfI&afeWq6u^j0jVthAYt99Yp07Fv|jON5_wi#P+yT0%7@# zAo!{o4qvm!LWO%`4}XY?H?v8o+u8f|8*pZz_5{#yMu878lF#3_cjLNBe*ie>s)|8QB_O}k6=hh+5Jb-woLF%-seYKpW<_-N_^^u1wQ<4 zZY+Bli8K{tf@D9*Qwv_*j09n^*rJ2_@?A?Man-r~i`VAYc5TTHc4R0IYUlh7q?a~d zZ%fpbPhD+F4r`fXf3`d5R7xc${r5g3YGdi%63|DT|Gohgg9IoZp~a3MFzcNu&H!1b z3?8R!F?L}zmjE&O8C|eLrXr|PMEPVR6?4_N^aNAe6*=UN&?!0O8H7aPUMW|%#2gpF zA9w02aOa$An$w&mnX~^0Nyat5rKVYlelIlj8P5P)%?mp@I zs)-^5U1l$=yd*5t309202pEwK$N6ch$?Of!#76Olh7K=mApfljnB|-{szSoLs2lK|pt3-&FS=F6Zu&=Jzs~pvUYSQ^l$+j_c!06AG=s$z!fA(_t|AUv4RFabwaC9{A_`92PQPEOE zR{P`TFqn)n5CAEawKj;@V#OP)%-cKwY5EX^836C*B{1~W4MJGcO23eOPS9`5>BFux zeJZV7o~kPN2EIYg+)Nz>knrkfIKBM5a=LoDP7Z5+^?U*9V_aahGpq+N!XBiWi?EX& zU8_>t9>k!yu}T|g3Xz*CZ!Y8-C`aTJrY1EPZca(``cNuT9jg?o(3HC88Y<)#n71b@ zjHcSoIbMp5SpYJU&$1n@ip#UEZUDwA^%P*uk-osciaLkw#?b~RG_&-pNY)MUZnA;HnD?x6jRz5h9*|HuM{LQLG7yBwdM@39BemYN;*boQt@c8qrrGK zH6(1YIpzUVfpRu#A_uO6D^X@%Bx2eQIg-S`OTAVkpY@sKk%->oL@Jx=9M9;$d!sIQ zr!0m(~3M%rkhXBjL%@d(WnQ$ zQYj8CN{NAf4LDjW5)>GUk1^q%j}uV6R#mP%caLJlmAh3QV#fV)ryC;m&mP7+d&LYv z;l$k`tT_M^J-qg!6a{&gz2dg0xZAT*^qpAeGdXKSpodL4(y=x+@-41Y5_MMLO3*HK zt#XuT(zEX73j#XHf4UquZB{>eP6(F-myHQVl94nw>r&v~Vv4YMNILNobL_SLeQUv9 zv9M8lD9vyUJm>jK^Z=dB)lJ4LOHa?a+}F7L0mV-F_Uv{7*4B<8_BH*N9D4d|K$Z|Z z2=9p5>CyU#8{ME%s#grrQOY7oD^&HAkR9RnYiwkqf!V33ogOCypZ80oj^+WXdA(@_H{L~kUE^rK?IMmr6P_G>V!}|?UAHJOk3JXzO(vrxH z)QvhvH92#@Xk=|6BxXX=yowVV4^2j$7Mnc{c_5;n;}1h zYLf1D@~XN;F1*urS`XD`R3W+@bdk8b;c4k0pJ7!(HumH9nlHcS`0jX*5U%?6W?Bn1 zW{~`jpCGHv(v*;>G{Oji8&XdYXlK8Fa?{4AgjV{cS)0D@q>|213s)i4iM|PU8;%}m zBwcLa^gyj>nN$%pFi2@EDDAQE0a?>STFpQIoRp!6IRMf46J7FYoXv+u4O7qMGTBD9%$rY zs8Eh4PDvbS?5oi3tLosJ?dxD_D@Q81{|Nwks4ii{d~VrYc=HJw*8*Az2N0$2zT=1CIAjnKNi+v=$no-RxBx%>wW%YJ!)}Rqk2@ zTK1zFtV9lEQ=KwN7$%8|WV7v1#1i4x#zjS*&)2PSPU6i~Kh>Iqzdjc-FV9n5EAt9l znZK98z4IJlP>RHddE)AWloRbD8CNA`S2!UIoIW>TJ%h!L@=Tjve zErw=UQyvoA9VOjd5f0$3ICUDOz=zyG_6e5`tO@#Va+r-v+Gv-J^33ZF&~?&>(jBi* z6)r&Gz=CehF+_Gi9kXl>_)xxS_W{G|?MlJw8Dzgbm65>e8R_;3!T!2c9{_!{dKH!I zUaCcxJFJz{59B+*>K;&n#ovz#A@MvqFHH2I_xFw67;!vBU44CLLpImEyXdr)gCBji zEWK69-Gbj;tjs1C+W2&ST$p9f7Lh8eP7pduM^{(VxT1k*30!mX9W$g3+ET@3E1W3; za@8p;?dUgKA+z@E5(T23RD05ANKYJ{vPuFPZ?uKSa>IQIPS~<;%NXCLM7K5{x2GG` z{H6RMOVTnQN>*`xE0csxwkcl6=iT<=eDk*Z)Q6a1>xB(c_c zF_oq9#uc@zD2l=~bykWn$;sNjP)^p}BFP*a{wTgaTPMe3wC_ zs!Xf0j+Hm`MRg~A#6I-C>}iulC>mlC28_r}y`cG~sM=m;7+c>E`&=_XmpbuIiW=ls z;PX0tnt1_%N}kpzPk&N#DRY8M@)(>03YQBILn(7@_a`Ts`=9lwzrpAF9q2JvN7SDS z@bGg1Lq|stk-QSW@r+2e7N2(+G&rW%ce!QnO9m-752yL*9XWup%@{+S=)l1-w=9Oc za?}MdOC|s}mk9G~J7NjH72apzve=!O<3`Hh6;}p+chT*rbkY+lPI<+%KXrw??8{J> zy4;IA)W5;sBw&s*0OuX|KIqLkACdOp@@kk%B+c8mCW0-=1XfTS8IS@}JGT_0>3*Hv zZ^cK@8h$<0KakIkIt0ZO<;ISSM%||@sVqOZs9wXOZOI_{MiNHN-9aMR%5zDS7c)%t zAdQ`1x`rP{i8&I}%EkHeTD2a>P3nc>jS2GZ;X#Hw%F!4ML^u(ur9Pj5tN7w}4#-*H z#@Y^=lr574yHhw2TkiETJf!BlxNlzr0KsrSa=!){ zR23m^P;82cP7o1BnRO)UaU?|GW~Av(!h`s^M2lDyQc=PCOvG_rs8^bhK_tv{?Y`9? zYl2Jx_bZ?ffbK+Qxz3J(+vD&C{`Tt%*&Ko1nYG-^t&8lCOSpOBdY429&7nbHjmb+bGlh>~(1X;d** zL4j1QJXW<RJIV<+27MIhzs5;49cX_#@vQ84Djq01l0#hc>z`PfXG8LI=L2bE5 zk&TXK>@BnYB=T3o^+9-XBg+i{NNMiceFuQvu*5K*(tL;SE5N6NX2mwTS(CNC zK<+?tV7G}VV)ls=j74>H*^5;cW|@{KrJ0(V8PdbBS+2_+OZc=5kN&J3k0^GQBaHqY zww9d1Q}aKWuzwh(-JObNeO+MR@3LcVmOZ7WnPOunVec5?wjzu9VgbFfWhb|e6mbv+ z-mU>;_qhSR($yC_S_PtL6`jWCt3?E%P*T!R=0nMX-O^+yBt!*y^ZvY%P}1=^vzH|1 zU~VCQBTcBf0{x`pk@H+FQ^-|2NdCl4a2Q*`j9j3zIu`BU`89ooQB2*FC9QW(a*h$c3JB*QLI$h`AY#>OQcWXF70}?OSLG*s#&5b)n zRR4}k7wmq-HcLM_e~H&%YjrDbjXQ04ziO@Ld2RoATEv=w^qFX6vXD_1%`q-nl(c0C zAsf&Y5@Fv3jZ22V^~cCK^C=gR!&aYcxhabEBSok`kk_5oNR;a{b9jJ8Am_Z*M=hGs zt?WZh1QY{QGi>t7)S+-|%~;3drIs6LI08i(YCL9iZ(xjT`jwcMIfB!R(3vQ6TaZ>U z@s?HB52hDHRQ*;9_Gbefuuj{$&Z`q{RZHi#_r4i?QA$fs!w0*Ardc`I= zBADGaDw=a(ZUn4pQ)p^t{qSQQcS?f`YXv6mX z4&P6o7TyylZbQc=H}Y~%Ik(}^6-d{eBa~zA3tNt+I3n*^|E2;GQpXR?7L_M$NyYbYw|~e2l@yo27w*quss59Yf|)fKbvuEzwBlR;b!pG>aPulpL$jB zdvM%QKNtgiIL5P#TCqnQ;Jx0v8t(yg`vo%ld|oN>dTVY8ws%7>GTcG@dI>v&#qQXu z-qGdc9Ju`D4!}CV$ZH|l(d^sfGHr`RT$3YN7n4zMnK++<7b^$M1}ta{ziHs&28X%J zqMw~%r0U_Sp6D9aF<>;72^+S9Ck0UzPjhf)XfYB>>$&ALLJJio<~fp0abpe}ZE+@W zD!F+!7*g&*bbP>|cFK-M>pydbhTLN;zPTe!q9A=DoIAsCIb;HK1+i-M;dO^}KV$uW zBLaULfxWVF$K=GuFcU(+S|jwReE?7g`?!)@NHN_HN(`+RCnmNy>MrQ(w zBPN>dw1<(Y7#Oix7rP8__04Ih0zsB+2AI`515PcicL;!lV7Yb6+A8b=NyrAsXhO)t z{vmePh&G=&m!N6h#>`b1tjbXksA*oryj~KVKW#1!?X!tV+Bge3T}sX!5N}`mjd9-J z*Ci(atF|9*R0^X;xBs%O;@#?O>m0|e>@49RQ^zzT1@9F@Pznm^>2UIG z$oT%Pm9G6A1gw)Ed?@cWM`RI3#1K;<+{X0G0K*uM}7e1fx&Vkx8XC?wr4+>rJ22WN+Z;Wa9X559|J!hNS)1%?R1q zIvZHnnmCFY7&+TH{)3d%nf_b61-i?Q6+JwR&mFkl3SNsus501(9AyBBZOA6AN~qRw z3xFpnO%%p86*vNJhc~l<+lxhvFN6XRooHyp&bvH*iGA-F;%WYsls$gN^q>}CwXQ5J?sJX~T z9<|{g^&s5EcZCdr%d&C@q2tb<#q)R(vdhi`M*mm18L$nXRrzO-H~%);qW<^OU}Ebm zZeVL{ZQ}S3W;Rwvc7OpPc%*1h2C7JYddRxUq71nF(Vq#rgi zeS4_`kigZG&IV_y&$py1brnD}ivi_5g}+O98R2#?VZ>g_GNs}q62eCF*v3RKFP7?x z7)$F@!s3NP%O^^53bHLqPAsd|h;&$?i9RCg+LtlYz|@vGOg5ug7NqxDr5QLHQo|Z+ zMNvGH%_I+zpo0yUr1jMCZ~Y$YI?r9^cB#s%T4Alu8TDra?q6**F&ic967Iu1d&6C@ zQsMi+F4$^uSGV-Lz;<+jFW75+IMhuF!3s6)UxELcaVx8~Ow2zY8u9$M4~_o$#UuaM zGyWG1F8{Yz`R}t`qyg!zytMQ?$IFZ2Uhx4UNnk+#g z!gt_i%PGZa<}JtR=Eq5={pk)p8(=F=j#uoj5pDIWek^ztJh?&kI@Rb5rrRKv z3+>l7aJcLT1WxqgzesNo-t(cOB{0IW=q@D%(b9#lY|)?H-4ArppFLs& zN8)3nzUVp+`%ss6Q|ez#EZ|7?2z*JW2rb~GoP^U0<~xa|YKlBm(pR+Iw}RQVU!$Q% zARvbtpvlo>3FQg%7EZ?_&TD&!xTo}Vk!LT35fp=sp4E@3@YEPgpBq2#l%S2nAtX#K z=3UrPqOysUB6b;--b6&+n2kk|+tFsSGxfA5wa8D<(WbiVdTBTybYLpdq99z5GXHcz z7855R*w7k~pD!Wu&i6@NIQgWOm<%pBWZ>6YoW2qN7W8=c@Cp6Z#=58Pas8@4^vQqr zs_)`X0!p?pX1ecg|1YHf(r|Fl>MH$q!1{;3GQF zR|&Z!%IYQxN*%Cg1<7S~%MxJZY+~_q$`HUmoE7>QL{RC|Y21U%#M>mi$2*-5C9#g@ z3}ObhKFas%tRv5TesHXKf{I7QzxUHn%SKey+Y0;vl1xRcgLKJ|=0z>>2u(Ez*hDmy z8Ko31$YUuPxpI;g>Q%}^rcz$uS9uZ&<7kOP6)Chx%~Sf51`Ue2-fqRtP73ZJPqleTK|nta zeFw2##QXa0N>GJUbHKa|($$|)@jvb>#+qP>*-REwIyEl)98_BwZ$wYxRh@za(A(1N zr_@%sm6SUImqh%}(?Pv|Srj|mrL?jznnrz=XTTzHBiHBe(4iVWPvl3@mzP0+ zqc`ponx0_|DI!3rq}QrxYamlWM!`zA3__Je*Wc)lEvNLgkD)zklvF1f>>cI&ANe9zDx^XJP**($1rJISs zZwCo%BomFC0|87ozCd(R_>bB!H@XnPt9F6x?g_|=ZR~k1n96H1dn0cVQN(@(dhU1 z8y#L~IIM2xFZe+Zc=3k$VEC?A@ybtie(wM$-A|eH2c{Rw@9QBx^4Wg}Cx-*_&w zRn%8i!zhLOBad)hj8W4^_vmSxmYR`JoBG;j71NR6l@%#!a~%zO(ef%RTX7M^Qvp=>D!=Nr}?_*W{MJxG@h6IT=C<59_#8efK^W5U0~wXK8u z9bY$Vpg_^>9U2+*Q4R9!Ny1IT4e*%FN_5n6^B32XafUSI5tG-6uRR)qgtr%I8k`F4 z>>MA05My{h1!8B08dCU}s|U>Kc1OfbVu0{|MPupB95^T(2;%J^uy)6d925*AyK^&I za)*y36b!T9wNhAWPr`%CES%U|QHW^^ah@{CnCimqZTe=2Dedm!%}%TU+_MT!9up`bY8=o-6Pqu_7z^Cpx2qF|5mkGQI+V6*q1Es#vc}(G<5H_@nS4?tb||ipLF+Qf6sA?gny0<7m8fr04_*Iy+DbdvO=#-uBM z=wRZQS*luWg_aS?HmZL=T>mZ?D5+DIbSF@HA$sva!Tp&moA&t5xxj})O3Hv*u#^p_i-^N>jiV4< z6m~+w*utqU_R2E)s`;7b8qMmi(v_yUQ_tiT#j5U*uKtkhkZD->+md(hV4SN5m( zLiWSQ>yzUVOFy&FAzQ8)kEaPoWmZ?4UWJnPbSsSzRxBmVIkKLh7mN?gKn3p*Ow)NT ztaz1>VMqaurq5c3~!^M#V?%*Hhi}V?`4!D{b6T?kuvU*vwileH^lK z_K=Je7V`=xxm)56n@NXwPGJ7J+2oH=wcWj+dml?Peo(TQ;W5bvi&cpv)3QLTuw(S7 z?SIs)ym>{iPjP`zpC=jsqN_!wp}gvqWvG47vP0RyoJotu^_Xr(-`dwvK;PMIg3dK z#v5kygnV)apr1v&%sp_AlP!qj?UQ}S={VI}twMRGpnooRzEt9=(}NwBI(Ph3)Co*k z!oZPVIZ(6YhAXq+sI=`vR0%04$Eqn6d2P~+QCouQEcT6JUo7A#Ry~k$LFiEmbx_0| zpnRg+R=wG4e8=#U&)LU)0-ZKT|A^<~bVmOaG25--LcX!W=bdePmDh{>9p4hh)GLw=Jp39w&7}TCyz%`EDY~ z0_X$E)o??1q*NA^P_<+9B3pnb^_q#ax<7PWsBNuAm$R(cis^ydJ>w)h>{^i~rBA|% zma{!$AR8aA1mx#bzMGvyRcJ<9B>Ns)#=$cGcDy;pBUT}te+WGzE5D$gUYIAHleFNY z7esYr#h2&*e8MCBsp)*ggvCY+?@L)6yr%K;eu zUi)NofG$xnj8F3bxHX{3M+QI}6Hs5K32-(6@X-*U3zHuoY&He(@uLPH`C*JQq5YWI}?82Grm6mu$|a(EAD%IroBCdY4o(&sseD47_f@R#qsz#8nzI@usqpL#) zPlDqHzi)*vpr$8U&J%uL%sMpmNHXs*tgn-(TPm)mVs|7^+6s8)fZ@qzu}GeWNU^5K)_bYCo1soAwWeO!v0# z>B0(*31VXpl`Ng&$}qtp4XQNEYSYrO`n7$Fj22DT)OP4!qNuvSSN&GqS%)7><(H@Z z7v-n@6Uy2)1g0Er1ixg03aXQN8!y5drqcMjIM1Y5?M!@H?$C)(lY)2L2>v;_AM_bA=8{@~&e_twt{bld2y zm*2J5iORbuh^VAd7diI)u+^EG`KehMQD@5E*L4)#-k^WG$e4$K$R$zwd~Of|x1t1_RXh-~e7XVKC1l6?4l;rlBNHH0x{E-?k&1;Q z2pTHi*SGlBzaS{MyuT{+E$tyt|6W0;Y#+wk=MZ+#_78z#us`B|o-(lhhxmVK=TF5S z&3rlgPp}<^zY7GG{U!eAsWj~0TmO4U|4%!A@94CF>asyQ#h(LzE?T_sF7tyd4_!u- zY%2&*If&XEE5repJH<3FpgS7D2mIF@tv3G09nQ*7M=6MmGxf6)=5}ryhlD_8zGJ5l zw0#WKEvQPp2_X?wLZB@%J8izQrZi?_kmrJ8^D`V4|4xa4GyBmTkFw-MY1FmJ^~b4f zdycO-{4DV!K~({MotWxu!XpBY4EzGwJEYA?lBj1Q+`J{1O)2tINUpKXo)TE+ z5VmsL$Ha5lnbPdXN-W`wMSD-#=-er)oNTp~Ir>G8_449*Hr9mZ3J>L)@-l(oGm)ks ztR=_wGQ2_^OIp@4*hVdzLZ5RDPYIji0ZVLL1sP{$++4Lq0Z$#=JoZI1XK5b+a%ZHj zvaZKu*@A?3MXsWT)5hsMw?_u9g3tvGo`~&*gEKi#sxJ+>f|sYMNB?X&{Bs7MLaWnE zUBQ#5t3eeGpK7&v(5{H@qMZESr&UxME7bG!6h&^7RWB4J+a*YkfJgJ8%K5zc-0!SI zE&ML?BPwQJ$>;eys+8|hlB`XGRoX|JV^8U2Q%}&^0;%PqHwW87uZ%A-_BRHf@Gmh= zH{|Yv$~z~-OD}KYPd?pk$9vf-4=@Wd#c*ze$|S$iwcF1Bo=gI848_#(hs*LK`giAD z|AvA28y6trZe(KbY++~ncTON$S;r1r1cm2dCiVFcKt*FTf{}E`r;z*2djBQa!iR z$u{#zwwIad@AsD%KET5}jsVU|k=WiW%KGIu`xN+>ehN{9eq2awZ`D_Oy?$U`J4p(O z)%aU^L5+T5$c;@M$O5e45g0R@srjYnYSXoL3l>Ri80$!bVsotK0<7uk^=r#MJ3sY^ z&#lb2M8dp9%cS*$;pTcZl?WG;0||!*+i13=&q5>^3HV%Hk5cOg3ZvH3a4Ij6B29V~ zkp2;dB8_B=rJhT3l4>h+`X8DTbI;UMLg|=>M?z0dO|z=efr2w`kpkzb&DXKMA+t7H zvstVmKefj%=apGr!q22N*c-2|Ba2O!mQ1w{giRyQRm(gzJEng=NVj0Bju*Sgb2Q2n z=wHxt*;LIc&{`_zjgudlNL}1oCvsAzbOyL@KR8+ll6dBFj^~Q@WKza0@E&E7NjK>& zH1c#tC{^yAO=M{M2URVk(dpHIUtJX zkh^&Y^2<&w*#T1gdLq^AVQlnGSU$^pBKkTD3YH0_IX0<_K{$p|HBYo?iUAM-puEu1 zC)e+RG8Wx!0Hc`n?<5L~`%YTtT;iR`;gUyu@hzkWV+Ae7(nQy}9q{ z6Tp6R-)w=K>p|xQr02Q^@ojw$;eWYA34>6xgbVw?#;AUDz?Jz$0VB+=h@pdfC zo?7c}n)9ddc|f-wo6?0r`RhNkgZN&TKtZ0E2;g1;YFmc1d`#&Ovyj6%jQP)*R?gyi zls4scx61c4-9(}83;dol9NNEydi#(?7o(>hr3H2g7Qub6&gu9tc`>X z7JD`S#+X}$S^MQDOpKm^E0}plRDEJ-7TS3NW)4N>RJVGXyvev9NM=$dub*)Jik2il z49rbb0fej4e!%K2lQUyC+xxPLZ8<>Q0*ll=AhU^N(@M+1_YVITvDn0fuz&j}*QMy+ ze(&}NW&Sg7sbx zcBMYdBDcvoRHrsFT?Ma2`)azLD{@q%j)Vp-6J#ex6iiX=tfP+B7X{RwhF77;Q$2v8L5n_6(*t>b@xt zHm`qJ-q^)JrLv8%-V-T-T~`V_X;eR+madGhqB8b9+_^InwICA;nhL!@M3g8?xsN<} z2|9whJk?r)t}<0gp{>$^MEkuqHLBW#qO@MA)3o$7*~h|iGXYLHJo|*WEIaI+V2NL+K+G4)EQ{eGIaQ3mi zl$DV*(ws`gpG3RUtlv)}bXuxx((SG*B3i_XLtO$!D(k1W25AKBqYbLr!z4Xu!tB$q ztl>gdSgJJ!l5(%u39?pNE*45^p)OZgnULylTw&DB#R94gdLE4)E_>_A=7qII20ltg zt+kYkn@F~Fm1~6%7NS@z~U+h(qB zU>WDF8bBuv?ds76p8V=~R$ZzB`c;>-K31zn1rO2uvx1Q)$lEiL8?;YJswUr`>{!Ns;R zL@>8x9$c=99v+JtLYVZvi}UevzMR?;o6zx3K1C4Fd3$_;-AYT}J6PTpO?r29Y{w4O%LZKIQ6}&d@&_WijuV#)KH-|PcAMVyIW%OVn_^gWvhIb|e)2s(}k`MK!y z5+jx}9Yq;xmMx9ICf5V7J^dO&URg=TS@kE|oGIst&Q1g1J6slWuBhfr;?_{`o;Jt& zkxPUX&|?1Auz7Y0IG8&EJe+((a%L5&5D<6b18Du^qG$#%x3tb$DXOMK&?4^|^jTsc zpr(*x-|=rhxdQEP34y8+#STh{Svlv;EN8i&(~IFNbMpYfC|0Pf5n=C+%v(sgsOevb zTj;xc+(f;^Z4CUl^Q!gv#b4haZA*Y+ULMjvNA6nzawK0o+QgX;(!l(L7CbED$>t7T zNhBYy%OlSucjVyBPmobcK;4Pt?(Yu)Hxi)k>lUqwV&qzngT1dlTWRn1-PJU*W;jJ^tM0SjY$1fc5x|Y{} z-@m?aZ2&(4w+qZHwqcc>Fg@vDXrOOlj9G<^k`Uz$ccQgf67L;%);et+8)lFlhxf8A zpNQnwbw1^(Z()`F%COV_e5&hUfd|TLVO)$yj}(2t5}K+Qz}jO{y!K0&LME!LceQDy zbG2S#sisa)-Eope=cd9LszVM`VxgoFBO)#IS4X#rM@ErWl`OfDFwsE~Xm8IdUCo!A zLJ+t6u8*&OZ3!Wcxe4kol?nD8t%a~Hk-TS#>TpB= z&qRrIDj|pa;YkgSHkVg9DX}K`1v=qAlB9=&vPbxQ;)?8yw=pW2d|Zl@o}F-9ZE&YX z+H)ozerUofVSFpTCNgCuhrt#fiu_1T!uLtScT^?D)#~7Ch4kqnNvsgeqAkpzz+nS~ zFB%Hc+G(?S(1ylV>%diL(>6*=fpfLF6;%g0gS02$C>aTUI$_hh{t#B7oo8R+H;$Df z*a^r>LK@CyIN4P{j3ea81d=p@n_R&)OWd@WSUU~iJ6`cok}ZAjVABWf-L+ogwT~gW zmXcG1c3+naAajLRqw29(!Q;T67!R%7@`K>V~iz)IVarsXWHO^xxFPZHpc;;>Q-p6&Drw z!uJ)B+KfmImrB-{H2Lmc9cfacGSmz62Z>Ng(JZtL<3!2P$_VPjH@ZFII@`s&Yv|{p z=WosS`y=bc>3t@MY(8>CSE%E?R78DciXYo)mavh8>?A)sNf-RI@-MP}Yd9n72&fI4 zsZywFwFkm0j60z7XpU~}3ig)qtIfSIW_m{qV~^}tWaDp&edjiXDh8e{oGQHFL4oLa zQP8^oY+t%8xb_-_L%Ym-1V{dQS)jCUZhi8n85T?IvppXwWBK_pD?cq^9rc)n!Jbo{ z^bxt&=i&e_Sp;5HBxJIPa#?`)QF?M`@cAAOuJ99_+$Amf&v{9EC!QDWj`AHHe!PT* zzU=6z_o9xiOkMHux|CgsK7(6i-*-C_rJMh?N3qu)+RB{t%5y=^A9FVBx(^!Uc#yQU z#ddN>D7v$_oG>O%8CekgDyX}^(i{}IwJwiJqg8tjUajyqp5WaH>qAre%Q(zO zD@w^)++v;gBXm`35#X&1W&+lw^f}w{`ahjq2T+sS*2M%8N&qpTSEU!FgeqM?dXX-K zA{|6PdQ*fbDqRB7LBznNh;*e0iGqmIi%1b7C`Gvt5FrQ`AMyGw5wHI9zm=IiUrw^u zIVahZd^2aSr7Rec9VFVr1ns|Pqu;L&|GZrqQZ;AomTcYS(g`2SUWE3o59EzJ`yz`c z&+cXwQ9|>p!A(!khOGATC25{>3x(eo^3a+lwm2`+VW2$@oEt3?(VzyH!Y4|2-`jcmu z|Kh7Qnw_bhF@6;2?_kWgHJiNYy3QQja=m9JS;S`J1Y0KD%?G?C%IBJx6>$YL3Ypf{ z$X7E8di7 z-0k)ZbV$FDEa(e+SHbnHzd^>6HyCKXJf?tBqVB6E|q$7{rHuLddRpB4H7L*>r z*I_^fg4>0Qz3a+no7Cc!R?%KAyp^)*Gsg9}tJ84#j#Svd=IJ$7T?g1w`E|h|bOugE zL`-ia$JZ+oLckGFS!}*%E>#qHI|RqIuq#MS&N|FLEh7i4fH|EoZ26A2LgPL`uc#oG_~I+?J(T#syO`Ad1CSx^s86&@)VqWk4$J+L{eXD zRa#t&6bpK%d?`9gci;iwhyp)@RH|rZXtfeU*a_4;cx_U+4@v1b!~8x>JD(msZNCOd zb+1#ZeScQS`2H6$vxoelr&rLD@rp?XLlt^)k29Vvqc6rImmddub>50RUUMm;R7d1J z$DLIf9|d1%a4^SWapLBXC)BKd_=SRa(!0UtPa`8;&Rg)TPbFQm1_*=H1uJ~dY4 zG(1^a#La!DEBx9$Yp{o2Vz6`&cV269vGTx0g4g}UM0)?DC-nnPPFyu8M4c@e@iuOm z$_kaigvl5?G|u?y;RSFl!lofEYaI=b3yOIOOWnietEu5-s3cpTAoIM7MM2ae9AEUd z6O%(1%-r4JM!92!qXU=~=}=3Dtr=RbMfo~$?PId=%NN{MQp)vQ6GK3D{uo8NuFce~ z?lqgsjb0ZqVaOdEzY5>z%X3>ZCr>ThtGXdeR zAtgvRa%FewMMiks)Gd5?Uqaz@cJ;cunPwCmx~LD&a*#9Ix&%*Dl^EI*g(JT@yRkjY zx)3=BL7jVHSX?Ucv|9;2DJG#+Jf7>uq}z1_J}oBmvfDr4_Kv5ls9|}jj8$g%r%Saj zCcR%}+V@nNpWz_B z7SZXII_;^i^=PdkXl<`!gmQ>ZC+n8)oi5W^t*yD3o!3K!(JtG~|`i+Z^hCBkir)Gj3S4F|_o?JjG|ZzsaXmGvv0z4Qot&XaAm<0V2JslZ%eDR5TaIBw%UhEYOY@{Cx3powuEsoNU&zdp`ppA6K zRO96F=2g!rpNR?x8JQWF8<-kc8k{k($gRvQ7P2(3N)vJu(qn`(*1~ETUE|=e0NDGu z#yDy%v{SxQt5ft{y)*Z1t4++}VeyRmFqt@XoNL_sI5?xb@ZQ~u$f-CRt-QPT43-t9 z6_yoeq=jCIyb@+({K&|lW&XyaCW5lBA%Z%mzD|q5tWHE$NLEBvSXOi#Hhm_yh;V|f zpuFo7`Qk8LKK*6-7P3izJ*7RlJ;WYhPi+tKp%4c@jJ6`ASslB?NVtUe!n5IR@F(%% zcrcC@mxwdO_27=$mRRB)((q5xO`b|8xa zwNkdaxR-7zNVSnUfE*4vP&fb`z|&;Ymo|GD6>>!xRC`{3Sy!Fs=%+1U5Xu1f*gJYHy?iP-Vk%r)^+FI#Y}O|PwCFP z?=zzm=Tto|Q7SFLI4^deVG-!8a!zm-+w01m4NmBkwC^Nvpk`RwoJ~2Qeg@gjO^dim z&N^(M1aRrl200un*8DKrKDZ%!DwtblEI27!CAc!1qxnHLqPZZubwk+e%UGC~k-A`* zW0W76{9z7qI?#2JatV%-;Z0$sVu~rk4B%M&#N_Fe7{vgcNGN6qa}&qsCnZmjOPx<= z1dPWnI#S64#VFjzfy3Q3;Igd58Yw(vzK6r*1-8+V!kVfVIFF>kh*Ys5C{F;Gk@^@m zKjB9Z1YJH=K1C&&Rm{;UrV8Lkti&T~1a0LZc1%6)WEBH~{xnADHF-X*>;!VSjt2^~ z#nR$V`#~SEdIQ^l`M}G}O3YVHCDLLFVGy*V5QT;?iyqd5I`)U5&>Us!9>(WtA}prZ z6zW)WiF+|e86l;PIusiJ*HC1JvL)@)VNGaMaOUB|lKnKX_7dwch0Hr<^Pkl_)g)QsuqKdLCkYs` zkOk7=CBXbwCm;EYn1N2C3 zOp%@j4-!hhfzi3<~oefKnZKsQ&-KO+cO|_X52cP)ox7%3*S#y2OEC5o|&W z!-@q;rI6RY?oxw7q_N*aca{;lmIG)ZVM6gOn9a9ThCl+bYRo?e%_V@$VbIV!mphQ+ zu`V@MNE-Hg=oTm$bn8@Ohty%eh1`!VDt(eBU|^8MPa&XG8A1CF>m4N353cR$QsaiK zW50)P86)(0PT(~O6UuKPpy<;Vflf7Ei1ZWEkl@koLmkdlv@2tI`m9Bw=xjn6TgbEA zvNzIxs_84mZ|P?qXnz*ZUrkONj;|4N807Uh+=J$k3H}OJ_AVJzFa3OEH}%W>S1|D~ zg0gK%N126;tW4r}r<#1fJB$eQJ@5McIP;RZtua&`wp)DMwUp6M9cEG?hiLM6?67L; z6+e=Gj0YqxNh4-0Hc@QX@(i3P{;VAgb=Uz4sCeGZ^q8T?YnM)UGapW)D8&jBhpC%KJzT6$07GzW*Fdrc}6 z;C>ue4}BgDzR=bFTC!bJE|*25wWA%+?x?2A7A)&YN4#g3^o~=-lPZ_HfNZClYX|~Z z6~M4^xr4#u5pSRH9otVEoQf7TZyL?dc}-<)7*T41<9r4b`TNi9*)D7v`ehh|#g^Mv z-2DgT7b!7@0-*1^1feWlFNM zTUOG26;Hs=+lO_RGrduW4lWW;nQ&)iC^Mw;M##V)$t!*|SKwwB6}K$OL!1#v8V#A^ zeLB1Fv{631S|!O&!urj$+_}H>ta+1^dSAW;$SfB+|IQ=A}e%DIAVeL@;YFtPE&ESgp3o9uPS=evLf&2v9><&#Dwg_L5 zgKm=JnPxP}eEFxCFcUXJ$ni$uY37gR%F5)`(I^hXyA$ne!hr&+>U>YR8T8_kDFvI+ zqsA+bZ3g?QY0f0E6M82G+K=a))yWYlp=nk?;pJwyb@f_(!ykX(8AO%3I(f|tGM&75 zBj7qfRMMM1)#*ndO@X{0K{2k$qSp_;A1>IZ5q%xx*Li(s8`YpdR zU6nWhY|*Qs`b{Ad*dE;_vUd=O+LIBR=pO>W$oBnYNo`JvezHH}ABWNd?y?72h*^8` zg>N7l;q3#tr)>C#<#%a&9SLT-4(x-5?cdpcG9WleNh;s_akmimf2Smo^plbuEIp#)Zy#d3 zKa+iLb08%l76z#Vj;QzBN5HR1{$2fdkeXEMMeN|(NBG{Y&%v7ezCI%LK}Fp`V$!BD zqEu`jOMBnbFNhBc#}1N`Hjw max) { + Seppuku.INSTANCE.errorChat("Too much input"); + return false; + } + if(split.length < min) { + Seppuku.INSTANCE.errorChat("Not enough input"); + return false; + } + return true; + } + + public boolean clamp(String input, int min) { + String[] split = input.split(" "); + if(split.length < min) { + Seppuku.INSTANCE.errorChat("Not enough input"); + return false; + } + return true; + } + + public boolean equals(String[] list, String input) { + for (String s : list) { + if (s.equalsIgnoreCase(input)) { + return true; + } + } + return false; + } + + public void printUsage() { + final String[] usage = this.getUsage().split("\n"); + Seppuku.INSTANCE.logChat("Usage: "); + + for(String u : usage) { + Seppuku.INSTANCE.logChat(u); + } + } + + public String getDisplayName() { + return displayName; + } + + public void setDisplayName(String displayName) { + this.displayName = displayName; + } + + public String[] getAlias() { + return alias; + } + + public void setAlias(String[] alias) { + this.alias = alias; + } + + public String getDesc() { + return desc; + } + + public void setDesc(String desc) { + this.desc = desc; + } + + public String getUsage() { + return usage; + } + + public void setUsage(String usage) { + this.usage = usage; + } +} diff --git a/src/main/java/me/rigamortis/seppuku/api/config/Configurable.java b/src/main/java/me/rigamortis/seppuku/api/config/Configurable.java new file mode 100644 index 0000000..3b1f830 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/config/Configurable.java @@ -0,0 +1,27 @@ +package me.rigamortis.seppuku.api.config; + +/** + * Author Seth + * 4/18/2019 @ 7:02 AM. + */ +public abstract class Configurable { + + private String path; + + public Configurable(String path) { + this.path = path; + } + + public abstract void load(); + + public abstract void save(); + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/EventCancellable.java b/src/main/java/me/rigamortis/seppuku/api/event/EventCancellable.java new file mode 100644 index 0000000..74699dc --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/EventCancellable.java @@ -0,0 +1,31 @@ +package me.rigamortis.seppuku.api.event; + +/** + * Author Seth + * 4/6/2019 @ 1:27 AM. + */ + +public class EventCancellable extends EventStageable { + + private boolean canceled; + + public EventCancellable() { + } + + public EventCancellable(EventStage stage) { + super(stage); + } + + public EventCancellable(EventStage stage, boolean canceled) { + super(stage); + this.canceled = canceled; + } + + public boolean isCanceled() { + return canceled; + } + + public void setCanceled(boolean canceled) { + this.canceled = canceled; + } +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/EventStageable.java b/src/main/java/me/rigamortis/seppuku/api/event/EventStageable.java new file mode 100644 index 0000000..ebc99b4 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/EventStageable.java @@ -0,0 +1,31 @@ +package me.rigamortis.seppuku.api.event; + +/** + * Author Seth + * 4/5/2019 @ 6:37 PM. + */ +public class EventStageable { + + private EventStage stage; + + public EventStageable() { + + } + + public EventStageable(EventStage stage) { + this.stage = stage; + } + + public EventStage getStage() { + return stage; + } + + public void setStage(EventStage stage) { + this.stage = stage; + } + + public enum EventStage { + PRE, POST + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/client/EventLoad.java b/src/main/java/me/rigamortis/seppuku/api/event/client/EventLoad.java new file mode 100644 index 0000000..9c06702 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/client/EventLoad.java @@ -0,0 +1,7 @@ +package me.rigamortis.seppuku.api.event.client; + +/** + * created by noil on 10/24/2019 at 7:19 PM + */ +public final class EventLoad { +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/client/EventReload.java b/src/main/java/me/rigamortis/seppuku/api/event/client/EventReload.java new file mode 100644 index 0000000..5366f08 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/client/EventReload.java @@ -0,0 +1,8 @@ +package me.rigamortis.seppuku.api.event.client; + +/** + * Author Seth + * 7/19/2019 @ 9:46 PM. + */ +public final class EventReload { +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/client/EventUnload.java b/src/main/java/me/rigamortis/seppuku/api/event/client/EventUnload.java new file mode 100644 index 0000000..1e6b41d --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/client/EventUnload.java @@ -0,0 +1,8 @@ +package me.rigamortis.seppuku.api.event.client; + +/** + * Author Seth + * 7/19/2019 @ 9:44 PM. + */ +public final class EventUnload { +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/command/EventCommandLoad.java b/src/main/java/me/rigamortis/seppuku/api/event/command/EventCommandLoad.java new file mode 100644 index 0000000..f09a283 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/command/EventCommandLoad.java @@ -0,0 +1,24 @@ +package me.rigamortis.seppuku.api.event.command; + +import me.rigamortis.seppuku.api.command.Command; + +/** + * Author Seth + * 6/10/2019 @ 2:37 PM. + */ +public class EventCommandLoad { + + private Command command; + + public EventCommandLoad(Command command) { + this.command = command; + } + + public Command getCommand() { + return command; + } + + public void setCommand(Command command) { + this.command = command; + } +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/entity/EventHorseSaddled.java b/src/main/java/me/rigamortis/seppuku/api/event/entity/EventHorseSaddled.java new file mode 100644 index 0000000..bdcaad2 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/entity/EventHorseSaddled.java @@ -0,0 +1,10 @@ +package me.rigamortis.seppuku.api.event.entity; + +import me.rigamortis.seppuku.api.event.EventCancellable; + +/** + * Author Seth + * 4/9/2019 @ 11:53 AM. + */ +public class EventHorseSaddled extends EventCancellable { +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/entity/EventPigTravel.java b/src/main/java/me/rigamortis/seppuku/api/event/entity/EventPigTravel.java new file mode 100644 index 0000000..d64965d --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/entity/EventPigTravel.java @@ -0,0 +1,10 @@ +package me.rigamortis.seppuku.api.event.entity; + +import me.rigamortis.seppuku.api.event.EventCancellable; + +/** + * Author Seth + * 6/27/2019 @ 6:30 AM. + */ +public class EventPigTravel extends EventCancellable { +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/entity/EventSteerEntity.java b/src/main/java/me/rigamortis/seppuku/api/event/entity/EventSteerEntity.java new file mode 100644 index 0000000..83f4c8f --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/entity/EventSteerEntity.java @@ -0,0 +1,10 @@ +package me.rigamortis.seppuku.api.event.entity; + +import me.rigamortis.seppuku.api.event.EventCancellable; + +/** + * Author Seth + * 4/9/2019 @ 11:42 AM. + */ +public class EventSteerEntity extends EventCancellable { +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/gui/EventBookPage.java b/src/main/java/me/rigamortis/seppuku/api/event/gui/EventBookPage.java new file mode 100644 index 0000000..94761f5 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/gui/EventBookPage.java @@ -0,0 +1,22 @@ +package me.rigamortis.seppuku.api.event.gui; + +/** + * Author Seth + * 4/8/2019 @ 7:59 PM. + */ +public class EventBookPage { + + private String page; + + public EventBookPage(String page) { + this.page = page; + } + + public String getPage() { + return page; + } + + public void setPage(String page) { + this.page = page; + } +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/gui/EventBookTitle.java b/src/main/java/me/rigamortis/seppuku/api/event/gui/EventBookTitle.java new file mode 100644 index 0000000..fd29822 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/gui/EventBookTitle.java @@ -0,0 +1,22 @@ +package me.rigamortis.seppuku.api.event.gui; + +/** + * Author Seth + * 4/8/2019 @ 7:58 PM. + */ +public class EventBookTitle { + + public String title; + + public EventBookTitle(String title) { + this.title = title; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/gui/EventRenderHelmet.java b/src/main/java/me/rigamortis/seppuku/api/event/gui/EventRenderHelmet.java new file mode 100644 index 0000000..c5c0e77 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/gui/EventRenderHelmet.java @@ -0,0 +1,10 @@ +package me.rigamortis.seppuku.api.event.gui; + +import me.rigamortis.seppuku.api.event.EventCancellable; + +/** + * Author Seth + * 4/8/2019 @ 8:19 PM. + */ +public class EventRenderHelmet extends EventCancellable { +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/gui/EventRenderPortal.java b/src/main/java/me/rigamortis/seppuku/api/event/gui/EventRenderPortal.java new file mode 100644 index 0000000..bff7c24 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/gui/EventRenderPortal.java @@ -0,0 +1,10 @@ +package me.rigamortis.seppuku.api.event.gui; + +import me.rigamortis.seppuku.api.event.EventCancellable; + +/** + * Author Seth + * 4/8/2019 @ 8:06 PM. + */ +public class EventRenderPortal extends EventCancellable { +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/gui/EventRenderPotions.java b/src/main/java/me/rigamortis/seppuku/api/event/gui/EventRenderPotions.java new file mode 100644 index 0000000..cb029d6 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/gui/EventRenderPotions.java @@ -0,0 +1,10 @@ +package me.rigamortis.seppuku.api.event.gui; + +import me.rigamortis.seppuku.api.event.EventCancellable; + +/** + * Author Seth + * 4/8/2019 @ 8:19 PM. + */ +public class EventRenderPotions extends EventCancellable { +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/minecraft/EventDisplayGui.java b/src/main/java/me/rigamortis/seppuku/api/event/minecraft/EventDisplayGui.java new file mode 100644 index 0000000..2f9e05c --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/minecraft/EventDisplayGui.java @@ -0,0 +1,25 @@ +package me.rigamortis.seppuku.api.event.minecraft; + +import me.rigamortis.seppuku.api.event.EventCancellable; +import net.minecraft.client.gui.GuiScreen; + +/** + * Author Seth + * 4/6/2019 @ 1:27 AM. + */ +public class EventDisplayGui extends EventCancellable { + + private GuiScreen screen; + + public EventDisplayGui(GuiScreen screen) { + this.screen = screen; + } + + public GuiScreen getScreen() { + return screen; + } + + public void setScreen(GuiScreen screen) { + this.screen = screen; + } +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/minecraft/EventKeyPress.java b/src/main/java/me/rigamortis/seppuku/api/event/minecraft/EventKeyPress.java new file mode 100644 index 0000000..83b4852 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/minecraft/EventKeyPress.java @@ -0,0 +1,22 @@ +package me.rigamortis.seppuku.api.event.minecraft; + +/** + * Author Seth + * 4/6/2019 @ 1:18 AM. + */ +public class EventKeyPress { + + private int key; + + public EventKeyPress(int key) { + this.key = key; + } + + public int getKey() { + return key; + } + + public void setKey(int key) { + this.key = key; + } +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/minecraft/EventRunTick.java b/src/main/java/me/rigamortis/seppuku/api/event/minecraft/EventRunTick.java new file mode 100644 index 0000000..5e05b98 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/minecraft/EventRunTick.java @@ -0,0 +1,15 @@ +package me.rigamortis.seppuku.api.event.minecraft; + +import me.rigamortis.seppuku.api.event.EventStageable; + +/** + * Author Seth + * 4/5/2019 @ 6:24 PM. + */ +public class EventRunTick extends EventStageable { + + public EventRunTick(EventStage stage) { + super(stage); + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/minecraft/EventUpdateFramebufferSize.java b/src/main/java/me/rigamortis/seppuku/api/event/minecraft/EventUpdateFramebufferSize.java new file mode 100644 index 0000000..5ecb2b3 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/minecraft/EventUpdateFramebufferSize.java @@ -0,0 +1,9 @@ +package me.rigamortis.seppuku.api.event.minecraft; + +/** + * Author Seth + * 4/4/2019 @ 11:41 PM. + */ +public class EventUpdateFramebufferSize { + +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/module/EventModuleLoad.java b/src/main/java/me/rigamortis/seppuku/api/event/module/EventModuleLoad.java new file mode 100644 index 0000000..db64688 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/module/EventModuleLoad.java @@ -0,0 +1,24 @@ +package me.rigamortis.seppuku.api.event.module; + +import me.rigamortis.seppuku.api.module.Module; + +/** + * Author Seth + * 6/10/2019 @ 2:36 PM. + */ +public class EventModuleLoad { + + private Module mod; + + public EventModuleLoad(Module mod) { + this.mod = mod; + } + + public Module getMod() { + return mod; + } + + public void setMod(Module mod) { + this.mod = mod; + } +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/network/EventReceivePacket.java b/src/main/java/me/rigamortis/seppuku/api/event/network/EventReceivePacket.java new file mode 100644 index 0000000..edea298 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/network/EventReceivePacket.java @@ -0,0 +1,26 @@ +package me.rigamortis.seppuku.api.event.network; + +import me.rigamortis.seppuku.api.event.EventCancellable; +import net.minecraft.network.Packet; + +/** + * Author Seth + * 4/6/2019 @ 1:45 PM. + */ +public class EventReceivePacket extends EventCancellable { + + private Packet packet; + + public EventReceivePacket(EventStage stage, Packet packet) { + super(stage); + this.packet = packet; + } + + public Packet getPacket() { + return packet; + } + + public void setPacket(Packet packet) { + this.packet = packet; + } +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/network/EventSendPacket.java b/src/main/java/me/rigamortis/seppuku/api/event/network/EventSendPacket.java new file mode 100644 index 0000000..7c5fd54 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/network/EventSendPacket.java @@ -0,0 +1,26 @@ +package me.rigamortis.seppuku.api.event.network; + +import me.rigamortis.seppuku.api.event.EventCancellable; +import net.minecraft.network.Packet; + +/** + * Author Seth + * 4/6/2019 @ 1:42 PM. + */ +public final class EventSendPacket extends EventCancellable { + + private Packet packet; + + public EventSendPacket(EventStage stage, Packet packet) { + super(stage); + this.packet = packet; + } + + public Packet getPacket() { + return packet; + } + + public void setPacket(Packet packet) { + this.packet = packet; + } +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/player/EventApplyCollision.java b/src/main/java/me/rigamortis/seppuku/api/event/player/EventApplyCollision.java new file mode 100644 index 0000000..463df5a --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/player/EventApplyCollision.java @@ -0,0 +1,10 @@ +package me.rigamortis.seppuku.api.event.player; + +import me.rigamortis.seppuku.api.event.EventCancellable; + +/** + * Author Seth + * 4/8/2019 @ 6:50 PM. + */ +public class EventApplyCollision extends EventCancellable { +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/player/EventClickBlock.java b/src/main/java/me/rigamortis/seppuku/api/event/player/EventClickBlock.java new file mode 100644 index 0000000..775dd2a --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/player/EventClickBlock.java @@ -0,0 +1,36 @@ +package me.rigamortis.seppuku.api.event.player; + +import me.rigamortis.seppuku.api.event.EventCancellable; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; + +/** + * Author Seth + * 4/6/2019 @ 6:20 PM. + */ +public class EventClickBlock extends EventCancellable { + + private BlockPos pos; + private EnumFacing face; + + public EventClickBlock(BlockPos pos, EnumFacing face) { + this.pos = pos; + this.face = face; + } + + public BlockPos getPos() { + return pos; + } + + public void setPos(BlockPos pos) { + this.pos = pos; + } + + public EnumFacing getFace() { + return face; + } + + public void setFace(EnumFacing face) { + this.face = face; + } +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/player/EventCloseScreen.java b/src/main/java/me/rigamortis/seppuku/api/event/player/EventCloseScreen.java new file mode 100644 index 0000000..8ca6291 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/player/EventCloseScreen.java @@ -0,0 +1,10 @@ +package me.rigamortis.seppuku.api.event.player; + +import me.rigamortis.seppuku.api.event.EventCancellable; + +/** + * Author Seth + * 4/8/2019 @ 4:34 PM. + */ +public class EventCloseScreen extends EventCancellable { +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/player/EventDestroyBlock.java b/src/main/java/me/rigamortis/seppuku/api/event/player/EventDestroyBlock.java new file mode 100644 index 0000000..9372eb3 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/player/EventDestroyBlock.java @@ -0,0 +1,25 @@ +package me.rigamortis.seppuku.api.event.player; + +import me.rigamortis.seppuku.api.event.EventCancellable; +import net.minecraft.util.math.BlockPos; + +/** + * Author Seth + * 4/6/2019 @ 6:16 PM. + */ +public class EventDestroyBlock extends EventCancellable { + + private BlockPos pos; + + public EventDestroyBlock(BlockPos pos) { + this.pos = pos; + } + + public BlockPos getPos() { + return pos; + } + + public void setPos(BlockPos pos) { + this.pos = pos; + } +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/player/EventExtendedReach.java b/src/main/java/me/rigamortis/seppuku/api/event/player/EventExtendedReach.java new file mode 100644 index 0000000..880b682 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/player/EventExtendedReach.java @@ -0,0 +1,10 @@ +package me.rigamortis.seppuku.api.event.player; + +import me.rigamortis.seppuku.api.event.EventCancellable; + +/** + * Author Seth + * 4/7/2019 @ 3:07 PM. + */ +public class EventExtendedReach extends EventCancellable { +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/player/EventGetBlockReachDistance.java b/src/main/java/me/rigamortis/seppuku/api/event/player/EventGetBlockReachDistance.java new file mode 100644 index 0000000..4155ebd --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/player/EventGetBlockReachDistance.java @@ -0,0 +1,25 @@ +package me.rigamortis.seppuku.api.event.player; + +/** + * Author Seth + * 4/6/2019 @ 6:35 PM. + */ +public class EventGetBlockReachDistance { + + private float distance; + + public EventGetBlockReachDistance() { + } + + public EventGetBlockReachDistance(float distance) { + this.distance = distance; + } + + public float getDistance() { + return distance; + } + + public void setDistance(float distance) { + this.distance = distance; + } +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/player/EventHittingPosition.java b/src/main/java/me/rigamortis/seppuku/api/event/player/EventHittingPosition.java new file mode 100644 index 0000000..5bb49c2 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/player/EventHittingPosition.java @@ -0,0 +1,25 @@ +package me.rigamortis.seppuku.api.event.player; + +import me.rigamortis.seppuku.api.event.EventCancellable; +import net.minecraft.util.math.BlockPos; + +/** + * Author Seth + * 4/24/2019 @ 1:36 PM. + */ +public class EventHittingPosition extends EventCancellable { + + private BlockPos blockPos; + + public EventHittingPosition(BlockPos blockPos) { + this.blockPos = blockPos; + } + + public BlockPos getBlockPos() { + return blockPos; + } + + public void setBlockPos(BlockPos blockPos) { + this.blockPos = blockPos; + } +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/player/EventMove.java b/src/main/java/me/rigamortis/seppuku/api/event/player/EventMove.java new file mode 100644 index 0000000..68d1baf --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/player/EventMove.java @@ -0,0 +1,56 @@ +package me.rigamortis.seppuku.api.event.player; + +import me.rigamortis.seppuku.api.event.EventCancellable; +import net.minecraft.entity.MoverType; + +/** + * Author Seth + * 4/25/2019 @ 7:01 PM. + */ +public class EventMove extends EventCancellable { + + private MoverType moverType; + + private double x; + private double y; + private double z; + + public EventMove(MoverType moverType, double x, double y, double z) { + this.moverType = moverType; + this.x = x; + this.y = y; + this.z = z; + } + + public MoverType getMoverType() { + return moverType; + } + + public void setMoverType(MoverType moverType) { + this.moverType = moverType; + } + + public double getX() { + return x; + } + + public void setX(double x) { + this.x = x; + } + + public double getY() { + return y; + } + + public void setY(double y) { + this.y = y; + } + + public double getZ() { + return z; + } + + public void setZ(double z) { + this.z = z; + } +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/player/EventPlayerDamageBlock.java b/src/main/java/me/rigamortis/seppuku/api/event/player/EventPlayerDamageBlock.java new file mode 100644 index 0000000..d4bafc7 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/player/EventPlayerDamageBlock.java @@ -0,0 +1,36 @@ +package me.rigamortis.seppuku.api.event.player; + +import me.rigamortis.seppuku.api.event.EventCancellable; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; + +/** + * Author Seth + * 4/6/2019 @ 6:31 PM. + */ +public class EventPlayerDamageBlock extends EventCancellable { + + private BlockPos pos; + private EnumFacing face; + + public EventPlayerDamageBlock(BlockPos pos, EnumFacing face) { + this.pos = pos; + this.face = face; + } + + public BlockPos getPos() { + return pos; + } + + public void setPos(BlockPos pos) { + this.pos = pos; + } + + public EnumFacing getFace() { + return face; + } + + public void setFace(EnumFacing face) { + this.face = face; + } +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/player/EventPlayerJoin.java b/src/main/java/me/rigamortis/seppuku/api/event/player/EventPlayerJoin.java new file mode 100644 index 0000000..15bd6d7 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/player/EventPlayerJoin.java @@ -0,0 +1,32 @@ +package me.rigamortis.seppuku.api.event.player; + +/** + * Author Seth + * 7/23/2019 @ 7:41 AM. + */ +public class EventPlayerJoin { + + private String name; + private String uuid; + + public EventPlayerJoin(String name, String uuid) { + this.name = name; + this.uuid = uuid; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/player/EventPlayerLeave.java b/src/main/java/me/rigamortis/seppuku/api/event/player/EventPlayerLeave.java new file mode 100644 index 0000000..4b79171 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/player/EventPlayerLeave.java @@ -0,0 +1,33 @@ +package me.rigamortis.seppuku.api.event.player; + +/** + * Author Seth + * 7/23/2019 @ 7:41 AM. + */ +public class EventPlayerLeave { + + private String name; + private String uuid; + + public EventPlayerLeave(String name, String uuid) { + this.name = name; + this.uuid = uuid; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/player/EventPlayerUpdate.java b/src/main/java/me/rigamortis/seppuku/api/event/player/EventPlayerUpdate.java new file mode 100644 index 0000000..d3bf308 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/player/EventPlayerUpdate.java @@ -0,0 +1,15 @@ +package me.rigamortis.seppuku.api.event.player; + +import me.rigamortis.seppuku.api.event.EventCancellable; + +/** + * Author Seth + * 4/8/2019 @ 3:03 AM. + */ +public class EventPlayerUpdate extends EventCancellable { + + public EventPlayerUpdate(EventStage stage) { + super(stage); + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/player/EventPushOutOfBlocks.java b/src/main/java/me/rigamortis/seppuku/api/event/player/EventPushOutOfBlocks.java new file mode 100644 index 0000000..c3a9f03 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/player/EventPushOutOfBlocks.java @@ -0,0 +1,10 @@ +package me.rigamortis.seppuku.api.event.player; + +import me.rigamortis.seppuku.api.event.EventCancellable; + +/** + * Author Seth + * 4/8/2019 @ 4:39 PM. + */ +public class EventPushOutOfBlocks extends EventCancellable { +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/player/EventPushedByWater.java b/src/main/java/me/rigamortis/seppuku/api/event/player/EventPushedByWater.java new file mode 100644 index 0000000..ac81a0b --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/player/EventPushedByWater.java @@ -0,0 +1,10 @@ +package me.rigamortis.seppuku.api.event.player; + +import me.rigamortis.seppuku.api.event.EventCancellable; + +/** + * Author Seth + * 4/8/2019 @ 6:50 PM. + */ +public class EventPushedByWater extends EventCancellable { +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/player/EventResetBlockRemoving.java b/src/main/java/me/rigamortis/seppuku/api/event/player/EventResetBlockRemoving.java new file mode 100644 index 0000000..da7e95e --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/player/EventResetBlockRemoving.java @@ -0,0 +1,10 @@ +package me.rigamortis.seppuku.api.event.player; + +import me.rigamortis.seppuku.api.event.EventCancellable; + +/** + * Author Seth + * 4/6/2019 @ 6:27 PM. + */ +public class EventResetBlockRemoving extends EventCancellable { +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/player/EventRightClick.java b/src/main/java/me/rigamortis/seppuku/api/event/player/EventRightClick.java new file mode 100644 index 0000000..00c9597 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/player/EventRightClick.java @@ -0,0 +1,25 @@ +package me.rigamortis.seppuku.api.event.player; + +import me.rigamortis.seppuku.api.event.EventCancellable; +import net.minecraft.util.EnumHand; + +/** + * Author Seth + * 4/7/2019 @ 4:51 PM. + */ +public class EventRightClick extends EventCancellable { + + private EnumHand hand; + + public EventRightClick(EnumHand hand) { + this.hand = hand; + } + + public EnumHand getHand() { + return hand; + } + + public void setHand(EnumHand hand) { + this.hand = hand; + } +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/player/EventRightClickBlock.java b/src/main/java/me/rigamortis/seppuku/api/event/player/EventRightClickBlock.java new file mode 100644 index 0000000..e9a33c6 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/player/EventRightClickBlock.java @@ -0,0 +1,58 @@ +package me.rigamortis.seppuku.api.event.player; + +import me.rigamortis.seppuku.api.event.EventCancellable; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.EnumHand; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; + +/** + * Author Seth + * 4/7/2019 @ 3:18 PM. + */ +public class EventRightClickBlock extends EventCancellable { + + private BlockPos pos; + private EnumFacing facing; + private Vec3d vec; + private EnumHand hand; + + public EventRightClickBlock(BlockPos pos, EnumFacing facing, Vec3d vec, EnumHand hand) { + this.pos = pos; + this.facing = facing; + this.vec = vec; + this.hand = hand; + } + + public BlockPos getPos() { + return pos; + } + + public void setPos(BlockPos pos) { + this.pos = pos; + } + + public EnumFacing getFacing() { + return facing; + } + + public void setFacing(EnumFacing facing) { + this.facing = facing; + } + + public Vec3d getVec() { + return vec; + } + + public void setVec(Vec3d vec) { + this.vec = vec; + } + + public EnumHand getHand() { + return hand; + } + + public void setHand(EnumHand hand) { + this.hand = hand; + } +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/player/EventSendChatMessage.java b/src/main/java/me/rigamortis/seppuku/api/event/player/EventSendChatMessage.java new file mode 100644 index 0000000..bf3e620 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/player/EventSendChatMessage.java @@ -0,0 +1,24 @@ +package me.rigamortis.seppuku.api.event.player; + +import me.rigamortis.seppuku.api.event.EventCancellable; + +/** + * Author Seth + * 4/8/2019 @ 3:57 AM. + */ +public class EventSendChatMessage extends EventCancellable { + + private String message; + + public EventSendChatMessage(String message) { + this.message = message; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/player/EventStep.java b/src/main/java/me/rigamortis/seppuku/api/event/player/EventStep.java new file mode 100644 index 0000000..f084467 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/player/EventStep.java @@ -0,0 +1,8 @@ +package me.rigamortis.seppuku.api.event.player; + +/** + * Author Seth + * 5/24/2019 @ 3:47 AM. + */ +public class EventStep { +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/player/EventSwingArm.java b/src/main/java/me/rigamortis/seppuku/api/event/player/EventSwingArm.java new file mode 100644 index 0000000..044cccd --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/player/EventSwingArm.java @@ -0,0 +1,25 @@ +package me.rigamortis.seppuku.api.event.player; + +import me.rigamortis.seppuku.api.event.EventCancellable; +import net.minecraft.util.EnumHand; + +/** + * Author Seth + * 4/8/2019 @ 3:57 AM. + */ +public class EventSwingArm extends EventCancellable { + + private EnumHand hand; + + public EventSwingArm(EnumHand hand) { + this.hand = hand; + } + + public EnumHand getHand() { + return hand; + } + + public void setHand(EnumHand hand) { + this.hand = hand; + } +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/player/EventUpdateInput.java b/src/main/java/me/rigamortis/seppuku/api/event/player/EventUpdateInput.java new file mode 100644 index 0000000..ef8500d --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/player/EventUpdateInput.java @@ -0,0 +1,8 @@ +package me.rigamortis.seppuku.api.event.player; + +/** + * Author Seth + * 4/10/2019 @ 3:15 AM. + */ +public class EventUpdateInput { +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/player/EventUpdateWalkingPlayer.java b/src/main/java/me/rigamortis/seppuku/api/event/player/EventUpdateWalkingPlayer.java new file mode 100644 index 0000000..5d33098 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/player/EventUpdateWalkingPlayer.java @@ -0,0 +1,15 @@ +package me.rigamortis.seppuku.api.event.player; + +import me.rigamortis.seppuku.api.event.EventCancellable; + +/** + * Author Seth + * 4/8/2019 @ 3:50 AM. + */ +public class EventUpdateWalkingPlayer extends EventCancellable { + + public EventUpdateWalkingPlayer(EventStage stage) { + super(stage); + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/render/EventHurtCamEffect.java b/src/main/java/me/rigamortis/seppuku/api/event/render/EventHurtCamEffect.java new file mode 100644 index 0000000..50cfd00 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/render/EventHurtCamEffect.java @@ -0,0 +1,10 @@ +package me.rigamortis.seppuku.api.event.render; + +import me.rigamortis.seppuku.api.event.EventCancellable; + +/** + * Author Seth + * 4/9/2019 @ 12:41 AM. + */ +public class EventHurtCamEffect extends EventCancellable { +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/render/EventOrientCamera.java b/src/main/java/me/rigamortis/seppuku/api/event/render/EventOrientCamera.java new file mode 100644 index 0000000..a43bc80 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/render/EventOrientCamera.java @@ -0,0 +1,10 @@ +package me.rigamortis.seppuku.api.event.render; + +import me.rigamortis.seppuku.api.event.EventCancellable; + +/** + * Author Seth + * 7/22/2019 @ 8:26 AM. + */ +public class EventOrientCamera extends EventCancellable { +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/render/EventRender2D.java b/src/main/java/me/rigamortis/seppuku/api/event/render/EventRender2D.java new file mode 100644 index 0000000..bb53620 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/render/EventRender2D.java @@ -0,0 +1,34 @@ +package me.rigamortis.seppuku.api.event.render; + +import net.minecraft.client.gui.ScaledResolution; + +/** + * Author Seth + * 4/6/2019 @ 1:08 PM. + */ +public class EventRender2D { + + private float partialTicks; + private ScaledResolution scaledResolution; + + public EventRender2D(float partialTicks, ScaledResolution scaledResolution) { + this.partialTicks = partialTicks; + this.scaledResolution = scaledResolution; + } + + public float getPartialTicks() { + return partialTicks; + } + + public void setPartialTicks(float partialTicks) { + this.partialTicks = partialTicks; + } + + public ScaledResolution getScaledResolution() { + return scaledResolution; + } + + public void setScaledResolution(ScaledResolution scaledResolution) { + this.scaledResolution = scaledResolution; + } +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/render/EventRender3D.java b/src/main/java/me/rigamortis/seppuku/api/event/render/EventRender3D.java new file mode 100644 index 0000000..7c8fe2d --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/render/EventRender3D.java @@ -0,0 +1,22 @@ +package me.rigamortis.seppuku.api.event.render; + +/** + * Author Seth + * 4/6/2019 @ 1:20 PM. + */ +public class EventRender3D { + + private float partialTicks; + + public EventRender3D(float partialTicks) { + this.partialTicks = partialTicks; + } + + public float getPartialTicks() { + return partialTicks; + } + + public void setPartialTicks(float partialTicks) { + this.partialTicks = partialTicks; + } +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/render/EventRenderBlockModel.java b/src/main/java/me/rigamortis/seppuku/api/event/render/EventRenderBlockModel.java new file mode 100644 index 0000000..dec4fcd --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/render/EventRenderBlockModel.java @@ -0,0 +1,98 @@ +package me.rigamortis.seppuku.api.event.render; + +import me.rigamortis.seppuku.api.event.EventCancellable; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.renderer.BufferBuilder; +import net.minecraft.client.renderer.block.model.IBakedModel; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IBlockAccess; + +/** + * Author Seth + * 4/10/2019 @ 4:10 PM. + */ +public class EventRenderBlockModel extends EventCancellable { + + private IBlockAccess blockAccess; + private IBakedModel bakedModel; + private IBlockState blockState; + private BlockPos blockPos; + private BufferBuilder bufferBuilder; + private boolean checkSides; + private long rand; + private boolean renderable; + + public EventRenderBlockModel(IBlockAccess blockAccess, IBakedModel bakedModel, IBlockState blockState, BlockPos blockPos, BufferBuilder bufferBuilder, boolean checkSides, long rand) { + this.blockAccess = blockAccess; + this.bakedModel = bakedModel; + this.blockState = blockState; + this.blockPos = blockPos; + this.bufferBuilder = bufferBuilder; + this.checkSides = checkSides; + this.rand = rand; + } + + public IBlockAccess getBlockAccess() { + return blockAccess; + } + + public void setBlockAccess(IBlockAccess blockAccess) { + this.blockAccess = blockAccess; + } + + public IBakedModel getBakedModel() { + return bakedModel; + } + + public void setBakedModel(IBakedModel bakedModel) { + this.bakedModel = bakedModel; + } + + public IBlockState getBlockState() { + return blockState; + } + + public void setBlockState(IBlockState blockState) { + this.blockState = blockState; + } + + public BlockPos getBlockPos() { + return blockPos; + } + + public void setBlockPos(BlockPos blockPos) { + this.blockPos = blockPos; + } + + public BufferBuilder getBufferBuilder() { + return bufferBuilder; + } + + public void setBufferBuilder(BufferBuilder bufferBuilder) { + this.bufferBuilder = bufferBuilder; + } + + public boolean isCheckSides() { + return checkSides; + } + + public void setCheckSides(boolean checkSides) { + this.checkSides = checkSides; + } + + public long getRand() { + return rand; + } + + public void setRand(long rand) { + this.rand = rand; + } + + public boolean isRenderable() { + return renderable; + } + + public void setRenderable(boolean renderable) { + this.renderable = renderable; + } +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/render/EventRenderBlockSide.java b/src/main/java/me/rigamortis/seppuku/api/event/render/EventRenderBlockSide.java new file mode 100644 index 0000000..9ecb857 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/render/EventRenderBlockSide.java @@ -0,0 +1,34 @@ +package me.rigamortis.seppuku.api.event.render; + +import me.rigamortis.seppuku.api.event.EventCancellable; +import net.minecraft.block.Block; + +/** + * Author Seth + * 4/9/2019 @ 12:21 PM. + */ +public class EventRenderBlockSide extends EventCancellable { + + private Block block; + private boolean renderable; + + public EventRenderBlockSide(Block block) { + this.block = block; + } + + public Block getBlock() { + return block; + } + + public void setBlock(Block block) { + this.block = block; + } + + public boolean isRenderable() { + return renderable; + } + + public void setRenderable(boolean renderable) { + this.renderable = renderable; + } +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/render/EventRenderBossHealth.java b/src/main/java/me/rigamortis/seppuku/api/event/render/EventRenderBossHealth.java new file mode 100644 index 0000000..20b4b31 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/render/EventRenderBossHealth.java @@ -0,0 +1,10 @@ +package me.rigamortis.seppuku.api.event.render; + +import me.rigamortis.seppuku.api.event.EventCancellable; + +/** + * Author Seth + * 9/30/2019 @ 6:45 AM. + */ +public class EventRenderBossHealth extends EventCancellable { +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/render/EventRenderEntity.java b/src/main/java/me/rigamortis/seppuku/api/event/render/EventRenderEntity.java new file mode 100644 index 0000000..ebaa745 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/render/EventRenderEntity.java @@ -0,0 +1,76 @@ +package me.rigamortis.seppuku.api.event.render; + +import me.rigamortis.seppuku.api.event.EventCancellable; +import net.minecraft.entity.Entity; + +/** + * Author Seth + * 4/9/2019 @ 10:43 AM. + */ +public class EventRenderEntity extends EventCancellable { + + private Entity entity; + private double x; + private double y; + private double z; + private float yaw; + private float partialTicks; + + public EventRenderEntity(EventStage stage, Entity entity, double x, double y, double z, float yaw, float partialTicks) { + super(stage); + this.entity = entity; + this.x = x; + this.y = y; + this.z = z; + this.yaw = yaw; + this.partialTicks = partialTicks; + } + + public Entity getEntity() { + return entity; + } + + public void setEntity(Entity entity) { + this.entity = entity; + } + + public double getX() { + return x; + } + + public void setX(double x) { + this.x = x; + } + + public double getY() { + return y; + } + + public void setY(double y) { + this.y = y; + } + + public double getZ() { + return z; + } + + public void setZ(double z) { + this.z = z; + } + + public float getYaw() { + return yaw; + } + + public void setYaw(float yaw) { + this.yaw = yaw; + } + + public float getPartialTicks() { + return partialTicks; + } + + public void setPartialTicks(float partialTicks) { + this.partialTicks = partialTicks; + } +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/render/EventRenderFluid.java b/src/main/java/me/rigamortis/seppuku/api/event/render/EventRenderFluid.java new file mode 100644 index 0000000..c013e8a --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/render/EventRenderFluid.java @@ -0,0 +1,67 @@ +package me.rigamortis.seppuku.api.event.render; + +import me.rigamortis.seppuku.api.event.EventCancellable; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.renderer.BufferBuilder; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IBlockAccess; + +/** + * Author Seth + * 4/11/2019 @ 3:21 AM. + */ +public class EventRenderFluid extends EventCancellable { + + private IBlockAccess blockAccess; + private IBlockState blockState; + private BlockPos blockPos; + private BufferBuilder bufferBuilder; + private boolean renderable; + + public EventRenderFluid(IBlockAccess blockAccess, IBlockState blockState, BlockPos blockPos, BufferBuilder bufferBuilder) { + this.blockAccess = blockAccess; + this.blockState = blockState; + this.blockPos = blockPos; + this.bufferBuilder = bufferBuilder; + } + + public IBlockAccess getBlockAccess() { + return blockAccess; + } + + public void setBlockAccess(IBlockAccess blockAccess) { + this.blockAccess = blockAccess; + } + + public IBlockState getBlockState() { + return blockState; + } + + public void setBlockState(IBlockState blockState) { + this.blockState = blockState; + } + + public BlockPos getBlockPos() { + return blockPos; + } + + public void setBlockPos(BlockPos blockPos) { + this.blockPos = blockPos; + } + + public BufferBuilder getBufferBuilder() { + return bufferBuilder; + } + + public void setBufferBuilder(BufferBuilder bufferBuilder) { + this.bufferBuilder = bufferBuilder; + } + + public boolean isRenderable() { + return renderable; + } + + public void setRenderable(boolean renderable) { + this.renderable = renderable; + } +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/render/EventRenderLivingEntity.java b/src/main/java/me/rigamortis/seppuku/api/event/render/EventRenderLivingEntity.java new file mode 100644 index 0000000..d49b5e9 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/render/EventRenderLivingEntity.java @@ -0,0 +1,26 @@ +package me.rigamortis.seppuku.api.event.render; + +import me.rigamortis.seppuku.api.event.EventCancellable; +import net.minecraft.entity.EntityLivingBase; + +/** + * Author Seth + * 4/23/2019 @ 12:41 PM. + */ +public class EventRenderLivingEntity extends EventCancellable { + + private EntityLivingBase entity; + + public EventRenderLivingEntity(EventStage stage, EntityLivingBase entity) { + super(stage); + this.entity = entity; + } + + public EntityLivingBase getEntity() { + return entity; + } + + public void setEntity(EntityLivingBase entity) { + this.entity = entity; + } +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/render/EventRenderName.java b/src/main/java/me/rigamortis/seppuku/api/event/render/EventRenderName.java new file mode 100644 index 0000000..f417353 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/render/EventRenderName.java @@ -0,0 +1,25 @@ +package me.rigamortis.seppuku.api.event.render; + +import me.rigamortis.seppuku.api.event.EventCancellable; +import net.minecraft.entity.EntityLivingBase; + +/** + * Author Seth + * 4/9/2019 @ 11:01 AM. + */ +public class EventRenderName extends EventCancellable { + + private EntityLivingBase entity; + + public EventRenderName(EntityLivingBase entity) { + this.entity = entity; + } + + public EntityLivingBase getEntity() { + return entity; + } + + public void setEntity(EntityLivingBase entity) { + this.entity = entity; + } +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/render/EventRenderOverlay.java b/src/main/java/me/rigamortis/seppuku/api/event/render/EventRenderOverlay.java new file mode 100644 index 0000000..977fd2d --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/render/EventRenderOverlay.java @@ -0,0 +1,31 @@ +package me.rigamortis.seppuku.api.event.render; + +import me.rigamortis.seppuku.api.event.EventCancellable; + +/** + * Author Seth + * 4/9/2019 @ 12:33 AM. + */ +public class EventRenderOverlay extends EventCancellable { + + private OverlayType type; + + public EventRenderOverlay(OverlayType type) { + this.type = type; + } + + public OverlayType getType() { + return type; + } + + public void setType(OverlayType type) { + this.type = type; + } + + public enum OverlayType { + BLOCK, + LIQUID, + FIRE + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/world/EventAddCollisionBox.java b/src/main/java/me/rigamortis/seppuku/api/event/world/EventAddCollisionBox.java new file mode 100644 index 0000000..94409dc --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/world/EventAddCollisionBox.java @@ -0,0 +1,36 @@ +package me.rigamortis.seppuku.api.event.world; + +import me.rigamortis.seppuku.api.event.EventCancellable; +import net.minecraft.entity.Entity; +import net.minecraft.util.math.BlockPos; + +/** + * Author Seth + * 4/10/2019 @ 2:08 AM. + */ +public class EventAddCollisionBox extends EventCancellable { + + private BlockPos pos; + private Entity entity; + + public EventAddCollisionBox(BlockPos pos, Entity entity) { + this.pos = pos; + this.entity = entity; + } + + public BlockPos getPos() { + return pos; + } + + public void setPos(BlockPos pos) { + this.pos = pos; + } + + public Entity getEntity() { + return entity; + } + + public void setEntity(Entity entity) { + this.entity = entity; + } +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/world/EventCanCollide.java b/src/main/java/me/rigamortis/seppuku/api/event/world/EventCanCollide.java new file mode 100644 index 0000000..874b00d --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/world/EventCanCollide.java @@ -0,0 +1,10 @@ +package me.rigamortis.seppuku.api.event.world; + +import me.rigamortis.seppuku.api.event.EventCancellable; + +/** + * Author Seth + * 6/5/2019 @ 10:52 PM. + */ +public class EventCanCollide extends EventCancellable { +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/world/EventCollideSoulSand.java b/src/main/java/me/rigamortis/seppuku/api/event/world/EventCollideSoulSand.java new file mode 100644 index 0000000..cc925a5 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/world/EventCollideSoulSand.java @@ -0,0 +1,10 @@ +package me.rigamortis.seppuku.api.event.world; + +import me.rigamortis.seppuku.api.event.EventCancellable; + +/** + * Author Seth + * 4/10/2019 @ 2:53 AM. + */ +public class EventCollideSoulSand extends EventCancellable { +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/world/EventFoliageColor.java b/src/main/java/me/rigamortis/seppuku/api/event/world/EventFoliageColor.java new file mode 100644 index 0000000..3bf5add --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/world/EventFoliageColor.java @@ -0,0 +1,23 @@ +package me.rigamortis.seppuku.api.event.world; + +import me.rigamortis.seppuku.api.event.EventCancellable; + +/** + * Author Seth + * 8/11/2019 @ 2:44 AM. + */ +public class EventFoliageColor extends EventCancellable { + + private int color; + + public EventFoliageColor() { + } + + public int getColor() { + return color; + } + + public void setColor(int color) { + this.color = color; + } +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/world/EventGetBlockLayer.java b/src/main/java/me/rigamortis/seppuku/api/event/world/EventGetBlockLayer.java new file mode 100644 index 0000000..08b5e54 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/world/EventGetBlockLayer.java @@ -0,0 +1,36 @@ +package me.rigamortis.seppuku.api.event.world; + +import me.rigamortis.seppuku.api.event.EventCancellable; +import net.minecraft.block.Block; +import net.minecraft.util.BlockRenderLayer; + +/** + * Author Seth + * 4/9/2019 @ 1:54 PM. + */ +public class EventGetBlockLayer extends EventCancellable { + + private Block block; + private BlockRenderLayer layer; + + public EventGetBlockLayer(Block block) { + this.block = block; + } + + public Block getBlock() { + return block; + } + + public void setBlock(Block block) { + this.block = block; + } + + public BlockRenderLayer getLayer() { + return layer; + } + + public void setLayer(BlockRenderLayer layer) { + this.layer = layer; + } +} + diff --git a/src/main/java/me/rigamortis/seppuku/api/event/world/EventGrassColor.java b/src/main/java/me/rigamortis/seppuku/api/event/world/EventGrassColor.java new file mode 100644 index 0000000..c53bce0 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/world/EventGrassColor.java @@ -0,0 +1,23 @@ +package me.rigamortis.seppuku.api.event.world; + +import me.rigamortis.seppuku.api.event.EventCancellable; + +/** + * Author Seth + * 8/11/2019 @ 2:10 AM. + */ +public class EventGrassColor extends EventCancellable { + + private int color; + + public EventGrassColor() { + } + + public int getColor() { + return color; + } + + public void setColor(int color) { + this.color = color; + } +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/world/EventLandOnSlime.java b/src/main/java/me/rigamortis/seppuku/api/event/world/EventLandOnSlime.java new file mode 100644 index 0000000..c6cdec7 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/world/EventLandOnSlime.java @@ -0,0 +1,10 @@ +package me.rigamortis.seppuku.api.event.world; + +import me.rigamortis.seppuku.api.event.EventCancellable; + +/** + * Author Seth + * 4/16/2019 @ 3:54 AM. + */ +public class EventLandOnSlime extends EventCancellable { +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/world/EventLightUpdate.java b/src/main/java/me/rigamortis/seppuku/api/event/world/EventLightUpdate.java new file mode 100644 index 0000000..a0f960a --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/world/EventLightUpdate.java @@ -0,0 +1,15 @@ +package me.rigamortis.seppuku.api.event.world; + +import me.rigamortis.seppuku.api.event.EventCancellable; + +/** + * Author Seth + * 4/6/2019 @ 1:28 PM. + */ +public class EventLightUpdate extends EventCancellable { + + public EventLightUpdate() { + + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/world/EventLiquidCollisionBB.java b/src/main/java/me/rigamortis/seppuku/api/event/world/EventLiquidCollisionBB.java new file mode 100644 index 0000000..88c4455 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/world/EventLiquidCollisionBB.java @@ -0,0 +1,39 @@ +package me.rigamortis.seppuku.api.event.world; + +import me.rigamortis.seppuku.api.event.EventCancellable; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; + +/** + * Author Seth + * 4/16/2019 @ 7:37 AM. + */ +public class EventLiquidCollisionBB extends EventCancellable { + + private AxisAlignedBB boundingBox; + private BlockPos blockPos; + + public EventLiquidCollisionBB() { + + } + + public EventLiquidCollisionBB(BlockPos blockPos) { + this.blockPos = blockPos; + } + + public AxisAlignedBB getBoundingBox() { + return boundingBox; + } + + public void setBoundingBox(AxisAlignedBB boundingBox) { + this.boundingBox = boundingBox; + } + + public BlockPos getBlockPos() { + return blockPos; + } + + public void setBlockPos(BlockPos blockPos) { + this.blockPos = blockPos; + } +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/world/EventSetOpaqueCube.java b/src/main/java/me/rigamortis/seppuku/api/event/world/EventSetOpaqueCube.java new file mode 100644 index 0000000..8395f29 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/world/EventSetOpaqueCube.java @@ -0,0 +1,10 @@ +package me.rigamortis.seppuku.api.event.world; + +import me.rigamortis.seppuku.api.event.EventCancellable; + +/** + * Author Seth + * 4/7/2019 @ 5:03 PM. + */ +public class EventSetOpaqueCube extends EventCancellable { +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/world/EventWalkOnSlime.java b/src/main/java/me/rigamortis/seppuku/api/event/world/EventWalkOnSlime.java new file mode 100644 index 0000000..1775ae1 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/world/EventWalkOnSlime.java @@ -0,0 +1,10 @@ +package me.rigamortis.seppuku.api.event.world; + +import me.rigamortis.seppuku.api.event.EventCancellable; + +/** + * Author Seth + * 4/16/2019 @ 3:42 AM. + */ +public class EventWalkOnSlime extends EventCancellable { +} diff --git a/src/main/java/me/rigamortis/seppuku/api/event/world/EventWaterColor.java b/src/main/java/me/rigamortis/seppuku/api/event/world/EventWaterColor.java new file mode 100644 index 0000000..007b2d9 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/event/world/EventWaterColor.java @@ -0,0 +1,23 @@ +package me.rigamortis.seppuku.api.event.world; + +import me.rigamortis.seppuku.api.event.EventCancellable; + +/** + * Author Seth + * 8/11/2019 @ 2:44 AM. + */ +public class EventWaterColor extends EventCancellable { + + private int color; + + public EventWaterColor() { + } + + public int getColor() { + return color; + } + + public void setColor(int color) { + this.color = color; + } +} diff --git a/src/main/java/me/rigamortis/seppuku/api/friend/Friend.java b/src/main/java/me/rigamortis/seppuku/api/friend/Friend.java new file mode 100644 index 0000000..780ed24 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/friend/Friend.java @@ -0,0 +1,51 @@ +package me.rigamortis.seppuku.api.friend; + +/** + * Author Seth + * 4/16/2019 @ 11:28 PM. + */ +public final class Friend { + + private String name; + private String uuid; + private String alias; + + public Friend() { + + } + + public Friend(String name, String alias) { + this.name = name; + this.alias = alias; + } + + public Friend(String name, String uuid, String alias) { + this.name = name; + this.uuid = uuid; + this.alias = alias; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getAlias() { + return alias; + } + + public void setAlias(String alias) { + this.alias = alias; + } +} diff --git a/src/main/java/me/rigamortis/seppuku/api/gui/hud/component/DraggableHudComponent.java b/src/main/java/me/rigamortis/seppuku/api/gui/hud/component/DraggableHudComponent.java new file mode 100644 index 0000000..0f91868 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/gui/hud/component/DraggableHudComponent.java @@ -0,0 +1,278 @@ +package me.rigamortis.seppuku.api.gui.hud.component; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.util.RenderUtil; +import me.rigamortis.seppuku.impl.gui.hud.GuiHudEditor; +import me.rigamortis.seppuku.impl.gui.hud.anchor.AnchorPoint; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.ScaledResolution; +import net.minecraft.util.math.MathHelper; + +/** + * Author Seth + * 7/25/2019 @ 7:17 AM. + */ +public class DraggableHudComponent extends HudComponent { + + private boolean dragging; + private float deltaX; + private float deltaY; + + private AnchorPoint anchorPoint; + + private DraggableHudComponent glued; + private GlueSide glueSide; + + public DraggableHudComponent(String name) { + this.setName(name); + this.setVisible(false); + this.setX(Minecraft.getMinecraft().displayWidth / 2.0f); + this.setY(Minecraft.getMinecraft().displayHeight / 2.0f); + } + + @Override + public void mouseClick(int mouseX, int mouseY, int button) { + final boolean inside = mouseX >= this.getX() && mouseX <= this.getX() + this.getW() && mouseY >= this.getY() && mouseY <= this.getY() + this.getH(); + + if (inside) { + if (button == 0) { + this.setDragging(true); + this.setDeltaX(mouseX - this.getX()); + this.setDeltaY(mouseY - this.getY()); + Seppuku.INSTANCE.getHudManager().moveToTop(this); + this.anchorPoint = null; + this.glued = null; + this.glueSide = null; + } + } + } + + @Override + public void render(int mouseX, int mouseY, float partialTicks) { + super.render(mouseX, mouseY, partialTicks); + + if (this.isDragging()) { + this.setX(mouseX - this.getDeltaX()); + this.setY(mouseY - this.getDeltaY()); + this.clamp(); + } + + final boolean inside = mouseX >= this.getX() && mouseX <= this.getX() + this.getW() && mouseY >= this.getY() && mouseY <= this.getY() + this.getH(); + if (inside) { + RenderUtil.drawRect(this.getX(), this.getY(), this.getX() + this.getW(), this.getY() + this.getH(), 0x45FFFFFF); + } + + if (Minecraft.getMinecraft().currentScreen instanceof GuiHudEditor) { + RenderUtil.drawRect(this.getX(), this.getY(), this.getX() + this.getW(), this.getY() + this.getH(), 0x75101010); + } + + if (this.glued != null) { + if (this.glued.getAnchorPoint() == null) { + if (this.anchorPoint != null) { + this.anchorPoint = null; + } + } else { + this.anchorPoint = this.glued.getAnchorPoint(); + } + } + + if (this.anchorPoint == null && this.glued != null) { + this.setX(this.glued.getX()); + if (this.glueSide != null) { + switch (this.glueSide) { + case TOP: + this.setY(this.glued.getY() - this.getH()); + break; + case BOTTOM: + this.setY(this.glued.getY() + this.glued.getH()); + break; + } + } + } + + if (!this.isDragging()) { + if (this.anchorPoint != null && this.glued != null) { + switch (this.anchorPoint.getPoint()) { + case TOP_LEFT: + this.setX(this.anchorPoint.getX()); + break; + case BOTTOM_LEFT: + this.setX(this.anchorPoint.getX()); + break; + case TOP_RIGHT: + this.setX(this.anchorPoint.getX() - this.getW()); + break; + case BOTTOM_RIGHT: + this.setX(this.anchorPoint.getX() - this.getW()); + break; + case TOP_CENTER: + this.setX(this.anchorPoint.getX() - (this.getW() / 2)); + break; + } + if (this.glueSide != null) { + switch (this.glueSide) { + case TOP: + this.setY(this.glued.getY() - this.getH()); + break; + case BOTTOM: + this.setY(this.glued.getY() + this.glued.getH()); + break; + } + } + } else if (this.anchorPoint != null) { + switch (this.anchorPoint.getPoint()) { + case TOP_LEFT: + this.setX(this.anchorPoint.getX()); + this.setY(this.anchorPoint.getY()); + break; + case BOTTOM_LEFT: + this.setX(this.anchorPoint.getX()); + this.setY(this.anchorPoint.getY() - this.getH()); + break; + case TOP_RIGHT: + this.setX(this.anchorPoint.getX() - this.getW()); + this.setY(this.anchorPoint.getY()); + break; + case BOTTOM_RIGHT: + this.setX(this.anchorPoint.getX() - this.getW()); + this.setY(this.anchorPoint.getY() - this.getH()); + break; + case TOP_CENTER: + this.setX(this.anchorPoint.getX() - (this.getW() / 2)); + this.setY(this.anchorPoint.getY()); + break; + } + } + } + + this.clamp(); + } + + @Override + public void mouseRelease(int mouseX, int mouseY, int button) { + super.mouseRelease(mouseX, mouseY, button); + + if (button == 0) { + if (this.isDragging()) { + this.anchorPoint = this.findClosest(mouseX, mouseY); + + for (HudComponent component : Seppuku.INSTANCE.getHudManager().getComponentList()) { + if (component instanceof DraggableHudComponent) { + DraggableHudComponent draggable = (DraggableHudComponent) component; + if (draggable != this && this.collidesWith(draggable) && draggable.isVisible()) { + if ((this.getY() + (this.getH() / 2)) < (draggable.getY() + (draggable.getH() / 2))) { // top + this.setY(draggable.getY() - this.getH()); + this.glueSide = GlueSide.TOP; + this.glued = draggable; + if (draggable.getAnchorPoint() != null) { + this.anchorPoint = draggable.getAnchorPoint(); + } + } else if ((this.getY() + (this.getH() / 2)) > (draggable.getY() + (draggable.getH() / 2))) { // bottom + this.setY(draggable.getY() + draggable.getH()); + this.glueSide = GlueSide.BOTTOM; + this.glued = draggable; + if (draggable.getAnchorPoint() != null) { + this.anchorPoint = draggable.getAnchorPoint(); + } + } + } + } + } + } + + this.setDragging(false); + } + } + + private AnchorPoint findClosest(int x, int y) { + AnchorPoint ret = null; + double max = 100; + for (AnchorPoint point : Seppuku.INSTANCE.getHudManager().getAnchorPoints()) { + final double deltaX = x - point.getX(); + final double deltaY = y - point.getY(); + + final double dist = MathHelper.sqrt(deltaX * deltaX + deltaY * deltaY); + if (dist <= max) { + max = dist; + ret = point; + } + } + return ret; + } + + public void clamp() { + if (this.getX() <= 0) { + this.setX(2); + } + + if (this.getY() <= 0) { + this.setY(2); + } + + final ScaledResolution res = new ScaledResolution(Minecraft.getMinecraft()); + + if (this.getX() + this.getW() >= res.getScaledWidth() - 2) { + this.setX(res.getScaledWidth() - 2 - this.getW()); + } + + if (this.getY() + this.getH() >= res.getScaledHeight() - 2) { + this.setY(res.getScaledHeight() - 2 - this.getH()); + } + } + + public boolean collides() { + return false; + } + + public boolean isDragging() { + return dragging; + } + + public void setDragging(boolean dragging) { + this.dragging = dragging; + } + + public float getDeltaX() { + return deltaX; + } + + public void setDeltaX(float deltaX) { + this.deltaX = deltaX; + } + + public float getDeltaY() { + return deltaY; + } + + public void setDeltaY(float deltaY) { + this.deltaY = deltaY; + } + + public AnchorPoint getAnchorPoint() { + return anchorPoint; + } + + public void setAnchorPoint(AnchorPoint anchorPoint) { + this.anchorPoint = anchorPoint; + } + + public HudComponent getGlued() { + return glued; + } + + public void setGlued(DraggableHudComponent glued) { + this.glued = glued; + } + + public GlueSide getGlueSide() { + return glueSide; + } + + public void setGlueSide(GlueSide glueSide) { + this.glueSide = glueSide; + } + + public enum GlueSide { + TOP, BOTTOM + } +} diff --git a/src/main/java/me/rigamortis/seppuku/api/gui/hud/component/HudComponent.java b/src/main/java/me/rigamortis/seppuku/api/gui/hud/component/HudComponent.java new file mode 100644 index 0000000..2ea5eb8 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/gui/hud/component/HudComponent.java @@ -0,0 +1,102 @@ +package me.rigamortis.seppuku.api.gui.hud.component; + +/** + * Author Seth + * 7/25/2019 @ 4:14 AM. + */ +public class HudComponent { + + private float x; + private float y; + private float w; + private float h; + + private String name; + private boolean visible; + + public HudComponent() { + + } + + public HudComponent(float x, float y, float w, float h) { + this.x = x; + this.y = y; + this.w = w; + this.h = h; + } + + public void render(int mouseX, int mouseY, float partialTicks) { + + } + + public void mouseClickMove(int mouseX, int mouseY, int button) { + + } + + public void mouseClick(int mouseX, int mouseY, int button) { + + } + + public void mouseRelease(int mouseX, int mouseY, int button) { + + } + + public boolean collidesWith(HudComponent other) { + // Collision x-axis? + boolean collisionX = this.x + this.w > other.x && + other.x + other.w > this.x; + // Collision y-axis? + boolean collisionY = this.y + this.h > other.y && + other.y + other.h > this.y; + // Collision only if on both axes + return collisionX && collisionY; + } + + public float getX() { + return x; + } + + public void setX(float x) { + this.x = x; + } + + public float getY() { + return y; + } + + public void setY(float y) { + this.y = y; + } + + public float getW() { + return w; + } + + public void setW(float w) { + this.w = w; + } + + public float getH() { + return h; + } + + public void setH(float h) { + this.h = h; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public boolean isVisible() { + return visible; + } + + public void setVisible(boolean visible) { + this.visible = visible; + } +} diff --git a/src/main/java/me/rigamortis/seppuku/api/gui/hud/component/HudComponentOptions.java b/src/main/java/me/rigamortis/seppuku/api/gui/hud/component/HudComponentOptions.java new file mode 100644 index 0000000..fa2ae00 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/gui/hud/component/HudComponentOptions.java @@ -0,0 +1,80 @@ +package me.rigamortis.seppuku.api.gui.hud.component; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.util.RenderUtil; +import net.minecraft.client.Minecraft; + +/** + * created by noil on 8/9/2019 at 9:28 AM + */ +public class HudComponentOptions extends HudComponent { + + private HudComponent parent; + + public HudComponentOptions(HudComponent parent) { + this.parent = parent; + this.setVisible(false); + } + + @Override + public void mouseClick(int mouseX, int mouseY, int button) { + final boolean inside = mouseX >= this.getX() && mouseX <= this.getX() + this.getW() && mouseY >= this.getY() && mouseY <= this.getY() + this.getH(); + if (inside && button == 0) { + Seppuku.INSTANCE.getHudManager().moveToTop(this); + } + } + + @Override + public void render(int mouseX, int mouseY, float partialTicks) { + super.render(mouseX, mouseY, partialTicks); + + if (parent == null) + return; + + this.setX(parent.getX() + parent.getW()); + this.setY(parent.getY()); + + final int parentNameWidth = Minecraft.getMinecraft().fontRenderer.getStringWidth(parent.getName()); + final int visibleStringWidth = Minecraft.getMinecraft().fontRenderer.getStringWidth("Visible"); + int yOffset = 0; + + RenderUtil.drawRect(this.getX(), this.getY(), this.getX() + parentNameWidth, this.getY() + Minecraft.getMinecraft().fontRenderer.FONT_HEIGHT, 0x75505050); + Minecraft.getMinecraft().fontRenderer.drawStringWithShadow(parent.getName(), this.getX(), this.getY(), 0xFFFFFFFF); + + yOffset += Minecraft.getMinecraft().fontRenderer.FONT_HEIGHT; + + RenderUtil.drawRect(this.getX(), this.getY() + yOffset, this.getX() + visibleStringWidth, this.getY() + yOffset + Minecraft.getMinecraft().fontRenderer.FONT_HEIGHT, parent.isVisible() ? 0x7550FF50 : 0x75FF5050); + Minecraft.getMinecraft().fontRenderer.drawStringWithShadow("Visible", this.getX(), this.getY() + yOffset, 0xFFFFFFFF); + + yOffset += Minecraft.getMinecraft().fontRenderer.FONT_HEIGHT; + this.setW(Math.max(parentNameWidth, visibleStringWidth)); + this.setH(yOffset); + } + + @Override + public void mouseRelease(int mouseX, int mouseY, int button) { + if (button == 0) { + if ((mouseX > this.getX()) && (mouseX < this.getX() + Minecraft.getMinecraft().fontRenderer.getStringWidth("Visible"))) { + if (mouseY > (this.getY() + Minecraft.getMinecraft().fontRenderer.FONT_HEIGHT)) { + if (mouseY < (this.getY() + this.getH())) { + parent.setVisible(!parent.isVisible()); + } + } + } + } + + } + + @Override + public void mouseClickMove(int mouseX, int mouseY, int button) { + super.mouseClickMove(mouseX, mouseY, button); + } + + public HudComponent getParent() { + return parent; + } + + public void setParent(HudComponent parent) { + this.parent = parent; + } +} diff --git a/src/main/java/me/rigamortis/seppuku/api/ignore/Ignored.java b/src/main/java/me/rigamortis/seppuku/api/ignore/Ignored.java new file mode 100644 index 0000000..68d1977 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/ignore/Ignored.java @@ -0,0 +1,23 @@ +package me.rigamortis.seppuku.api.ignore; + +/** + * Author Seth + * 6/29/2019 @ 4:49 AM. + */ +public final class Ignored { + + private String name; + + public Ignored(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/api/logging/SeppukuFormatter.java b/src/main/java/me/rigamortis/seppuku/api/logging/SeppukuFormatter.java new file mode 100644 index 0000000..859e06b --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/logging/SeppukuFormatter.java @@ -0,0 +1,22 @@ +package me.rigamortis.seppuku.api.logging; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.logging.*; + +/** + * Author Seth + * 4/4/2019 @ 10:46 PM. + */ +public final class SeppukuFormatter extends Formatter { + + public String format(LogRecord record) { + final StringBuilder sb = new StringBuilder(); + sb.append("[" + new SimpleDateFormat("HH.mm.ss").format(new Date()) + "] "); + sb.append("[Seppuku]: "); + sb.append(formatMessage(record)); + sb.append("\n"); + return sb.toString(); + } + +} \ No newline at end of file diff --git a/src/main/java/me/rigamortis/seppuku/api/macro/Macro.java b/src/main/java/me/rigamortis/seppuku/api/macro/Macro.java new file mode 100644 index 0000000..be4b45c --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/macro/Macro.java @@ -0,0 +1,42 @@ +package me.rigamortis.seppuku.api.macro; + +/** + * Author Seth + * 5/7/2019 @ 4:22 AM. + */ +public final class Macro { + + private String name; + private String key; + private String macro; + + public Macro(String name, String key, String macro) { + this.name = name; + this.key = key; + this.macro = macro; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getMacro() { + return macro; + } + + public void setMacro(String macro) { + this.macro = macro; + } +} diff --git a/src/main/java/me/rigamortis/seppuku/api/module/Module.java b/src/main/java/me/rigamortis/seppuku/api/module/Module.java new file mode 100644 index 0000000..229d2c7 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/module/Module.java @@ -0,0 +1,216 @@ +package me.rigamortis.seppuku.api.module; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.value.*; + +import java.util.ArrayList; +import java.util.List; + +/** + * Author Seth + * 4/7/2019 @ 10:02 PM. + */ +public class Module { + + private String displayName; + private String[] alias; + private String desc; + private String key; + private int color; + private boolean hidden; + private boolean enabled; + private ModuleType type; + + private List valueList = new ArrayList(); + + public Module() { + + } + + public Module(String displayName, String[] alias, String desc, String key, int color, boolean hidden, boolean enabled, ModuleType type) { + this.displayName = displayName; + this.alias = alias; + this.desc = desc; + this.key = key; + this.color = color; + this.hidden = hidden; + this.enabled = enabled; + this.type = type; + } + + public Module(String displayName, String[] alias, String desc, String key, int color, ModuleType type) { + this.displayName = displayName; + this.alias = alias; + this.desc = desc; + this.key = key; + this.color = color; + this.type = type; + } + + public Module(String displayName, String[] alias, String key, int color, ModuleType type) { + this.displayName = displayName; + this.alias = alias; + this.key = key; + this.color = color; + this.type = type; + } + + public void onEnable() { + Seppuku.INSTANCE.getEventManager().addEventListener(this); + } + + public void onDisable() { + Seppuku.INSTANCE.getEventManager().removeEventListener(this); + } + + public void onToggle() { + + } + + public void toggle() { + this.setEnabled(!this.isEnabled()); + if(this.isEnabled()) { + this.onEnable(); + }else{ + this.onDisable(); + } + this.onToggle(); + } + + public String getMetaData() { + return null; + } + + public String toUsageString() { + if(this.valueList.size() <= 0) { + return null; + } + + final StringBuilder sb = new StringBuilder(); + + for(Value v : this.getValueList()) { + if(v instanceof BooleanValue) { + sb.append(v.getDisplayName() + "\n"); + } + if(v instanceof NumberValue && !(v instanceof OptionalValue)) { + sb.append(v.getDisplayName() + " \n"); + } + if(v instanceof StringValue) { + sb.append(v.getDisplayName() + " \n"); + } + if(v instanceof OptionalValue) { + final OptionalValue val = (OptionalValue) v; + + final StringBuilder options = new StringBuilder(); + + final int size = val.getOptions().length; + + for(int i = 0; i < val.getOptions().length; i++) { + final String option = val.getOptions()[i]; + + options.append(option + ((i == size - 1) ? "" : "|")); + } + + sb.append(v.getDisplayName() + " <" + options.toString() + ">\n"); + } + } + + final String s = sb.toString(); + + return s.substring(0, s.length() - 1); + } + + public Value find(String alias) { + for(Value v : this.getValueList()) { + for(String s : v.getAlias()) { + if(alias.equalsIgnoreCase(s)) { + return v; + } + } + if(v.getDisplayName().equalsIgnoreCase(alias)) { + return v; + } + } + return null; + } + + public void unload() { + this.valueList.clear(); + } + + public enum ModuleType { + COMBAT, MOVEMENT, RENDER, PLAYER, WORLD, MISC, HIDDEN, UI + } + + public String getDisplayName() { + return displayName; + } + + public void setDisplayName(String displayName) { + this.displayName = displayName; + } + + public String[] getAlias() { + return alias; + } + + public void setAlias(String[] alias) { + this.alias = alias; + } + + public String getDesc() { + return desc; + } + + public void setDesc(String desc) { + this.desc = desc; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public int getColor() { + return color; + } + + public void setColor(int color) { + this.color = color; + } + + public boolean isHidden() { + return hidden; + } + + public void setHidden(boolean hidden) { + this.hidden = hidden; + } + + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public ModuleType getType() { + return type; + } + + public void setType(ModuleType type) { + this.type = type; + } + + public List getValueList() { + return valueList; + } + + public void setValueList(List valueList) { + this.valueList = valueList; + } +} diff --git a/src/main/java/me/rigamortis/seppuku/api/notification/Notification.java b/src/main/java/me/rigamortis/seppuku/api/notification/Notification.java new file mode 100644 index 0000000..cca721c --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/notification/Notification.java @@ -0,0 +1,145 @@ +package me.rigamortis.seppuku.api.notification; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.util.MathUtil; +import me.rigamortis.seppuku.api.util.Timer; +import me.rigamortis.seppuku.impl.gui.hud.component.NotificationsComponent; + +/** + * created by noil on 8/17/2019 at 3:15 PM + */ +public final class Notification { + + private final String title; + + private String text; + + private float x = 0, y = 0, width = 0, height = 0; + + private final Type type; + + private int duration; // milliseconds + + private final int maxDuration; + + private float transitionX = 0, transitionY = 0; + + private final Timer timer = new Timer(); + + public Notification(String title, String text, Type type, int duration) { + this.title = title; + this.text = text; + this.type = type; + this.duration = duration; + this.maxDuration = duration; + + final NotificationsComponent notificationsComponent = (NotificationsComponent) Seppuku.INSTANCE.getHudManager().findComponent(NotificationsComponent.class); + if (notificationsComponent != null) { + this.setX(notificationsComponent.getX()); + this.setY(notificationsComponent.getY()); + this.transitionX = notificationsComponent.getX(); + this.transitionY = notificationsComponent.getY(); + } + + this.timer.reset(); + } + + public Notification(String title, String text) { + this(title, text, Type.INFO, 3000); + } + + public void update() { + int incline = 10; + this.transitionX = (float) MathUtil.parabolic(this.transitionX, this.x, incline); + this.transitionY = (float) MathUtil.parabolic(this.transitionY, this.y, incline); + if (this.timer.passed((this.duration))) { + Seppuku.INSTANCE.getNotificationManager().removeNotification(this); + } + } + + public String getTitle() { + return title; + } + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + public float getX() { + return x; + } + + public void setX(float x) { + this.x = x; + } + + public float getY() { + return y; + } + + public void setY(float y) { + this.y = y; + } + + public float getWidth() { + return width; + } + + public void setWidth(float width) { + this.width = width; + } + + public float getHeight() { + return height; + } + + public void setHeight(float height) { + this.height = height; + } + + public void setHeight(int height) { + this.height = height; + } + + public Type getType() { + return type; + } + + public int getDuration() { + return duration; + } + + public void setDuration(int duration) { + this.duration = duration; + } + + public int getMaxDuration() { + return maxDuration; + } + + public float getTransitionX() { + return transitionX; + } + + public float getTransitionY() { + return transitionY; + } + + public enum Type { + INFO(0xFF909090), SUCCESS(0xFF10FF10), WARNING(0xFFFFFF10), ERROR(0xFFFF1010), QUESTION(0xFF10FFFF), MISC(0xFFFFFFFF); + + private int color; + + Type(int color) { + this.color = color; + } + + public int getColor() { + return color; + } + } +} diff --git a/src/main/java/me/rigamortis/seppuku/api/patch/ClassPatch.java b/src/main/java/me/rigamortis/seppuku/api/patch/ClassPatch.java new file mode 100644 index 0000000..d7674ef --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/patch/ClassPatch.java @@ -0,0 +1,56 @@ +package me.rigamortis.seppuku.api.patch; + +import me.rigamortis.seppuku.api.patch.access.AccessPatch; + +/** + * Author Seth + * 4/4/2019 @ 11:23 PM. + */ +public class ClassPatch { + + private String mcpName; + private String notchName; + private boolean debug; + private AccessPatch accessPatch; + + public ClassPatch(String mcpName) { + this.mcpName = mcpName; + } + + public ClassPatch(String mcpName, String notchName) { + this.mcpName = mcpName; + this.notchName = notchName; + } + + public String getMcpName() { + return mcpName; + } + + public void setMcpName(String mcpName) { + this.mcpName = mcpName; + } + + public String getNotchName() { + return notchName; + } + + public void setNotchName(String notchName) { + this.notchName = notchName; + } + + public boolean isDebug() { + return debug; + } + + public void setDebug(boolean debug) { + this.debug = debug; + } + + public AccessPatch getAccessPatch() { + return accessPatch; + } + + public void setAccessPatch(AccessPatch accessPatch) { + this.accessPatch = accessPatch; + } +} diff --git a/src/main/java/me/rigamortis/seppuku/api/patch/MethodPatch.java b/src/main/java/me/rigamortis/seppuku/api/patch/MethodPatch.java new file mode 100644 index 0000000..cbfd636 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/patch/MethodPatch.java @@ -0,0 +1,24 @@ +package me.rigamortis.seppuku.api.patch; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Author Seth + * 4/4/2019 @ 11:24 PM. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface MethodPatch { + + String mcpName() default ""; + + String notchName() default ""; + + String mcpDesc() default ""; + + String notchDesc() default ""; + +} diff --git a/src/main/java/me/rigamortis/seppuku/api/patch/access/AccessPatch.java b/src/main/java/me/rigamortis/seppuku/api/patch/access/AccessPatch.java new file mode 100644 index 0000000..31fdabb --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/patch/access/AccessPatch.java @@ -0,0 +1,22 @@ +package me.rigamortis.seppuku.api.patch.access; + +/** + * Author Seth + * 6/27/2019 @ 2:22 AM. + */ +public class AccessPatch { + + private String file; + + public AccessPatch(String file) { + this.file = file; + } + + public String getFile() { + return file; + } + + public void setFile(String file) { + this.file = file; + } +} diff --git a/src/main/java/me/rigamortis/seppuku/api/util/ASMUtil.java b/src/main/java/me/rigamortis/seppuku/api/util/ASMUtil.java new file mode 100644 index 0000000..cad2e5f --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/util/ASMUtil.java @@ -0,0 +1,79 @@ +package me.rigamortis.seppuku.api.util; + +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.tree.*; + +import static org.objectweb.asm.ClassWriter.COMPUTE_FRAMES; +import static org.objectweb.asm.ClassWriter.COMPUTE_MAXS; + +/** + * Author Seth + * 4/4/2019 @ 11:22 PM. + */ +public final class ASMUtil { + + public static MethodNode findMethod(ClassNode classNode, String name, String desc) { + for (MethodNode methodNode : classNode.methods) { + if (methodNode.name.equals(name) && methodNode.desc.equals(desc)) { + return methodNode; + } + } + return null; + } + + public static AbstractInsnNode findMethodInsn(MethodNode mn, int opcode, String owner, String name, String desc) { + for(AbstractInsnNode insn : mn.instructions.toArray()) { + if(insn instanceof MethodInsnNode) { + final MethodInsnNode method = (MethodInsnNode)insn; + if(method.getOpcode() == opcode && method.owner.equals(owner) && method.name.equals(name) && method.desc.equals(desc)) { + return insn; + } + } + } + return null; + } + + public static AbstractInsnNode findPatternInsn(MethodNode mn, int[] pattern) { + for(AbstractInsnNode insn : mn.instructions.toArray()) { + for (final int opcode : pattern) { + if (opcode == insn.getOpcode()) { + return insn; + } + } + } + return null; + } + + public static AbstractInsnNode findInsnLdc(MethodNode mn, String s) { + for(AbstractInsnNode insn : mn.instructions.toArray()) { + if(insn instanceof LdcInsnNode) { + final LdcInsnNode ldc = (LdcInsnNode)insn; + if(ldc.cst instanceof String) { + String var = (String)ldc.cst; + if(var.equals(s)) { + return insn; + } + } + } + } + return null; + } + + public static AbstractInsnNode bottom(MethodNode method) { + return method.instructions.get(method.instructions.size() - 2); + } + + public static ClassNode getNode(byte[] classBuffer) { + ClassNode classNode = new ClassNode(); + ClassReader reader = new ClassReader(classBuffer); + reader.accept(classNode, 0); + return classNode; + } + + public static byte[] toBytes(ClassNode classNode) { + ClassWriter writer = new ClassWriter(COMPUTE_MAXS | COMPUTE_FRAMES); + classNode.accept(writer); + return writer.toByteArray(); + } +} diff --git a/src/main/java/me/rigamortis/seppuku/api/util/ColorUtil.java b/src/main/java/me/rigamortis/seppuku/api/util/ColorUtil.java new file mode 100644 index 0000000..a9b09b4 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/util/ColorUtil.java @@ -0,0 +1,21 @@ +package me.rigamortis.seppuku.api.util; + +/** + * created by noil on 9/22/2019 at 1:22 PM + */ +public final class ColorUtil { + + public static int changeAlpha(int origColor, int userInputedAlpha) { + origColor = origColor & 0x00FFFFFF; + return (userInputedAlpha << 24) | origColor; + } + + public static int getRandomColor() { + String[] letters = "0123456789ABCDEF".split(""); + StringBuilder color = new StringBuilder(); + for (int i = 0; i < 6; i++) + color.append(letters[(int) Math.round(Math.random() * 15)]); + + return Integer.parseInt(color.toString(), 16); + } +} diff --git a/src/main/java/me/rigamortis/seppuku/api/util/GLUProjection.java b/src/main/java/me/rigamortis/seppuku/api/util/GLUProjection.java new file mode 100644 index 0000000..5e85bab --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/util/GLUProjection.java @@ -0,0 +1,596 @@ +package me.rigamortis.seppuku.api.util; + +import org.lwjgl.BufferUtils; +import org.lwjgl.util.glu.GLU; +import org.lwjgl.util.vector.Matrix4f; + +import java.nio.FloatBuffer; +import java.nio.IntBuffer; + +/** + * Helper class to project world space coordinates to screen space coordinates with {@link GLU#gluProject(float, float, float, FloatBuffer, FloatBuffer, IntBuffer, FloatBuffer)} + * Author TheCyberBrick + */ +public final class GLUProjection { + public static class Line { + public Vector3D sourcePoint = new Vector3D(0, 0, 0); + public Vector3D direction = new Vector3D(0, 0, 0); + + public Line(double sx, double sy, double sz, double dx, double dy, double dz) { + this.sourcePoint.x = sx; + this.sourcePoint.y = sy; + this.sourcePoint.z = sz; + this.direction.x = dx; + this.direction.y = dy; + this.direction.z = dz; + } + + public Vector3D intersect(Line line) { + double a = this.sourcePoint.x; + double b = this.direction.x; + double c = line.sourcePoint.x; + double d = line.direction.x; + double e = this.sourcePoint.y; + double f = this.direction.y; + double g = line.sourcePoint.y; + double h = line.direction.y; + double te = -(a * h - c * h - d * (e - g)); + double be = b * h - d * f; + if (be == 0) { + return this.intersectXZ(line); + } + double t = te / be; + Vector3D result = new Vector3D(0, 0, 0); + result.x = this.sourcePoint.x + this.direction.x * t; + result.y = this.sourcePoint.y + this.direction.y * t; + result.z = this.sourcePoint.z + this.direction.z * t; + return result; + } + + private Vector3D intersectXZ(Line line) { + double a = this.sourcePoint.x; + double b = this.direction.x; + double c = line.sourcePoint.x; + double d = line.direction.x; + double e = this.sourcePoint.z; + double f = this.direction.z; + double g = line.sourcePoint.z; + double h = line.direction.z; + double te = -(a * h - c * h - d * (e - g)); + double be = b * h - d * f; + if (be == 0) { + return this.intersectYZ(line); + } + double t = te / be; + Vector3D result = new Vector3D(0, 0, 0); + result.x = this.sourcePoint.x + this.direction.x * t; + result.y = this.sourcePoint.y + this.direction.y * t; + result.z = this.sourcePoint.z + this.direction.z * t; + return result; + } + + private Vector3D intersectYZ(Line line) { + double a = this.sourcePoint.y; + double b = this.direction.y; + double c = line.sourcePoint.y; + double d = line.direction.y; + double e = this.sourcePoint.z; + double f = this.direction.z; + double g = line.sourcePoint.z; + double h = line.direction.z; + double te = -(a * h - c * h - d * (e - g)); + double be = b * h - d * f; + if (be == 0) { + return null; + } + double t = te / be; + Vector3D result = new Vector3D(0, 0, 0); + result.x = this.sourcePoint.x + this.direction.x * t; + result.y = this.sourcePoint.y + this.direction.y * t; + result.z = this.sourcePoint.z + this.direction.z * t; + return result; + } + + public Vector3D intersectPlane(Vector3D pointOnPlane, Vector3D planeNormal) { + Vector3D result = new Vector3D(this.sourcePoint.x, this.sourcePoint.y, this.sourcePoint.z); + double d = pointOnPlane.sub(this.sourcePoint).dot(planeNormal) / this.direction.dot(planeNormal); + result.sadd(this.direction.mul(d)); + if (this.direction.dot(planeNormal) == 0.0D) { + return null; + } + return result; + } + } + + public static class Vector3D { + public double x, y, z; + + public Vector3D(double x, double y, double z) { + this.x = x; + this.y = y; + this.z = z; + } + + public Vector3D add(Vector3D v) { + return new Vector3D(this.x + v.x, this.y + v.y, this.z + v.z); + } + + public Vector3D add(double x, double y, double z) { + return new Vector3D(this.x + x, this.y + y, this.z + z); + } + + public Vector3D sub(Vector3D v) { + return new Vector3D(this.x - v.x, this.y - v.y, this.z - v.z); + } + + public Vector3D sub(double x, double y, double z) { + return new Vector3D(this.x - x, this.y - y, this.z - z); + } + + public Vector3D normalized() { + double len = (double) Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z); + return new Vector3D(this.x / len, this.y / len, this.z / len); + } + + public double dot(Vector3D v) { + return this.x * v.x + this.y * v.y + this.z * v.z; + } + + public Vector3D cross(Vector3D v) { + return new Vector3D(this.y * v.z - this.z * v.y, this.z * v.x - this.x * v.z, this.x * v.y - this.y * v.x); + } + + public Vector3D mul(double m) { + return new Vector3D(this.x * m, this.y * m, this.z * m); + } + + public Vector3D div(double d) { + return new Vector3D(this.x / d, this.y / d, this.z / d); + } + + public double length() { + return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z); + } + + public Vector3D sadd(Vector3D v) { + this.x += v.x; + this.y += v.y; + this.z += v.z; + return this; + } + + public Vector3D sadd(double x, double y, double z) { + this.x += x; + this.y += y; + this.z += z; + return this; + } + + public Vector3D ssub(Vector3D v) { + this.x -= v.x; + this.y -= v.y; + this.z -= v.z; + return this; + } + + public Vector3D ssub(double x, double y, double z) { + this.x -= x; + this.y -= y; + this.z -= z; + return this; + } + + public Vector3D snormalize() { + double len = (double) Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z); + this.x /= len; + this.y /= len; + this.z /= len; + return this; + } + + public Vector3D scross(Vector3D v) { + this.x = this.y * v.z - this.z * v.y; + this.y = this.z * v.x - this.x * v.z; + this.z = this.x * v.y - this.y * v.x; + return this; + } + + public Vector3D smul(double m) { + this.x *= m; + this.y *= m; + this.z *= m; + return this; + } + + public Vector3D sdiv(double d) { + this.x /= d; + this.y /= d; + this.z /= d; + return this; + } + + @Override + public String toString() { + return "(X: " + this.x + " Y: " + this.y + " Z: " + this.z + ")"; + } + } + + public static class Projection { + public static enum Type { + INSIDE, OUTSIDE, INVERTED, FAIL + } + + private final double x; + private final double y; + private final Type t; + + public Projection(double x, double y, Type t) { + this.x = x; + this.y = y; + this.t = t; + } + + public double getX() { + return this.x; + } + + public double getY() { + return this.y; + } + + public Type getType() { + return this.t; + } + + public boolean isType(Type type) { + return this.t == type; + } + } + + public static enum ClampMode {ORTHOGONAL, DIRECT, NONE} + + private GLUProjection() { + } + + private static GLUProjection instance; + + public static GLUProjection getInstance() { + if (instance == null) { + instance = new GLUProjection(); + } + return instance; + } + + private IntBuffer viewport; + private FloatBuffer modelview; + private FloatBuffer projection; + private FloatBuffer coords = BufferUtils.createFloatBuffer(3); + private Vector3D frustumPos; + private Vector3D[] frustum; + private Vector3D[] invFrustum; + private Vector3D viewVec; + private double displayWidth; + private double displayHeight; + private double widthScale; + private double heightScale; + private double bra, bla, tra, tla; + private Line tb, bb, lb, rb; + private float fovY; + private float fovX; + private Vector3D lookVec; + + /** + * Updates the matrices. Needed whenever the viewport or one of the matrices has changed. + * + * @param viewport Viewport + * @param modelview Modelview matrix + * @param projection Projection matrix + * @param widthScale (GUI Width) / (Display Width) + * @param heightScale (GUI Height) / (Display Height) + */ + public void updateMatrices(IntBuffer viewport, FloatBuffer modelview, FloatBuffer projection, double widthScale, double heightScale) { + this.viewport = viewport; + this.modelview = modelview; + this.projection = projection; + this.widthScale = widthScale; + this.heightScale = heightScale; + + //Get fov and display dimensions + float fov = (float) Math.toDegrees(Math.atan(1.0D / this.projection.get(5)) * 2.0D); + this.fovY = fov; + this.displayWidth = this.viewport.get(2); + this.displayHeight = this.viewport.get(3); + this.fovX = (float) Math.toDegrees(2.0D * Math.atan((this.displayWidth / this.displayHeight) * Math.tan(Math.toRadians(this.fovY) / 2.0D))); + //Getting modelview vectors + Vector3D lv = new Vector3D(this.modelview.get(0), this.modelview.get(1), this.modelview.get(2)); + Vector3D uv = new Vector3D(this.modelview.get(4), this.modelview.get(5), this.modelview.get(6)); + Vector3D fv = new Vector3D(this.modelview.get(8), this.modelview.get(9), this.modelview.get(10)); + //Default axes + Vector3D nuv = new Vector3D(0, 1.0D, 0); + Vector3D nlv = new Vector3D(1.0D, 0, 0); + //Calculate yaw and pitch from modelview + double yaw = Math.toDegrees(Math.atan2(nlv.cross(lv).length(), nlv.dot(lv))) + 180.0D; + if (fv.x < 0.0D) { + yaw = 360.0D - yaw; + } + double pitch = 0.0D; + if ((-fv.y > 0.0D && yaw >= 90.0D && yaw < 270.0D) || (fv.y > 0.0D && !(yaw >= 90.0D && yaw < 270.0D))) { + pitch = Math.toDegrees(Math.atan2(nuv.cross(uv).length(), nuv.dot(uv))); + } else { + pitch = -Math.toDegrees(Math.atan2(nuv.cross(uv).length(), nuv.dot(uv))); + } + this.lookVec = this.getRotationVector(yaw, pitch); + //Get modelview matrix and invert it + Matrix4f modelviewMatrix = new Matrix4f(); + modelviewMatrix.load(this.modelview.asReadOnlyBuffer()); + modelviewMatrix.invert(); + //Get frustum position + this.frustumPos = new Vector3D(modelviewMatrix.m30, modelviewMatrix.m31, modelviewMatrix.m32); + this.frustum = this.getFrustum(this.frustumPos.x, this.frustumPos.y, this.frustumPos.z, yaw, pitch, fov, 1.0F, displayWidth / displayHeight); + this.invFrustum = this.getFrustum(this.frustumPos.x, this.frustumPos.y, this.frustumPos.z, yaw - 180, -pitch, fov, 1.0F, displayWidth / displayHeight); + //Set view vec + this.viewVec = this.getRotationVector(yaw, pitch).normalized(); + //Calculate screen border angles + this.bra = Math.toDegrees(Math.acos((displayHeight * heightScale) / Math.sqrt(displayWidth * widthScale * displayWidth * widthScale + displayHeight * heightScale * displayHeight * heightScale))); + this.bla = 360 - this.bra; + this.tra = this.bla - 180; + this.tla = this.bra + 180; + //Create screen border lines + this.rb = new Line(this.displayWidth * this.widthScale, 0, 0, 0, 1, 0); + this.tb = new Line(0, 0, 0, 1, 0, 0); + this.lb = new Line(0, 0, 0, 0, 1, 0); + this.bb = new Line(0, this.displayHeight * this.heightScale, 0, 1, 0, 0); + } + + /** + * Uses {@link GLU#gluProject(float, float, float, FloatBuffer, FloatBuffer, IntBuffer, FloatBuffer)} to project world space coordinates to screen space coordinates. + * + * @param x X position + * @param y Y position + * @param z Z position + * @param clampModeOutside Clamp mode used when the point is outside + * the normal and inverted frustum + * @param extrudeInverted If set to true this extrudes the projected point + * onto the screen borders if the point is inside + * the inverted frustum + * @return + */ + public Projection project(double x, double y, double z, ClampMode clampModeOutside, boolean extrudeInverted) { + if (this.viewport != null && this.modelview != null && this.projection != null) { + Vector3D posVec = new Vector3D(x, y, z); + boolean frustum[] = this.doFrustumCheck(this.frustum, this.frustumPos, x, y, z); + boolean outsideFrustum = frustum[0] || frustum[1] || frustum[2] || frustum[3]; + //Check if point is inside frustum + if (outsideFrustum) { + //Check if point is on opposite side of the near clip plane + boolean opposite = posVec.sub(this.frustumPos).dot(this.viewVec) <= 0.0D; + //Get inverted frustum check + boolean invFrustum[] = this.doFrustumCheck(this.invFrustum, this.frustumPos, x, y, z); + boolean outsideInvertedFrustum = invFrustum[0] || invFrustum[1] || invFrustum[2] || invFrustum[3]; + if ((extrudeInverted && !outsideInvertedFrustum) || (outsideInvertedFrustum && clampModeOutside != ClampMode.NONE)) { + if ((extrudeInverted && !outsideInvertedFrustum) || + (clampModeOutside == ClampMode.DIRECT && outsideInvertedFrustum)) { + //Point in inverted frustum, has to be clamped + double vecX = 0.0D; + double vecY = 0.0D; + if (GLU.gluProject((float) x, (float) y, (float) z, this.modelview, this.projection, this.viewport, this.coords)) { + //Get projected coordinates + if (opposite) { + //Invert coordinates + vecX = this.displayWidth * this.widthScale - (double) this.coords.get(0) * this.widthScale - this.displayWidth * this.widthScale / 2.0F; + vecY = this.displayHeight * this.heightScale - ((double) displayHeight - (double) this.coords.get(1)) * (double) this.heightScale - this.displayHeight * this.heightScale / 2.0F; + } else { + vecX = (double) this.coords.get(0) * this.widthScale - this.displayWidth * this.widthScale / 2.0F; + vecY = ((double) this.displayHeight - (double) this.coords.get(1)) * (double) this.heightScale - this.displayHeight * this.heightScale / 2.0F; + } + } else { + return new Projection(0, 0, Projection.Type.FAIL); + } + //Normalize point direction vector + Vector3D vec = new Vector3D(vecX, vecY, 0).snormalize(); + vecX = vec.x; + vecY = vec.y; + //Get vector line + Line vectorLine = new Line(this.displayWidth * this.widthScale / 2.0F, this.displayHeight * this.heightScale / 2.0F, 0, vecX, vecY, 0); + //Calculate angle of point on 2D plane relative to the screen center + double angle = Math.toDegrees(Math.acos((vec.y) / Math.sqrt(vec.x * vec.x + vec.y * vec.y))); + if (vecX < 0.0D) { + angle = 360.0D - angle; + } + //Calculate screen border intersections + Vector3D intersect = new Vector3D(0, 0, 0); + //Check which screen border to intersect + if (angle >= this.bra && angle < this.tra) { + //Right + intersect = this.rb.intersect(vectorLine); + } else if (angle >= this.tra && angle < this.tla) { + //Top + intersect = this.tb.intersect(vectorLine); + } else if (angle >= this.tla && angle < this.bla) { + //Left + intersect = this.lb.intersect(vectorLine); + } else { + //Bottom + intersect = this.bb.intersect(vectorLine); + } + return new Projection(intersect.x, intersect.y, outsideInvertedFrustum ? Projection.Type.OUTSIDE : Projection.Type.INVERTED); + } else if ((clampModeOutside == ClampMode.ORTHOGONAL && outsideInvertedFrustum)) { + if (GLU.gluProject((float) x, (float) y, (float) z, this.modelview, this.projection, this.viewport, this.coords)) { + //Get projected coordinates + double guiX = (double) this.coords.get(0) * this.widthScale; + double guiY = ((double) this.displayHeight - (double) this.coords.get(1)) * (double) this.heightScale; + if (opposite) { + //Invert coordinates + guiX = this.displayWidth * this.widthScale - guiX; + guiY = this.displayHeight * this.heightScale - guiY; + } + if (guiX < 0) { + guiX = 0; + } else if (guiX > this.displayWidth * this.widthScale) { + guiX = this.displayWidth * this.widthScale; + } + if (guiY < 0) { + guiY = 0; + } else if (guiY > this.displayHeight * this.heightScale) { + guiY = this.displayHeight * this.heightScale; + } + return new Projection(guiX, guiY, outsideInvertedFrustum ? Projection.Type.OUTSIDE : Projection.Type.INVERTED); + } else { + return new Projection(0, 0, Projection.Type.FAIL); + } + } + } else { + //Return point without clamping + if (GLU.gluProject((float) x, (float) y, (float) z, this.modelview, this.projection, this.viewport, this.coords)) { + //Get projected coordinates + double guiX = (double) this.coords.get(0) * this.widthScale; + double guiY = ((double) this.displayHeight - (double) this.coords.get(1)) * (double) this.heightScale; + if (opposite) { + //Invert coordinates + guiX = this.displayWidth * this.widthScale - guiX; + guiY = this.displayHeight * this.heightScale - guiY; + } + return new Projection(guiX, guiY, outsideInvertedFrustum ? Projection.Type.OUTSIDE : Projection.Type.INVERTED); + } else { + return new Projection(0, 0, Projection.Type.FAIL); + } + } + } else { + //Point inside frustum, can be projected normally + if (GLU.gluProject((float) x, (float) y, (float) z, this.modelview, this.projection, this.viewport, this.coords)) { + //Get projected coordinates + double guiX = (double) this.coords.get(0) * this.widthScale; + double guiY = ((double) this.displayHeight - (double) this.coords.get(1)) * (double) this.heightScale; + return new Projection(guiX, guiY, Projection.Type.INSIDE); + } else { + return new Projection(0, 0, Projection.Type.FAIL); + } + } + } + return new Projection(0, 0, Projection.Type.FAIL); + } + + /** + * Performs a frustum check. + * + * @param frustumCorners Frustum corners + * @param frustumPos Frustum position + * @param x X position + * @param y Y position + * @param z Z position + * @return + */ + public boolean[] doFrustumCheck(Vector3D[] frustumCorners, Vector3D frustumPos, double x, double y, double z) { + Vector3D point = new Vector3D(x, y, z); + boolean c1 = crossPlane(new Vector3D[]{frustumPos, frustumCorners[3], frustumCorners[0]}, point); + boolean c2 = crossPlane(new Vector3D[]{frustumPos, frustumCorners[0], frustumCorners[1]}, point); + boolean c3 = crossPlane(new Vector3D[]{frustumPos, frustumCorners[1], frustumCorners[2]}, point); + boolean c4 = crossPlane(new Vector3D[]{frustumPos, frustumCorners[2], frustumCorners[3]}, point); + return new boolean[]{c1, c2, c3, c4}; + } + + /** + * Returns true if the given plane has been crossed by the point. + * + * @param plane Vector3D[] that describes the plane + * @param point Vector3D that describes the point + * @return + */ + public boolean crossPlane(Vector3D[] plane, Vector3D point) { + Vector3D z = new Vector3D(0.0D, 0.0D, 0.0D); + Vector3D e0 = plane[1].sub(plane[0]); + Vector3D e1 = plane[2].sub(plane[0]); + Vector3D normal = e0.cross(e1).snormalize(); + double D = (z.sub(normal)).dot(plane[2]); + double dist = normal.dot(point) + D; + return dist >= 0.0D; + } + + /** + * Returns the frustum corner points + * 0 -------- 3 + * | | + * | | + * 1 -------- 2 + * + * @param x X position + * @param y Y position + * @param z Z position + * @param rotationYaw Yaw + * @param rotationPitch Pitch + * @param fov FOV + * @param farDistance Far plane distance + * @param aspectRatio (Display width) / (Display height) + * @return + */ + public Vector3D[] getFrustum(double x, double y, double z, double rotationYaw, double rotationPitch, double fov, double farDistance, double aspectRatio) { + double hFar = 2D * Math.tan(Math.toRadians(fov / 2D)) * farDistance; + double wFar = hFar * aspectRatio; + Vector3D view = this.getRotationVector(rotationYaw, rotationPitch).snormalize(); + Vector3D up = this.getRotationVector(rotationYaw, rotationPitch - 90).snormalize(); + Vector3D right = this.getRotationVector(rotationYaw + 90, 0).snormalize(); + Vector3D camPos = new Vector3D(x, y, z); + Vector3D view_camPos_product = view.add(camPos); + Vector3D fc = new Vector3D(view_camPos_product.x * farDistance, view_camPos_product.y * farDistance, view_camPos_product.z * farDistance); + Vector3D topLeftfrustum = new Vector3D(fc.x + (up.x * hFar / 2D) - (right.x * wFar / 2D), fc.y + (up.y * hFar / 2D) - (right.y * wFar / 2D), fc.z + (up.z * hFar / 2D) - (right.z * wFar / 2D)); + Vector3D downLeftfrustum = new Vector3D(fc.x - (up.x * hFar / 2D) - (right.x * wFar / 2D), fc.y - (up.y * hFar / 2D) - (right.y * wFar / 2D), fc.z - (up.z * hFar / 2D) - (right.z * wFar / 2D)); + Vector3D topRightfrustum = new Vector3D(fc.x + (up.x * hFar / 2D) + (right.x * wFar / 2D), fc.y + (up.y * hFar / 2D) + (right.y * wFar / 2D), fc.z + (up.z * hFar / 2D) + (right.z * wFar / 2D)); + Vector3D downRightfrustum = new Vector3D(fc.x - (up.x * hFar / 2D) + (right.x * wFar / 2D), fc.y - (up.y * hFar / 2D) + (right.y * wFar / 2D), fc.z - (up.z * hFar / 2D) + (right.z * wFar / 2D)); + return new Vector3D[]{topLeftfrustum, downLeftfrustum, downRightfrustum, topRightfrustum}; + } + + /** + * Returns the frustum that has been constructed with {@link GLUProjection#updateMatrices(IntBuffer, FloatBuffer, FloatBuffer, double, double)} + * 0 -------- 3 + * | | + * | | + * 1 -------- 2 + * + * @return + */ + public Vector3D[] getFrustum() { + return this.frustum; + } + + /** + * Returns the horizontal fov angle + * + * @return + */ + public float getFovX() { + return this.fovX; + } + + /** + * Returns the vertical fov angle + * + * @return + */ + public float getFovY() { + return this.fovY; + } + + /** + * Returns the normalized look vector + * + * @return + */ + public Vector3D getLookVector() { + return this.lookVec; + } + + /** + * Returns a rotated vector with the given yaw and pitch. + * + * @param rotYaw Yaw + * @param rotPitch Pitch + * @return + */ + public Vector3D getRotationVector(double rotYaw, double rotPitch) { + double c = Math.cos(-rotYaw * 0.017453292F - Math.PI); + double s = Math.sin(-rotYaw * 0.017453292F - Math.PI); + double nc = -Math.cos(-rotPitch * 0.017453292F); + double ns = Math.sin(-rotPitch * 0.017453292F); + return new Vector3D((double) (s * nc), (double) ns, (double) (c * nc)); + } +} \ No newline at end of file diff --git a/src/main/java/me/rigamortis/seppuku/api/util/ItemUtil.java b/src/main/java/me/rigamortis/seppuku/api/util/ItemUtil.java new file mode 100644 index 0000000..0449137 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/util/ItemUtil.java @@ -0,0 +1,17 @@ +package me.rigamortis.seppuku.api.util; + +import net.minecraft.enchantment.Enchantment; + +/** + * created by noil on 10/13/2019 at 10:22 AM + */ +public final class ItemUtil { + + public static boolean isIllegalEnchant(Enchantment enc, short lvl) { + final int maxPossibleLevel = enc.getMaxLevel(); + if (lvl == 0 || lvl > maxPossibleLevel) + return true; + + return lvl == Short.MAX_VALUE; + } +} diff --git a/src/main/java/me/rigamortis/seppuku/api/util/MathUtil.java b/src/main/java/me/rigamortis/seppuku/api/util/MathUtil.java new file mode 100644 index 0000000..629f6aa --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/util/MathUtil.java @@ -0,0 +1,139 @@ +package me.rigamortis.seppuku.api.util; + +import net.minecraft.client.Minecraft; +import net.minecraft.entity.Entity; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; + +import java.math.BigDecimal; +import java.math.RoundingMode; + +/** + * Author Seth + * 4/16/2019 @ 3:26 AM. + */ +public final class MathUtil { + + public static Vec3d interpolateEntity(Entity entity, float time) { + return new Vec3d(entity.lastTickPosX + (entity.posX - entity.lastTickPosX) * time, + entity.lastTickPosY + (entity.posY - entity.lastTickPosY) * time, + entity.lastTickPosZ + (entity.posZ - entity.lastTickPosZ) * time); + } + + public static double radToDeg(double rad) { + return rad * (float) (180.0f / Math.PI); + } + + public static double degToRad(double deg) { + return deg * (float) (Math.PI / 180.0f); + } + + public static Vec3d direction(float yaw) { + return new Vec3d(Math.cos(degToRad(yaw + 90f)), 0, Math.sin(degToRad(yaw + 90f))); + } + + public static float[] calcAngle(Vec3d from, Vec3d to) { + final double difX = to.x - from.x; + final double difY = (to.y - from.y) * -1.0F; + final double difZ = to.z - from.z; + + final double dist = MathHelper.sqrt(difX * difX + difZ * difZ); + + return new float[]{(float) MathHelper.wrapDegrees(Math.toDegrees(Math.atan2(difZ, difX)) - 90.0f), (float) MathHelper.wrapDegrees(Math.toDegrees(Math.atan2(difY, dist)))}; + } + + public static double[] directionSpeed(double speed) { + final Minecraft mc = Minecraft.getMinecraft(); + float forward = mc.player.movementInput.moveForward; + float side = mc.player.movementInput.moveStrafe; + float yaw = mc.player.prevRotationYaw + (mc.player.rotationYaw - mc.player.prevRotationYaw) * mc.getRenderPartialTicks(); + + if (forward != 0) { + if (side > 0) { + yaw += (forward > 0 ? -45 : 45); + } else if (side < 0) { + yaw += (forward > 0 ? 45 : -45); + } + side = 0; + + //forward = clamp(forward, 0, 1); + if (forward > 0) { + forward = 1; + } else if (forward < 0) { + forward = -1; + } + } + + final double sin = Math.sin(Math.toRadians(yaw + 90)); + final double cos = Math.cos(Math.toRadians(yaw + 90)); + final double posX = (forward * speed * cos + side * speed * sin); + final double posZ = (forward * speed * sin - side * speed * cos); + return new double[] { posX, posZ }; + } + + public static Vec3d mult(Vec3d factor, Vec3d multiplier) { + return new Vec3d(factor.x * multiplier.x, factor.y * multiplier.y, factor.z * multiplier.z); + } + + public static Vec3d mult(Vec3d factor, float multiplier) { + return new Vec3d(factor.x * multiplier, factor.y * multiplier, factor.z * multiplier); + } + + public static Vec3d div(Vec3d factor, Vec3d divisor) { + return new Vec3d(factor.x / divisor.x, factor.y / divisor.y, factor.z / divisor.z); + } + + public static Vec3d div(Vec3d factor, float divisor) { + return new Vec3d(factor.x / divisor, factor.y / divisor, factor.z / divisor); + } + + public static double round(double value, int places) { + if (places < 0) { + return value; + } + return new BigDecimal(value).setScale(places, RoundingMode.HALF_UP).doubleValue(); + } + + public static float clamp(float val, float min, float max) { + if (val <= min) { + val = min; + } + if (val >= max) { + val = max; + } + return val; + } + + public static float wrap(float val) { + val = val % 360.0f; + if (val >= 180.0f) + val -= 360.0f; + if (val < -180.0f) + val += 360.0f; + return val; + } + + // linearly maps value from the range (a..b) to (c..d) + public static double map(double value, double a, double b, double c, double d) { + // first map value from (a..b) to (0..1) + value = (value - a) / (b - a); + // then map it from (0..1) to (c..d) and return it + return c + value * (d - c); + } + + public static double linear(double from, double to, double incline) { + return (from < to - incline) ? (from + incline) : ((from > to + incline) ? (from - incline) : to); + } + + public static double parabolic(double from, double to, double incline) { + return from + (to - from) / incline; + } + + public static double getDistance(Vec3d pos, double x, double y, double z) { + final double deltaX = pos.x - x; + final double deltaY = pos.y - y; + final double deltaZ = pos.z - z; + return (double) MathHelper.sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ); + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/api/util/PotionUtil.java b/src/main/java/me/rigamortis/seppuku/api/util/PotionUtil.java new file mode 100644 index 0000000..2169f48 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/util/PotionUtil.java @@ -0,0 +1,25 @@ +package me.rigamortis.seppuku.api.util; + +import net.minecraft.client.resources.I18n; +import net.minecraft.potion.Potion; +import net.minecraft.potion.PotionEffect; + +public final class PotionUtil { + + public static String getFriendlyPotionName(PotionEffect potionEffect) { + String effectName = I18n.format(potionEffect.getPotion().getName()); + if (potionEffect.getAmplifier() == 1) { + effectName = effectName + " " + I18n.format("enchantment.level.2"); + } else if (potionEffect.getAmplifier() == 2) { + effectName = effectName + " " + I18n.format("enchantment.level.3"); + } else if (potionEffect.getAmplifier() == 3) { + effectName = effectName + " " + I18n.format("enchantment.level.4"); + } + + return effectName; + } + + public static String getNameDurationString(PotionEffect potionEffect) { + return String.format("%s (%s)", getFriendlyPotionName(potionEffect), Potion.getPotionDurationString(potionEffect, 1.0F)); + } +} diff --git a/src/main/java/me/rigamortis/seppuku/api/util/ReflectionUtil.java b/src/main/java/me/rigamortis/seppuku/api/util/ReflectionUtil.java new file mode 100644 index 0000000..53725cb --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/util/ReflectionUtil.java @@ -0,0 +1,48 @@ +package me.rigamortis.seppuku.api.util; + +import me.rigamortis.seppuku.Seppuku; + +import java.io.File; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + +/** + * Author Seth + * 4/7/2019 @ 9:13 PM. + */ +public final class ReflectionUtil { + + public static List> getClassesEx(String path) { + final List> classes = new ArrayList<>(); + + try { + final File dir = new File(path); + + for (File file : dir.listFiles()) { + if (file.getName().endsWith(".jar") || file.getName().endsWith(".zip")) { + final ClassLoader classLoader = URLClassLoader.newInstance(new URL[]{file.toURI().toURL()}, Seppuku.class.getClassLoader()); + + final ZipFile zip = new ZipFile(file); + + for (Enumeration list = zip.entries(); list.hasMoreElements(); ) { + final ZipEntry entry = (ZipEntry) list.nextElement(); + + if (entry.getName().contains(".class")) { + classes.add(classLoader.loadClass(entry.getName().substring(0, entry.getName().length() - 6).replace('/', '.'))); + } + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } + + return classes; + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/api/util/RenderUtil.java b/src/main/java/me/rigamortis/seppuku/api/util/RenderUtil.java new file mode 100644 index 0000000..3a557a5 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/util/RenderUtil.java @@ -0,0 +1,352 @@ +package me.rigamortis.seppuku.api.util; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.ScaledResolution; +import net.minecraft.client.renderer.BufferBuilder; +import net.minecraft.client.renderer.GLAllocation; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.util.math.AxisAlignedBB; +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL32; + +import java.nio.FloatBuffer; +import java.nio.IntBuffer; + +import static org.lwjgl.opengl.GL11.*; + +/** + * Author Seth + * 4/16/2019 @ 3:28 AM. + */ +public final class RenderUtil { + + private static final IntBuffer VIEWPORT = GLAllocation.createDirectIntBuffer(16); + private static final FloatBuffer MODELVIEW = GLAllocation.createDirectFloatBuffer(16); + private static final FloatBuffer PROJECTION = GLAllocation.createDirectFloatBuffer(16); + + public static void updateModelViewProjectionMatrix() { + glGetFloat(GL_MODELVIEW_MATRIX, MODELVIEW); + glGetFloat(GL_PROJECTION_MATRIX, PROJECTION); + glGetInteger(GL_VIEWPORT, VIEWPORT); + final ScaledResolution res = new ScaledResolution(Minecraft.getMinecraft()); + GLUProjection.getInstance().updateMatrices(VIEWPORT, MODELVIEW, PROJECTION, (float) res.getScaledWidth() / (float) Minecraft.getMinecraft().displayWidth, (float) res.getScaledHeight() / (float) Minecraft.getMinecraft().displayHeight); + } + + public static void drawRect(float x, float y, float w, float h, int color) { + float alpha = (float) (color >> 24 & 255) / 255.0F; + float red = (float) (color >> 16 & 255) / 255.0F; + float green = (float) (color >> 8 & 255) / 255.0F; + float blue = (float) (color & 255) / 255.0F; + final Tessellator tessellator = Tessellator.getInstance(); + final BufferBuilder bufferbuilder = tessellator.getBuffer(); + GlStateManager.enableBlend(); + GlStateManager.disableTexture2D(); + GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0); + bufferbuilder.begin(7, DefaultVertexFormats.POSITION_COLOR); + bufferbuilder.pos((double) x, (double) h, 0.0D).color(red, green, blue, alpha).endVertex(); + bufferbuilder.pos((double) w, (double) h, 0.0D).color(red, green, blue, alpha).endVertex(); + bufferbuilder.pos((double) w, (double) y, 0.0D).color(red, green, blue, alpha).endVertex(); + bufferbuilder.pos((double) x, (double) y, 0.0D).color(red, green, blue, alpha).endVertex(); + tessellator.draw(); + GlStateManager.enableTexture2D(); + GlStateManager.disableBlend(); + } + + public static void drawGradientRect(float left, float top, float right, float bottom, int startColor, int endColor) { + float f = (float) (startColor >> 24 & 255) / 255.0F; + float f1 = (float) (startColor >> 16 & 255) / 255.0F; + float f2 = (float) (startColor >> 8 & 255) / 255.0F; + float f3 = (float) (startColor & 255) / 255.0F; + float f4 = (float) (endColor >> 24 & 255) / 255.0F; + float f5 = (float) (endColor >> 16 & 255) / 255.0F; + float f6 = (float) (endColor >> 8 & 255) / 255.0F; + float f7 = (float) (endColor & 255) / 255.0F; + GlStateManager.disableTexture2D(); + GlStateManager.enableBlend(); + GlStateManager.disableAlpha(); + GlStateManager.tryBlendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO); + GlStateManager.shadeModel(7425); + Tessellator tessellator = Tessellator.getInstance(); + BufferBuilder bufferbuilder = tessellator.getBuffer(); + bufferbuilder.begin(7, DefaultVertexFormats.POSITION_COLOR); + bufferbuilder.pos((double) right, (double) top, (double) 0).color(f1, f2, f3, f).endVertex(); + bufferbuilder.pos((double) left, (double) top, (double) 0).color(f1, f2, f3, f).endVertex(); + bufferbuilder.pos((double) left, (double) bottom, (double) 0).color(f5, f6, f7, f4).endVertex(); + bufferbuilder.pos((double) right, (double) bottom, (double) 0).color(f5, f6, f7, f4).endVertex(); + tessellator.draw(); + GlStateManager.shadeModel(7424); + GlStateManager.disableBlend(); + GlStateManager.enableAlpha(); + GlStateManager.enableTexture2D(); + } + + public static void drawTriangle(float x, float y, float size, float theta, int color) { + GL11.glTranslated(x, y, 0); + GL11.glRotatef(180 + theta, 0F, 0F, 1.0F); + + float alpha = (float) (color >> 24 & 255) / 255.0F; + float red = (float) (color >> 16 & 255) / 255.0F; + float green = (float) (color >> 8 & 255) / 255.0F; + float blue = (float) (color & 255) / 255.0F; + + GL11.glColor4f(red, green, blue, alpha); + GL11.glEnable(GL11.GL_BLEND); + GL11.glDisable(GL11.GL_TEXTURE_2D); + GL11.glEnable(GL11.GL_LINE_SMOOTH); + GL11.glBlendFunc(770, 771); + GL11.glLineWidth(1); + GL11.glBegin(GL11.GL_TRIANGLE_FAN); + + GL11.glVertex2d(0, (1.0F * size)); + GL11.glVertex2d((1 * size), -(1.0F * size)); + GL11.glVertex2d(-(1 * size), -(1.0F * size)); + + GL11.glEnd(); + GL11.glDisable(GL11.GL_LINE_SMOOTH); + GL11.glEnable(GL11.GL_TEXTURE_2D); + GL11.glDisable(GL11.GL_BLEND); + GL11.glRotatef(-180 - theta, 0F, 0F, 1.0F); + GL11.glTranslated(-x, -y, 0); + } + + public static void drawOutlineRect(float x, float y, float w, float h, float thickness, int c) { + drawRect(x, y, x - thickness, h, c); + drawRect(w + thickness, y, w, h, c); + drawRect(x, y, w, y - thickness, c); + drawRect(x, h + thickness, w, h, c); + } + + public static void drawLine(float x, float y, float x1, float y1, float thickness, int hex) { + float red = (hex >> 16 & 0xFF) / 255.0F; + float green = (hex >> 8 & 0xFF) / 255.0F; + float blue = (hex & 0xFF) / 255.0F; + float alpha = (hex >> 24 & 0xFF) / 255.0F; + + GlStateManager.pushMatrix(); + GlStateManager.disableTexture2D(); + GlStateManager.enableBlend(); + GlStateManager.disableAlpha(); + GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0); + GlStateManager.shadeModel(GL_SMOOTH); + glLineWidth(thickness); + glEnable(GL_LINE_SMOOTH); + glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); + final Tessellator tessellator = Tessellator.getInstance(); + final BufferBuilder bufferbuilder = tessellator.getBuffer(); + bufferbuilder.begin(GL_LINE_STRIP, DefaultVertexFormats.POSITION_COLOR); + bufferbuilder.pos((double) x, (double) y, (double) 0).color(red, green, blue, alpha).endVertex(); + bufferbuilder.pos((double) x1, (double) y1, (double) 0).color(red, green, blue, alpha).endVertex(); + tessellator.draw(); + GlStateManager.shadeModel(GL_FLAT); + glDisable(GL_LINE_SMOOTH); + GlStateManager.disableBlend(); + GlStateManager.enableAlpha(); + GlStateManager.enableTexture2D(); + GlStateManager.popMatrix(); + } + + public static void drawLine3D(float x, float y, float z, float x1, float y1, float z1, float thickness, int hex) { + float red = (hex >> 16 & 0xFF) / 255.0F; + float green = (hex >> 8 & 0xFF) / 255.0F; + float blue = (hex & 0xFF) / 255.0F; + float alpha = (hex >> 24 & 0xFF) / 255.0F; + + GlStateManager.pushMatrix(); + GlStateManager.disableTexture2D(); + GlStateManager.enableBlend(); + GlStateManager.disableAlpha(); + GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0); + GlStateManager.shadeModel(GL_SMOOTH); + glLineWidth(thickness); + glEnable(GL_LINE_SMOOTH); + glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); + GlStateManager.disableDepth(); + glEnable(GL32.GL_DEPTH_CLAMP); + final Tessellator tessellator = Tessellator.getInstance(); + final BufferBuilder bufferbuilder = tessellator.getBuffer(); + bufferbuilder.begin(GL_LINES, DefaultVertexFormats.POSITION_COLOR); + bufferbuilder.pos((double) x, (double) y, (double) z).color(red, green, blue, alpha).endVertex(); + bufferbuilder.pos((double) x1, (double) y1, (double) z1).color(red, green, blue, alpha).endVertex(); + tessellator.draw(); + GlStateManager.shadeModel(GL_FLAT); + glDisable(GL_LINE_SMOOTH); + GlStateManager.enableDepth(); + glDisable(GL32.GL_DEPTH_CLAMP); + GlStateManager.disableBlend(); + GlStateManager.enableAlpha(); + GlStateManager.enableTexture2D(); + GlStateManager.popMatrix(); + } + + public static void drawBoundingBox(AxisAlignedBB bb, float width, int color) { + GlStateManager.pushMatrix(); + GlStateManager.enableBlend(); + GlStateManager.disableDepth(); + GlStateManager.tryBlendFuncSeparate(770, 771, 0, 1); + GlStateManager.disableTexture2D(); + GlStateManager.depthMask(false); + glEnable(GL_LINE_SMOOTH); + glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); + glLineWidth(width); + + final float alpha = (color >> 24 & 0xFF) / 255.0F; + final float red = (color >> 16 & 0xFF) / 255.0F; + final float green = (color >> 8 & 0xFF) / 255.0F; + final float blue = (color & 0xFF) / 255.0F; + + final Tessellator tessellator = Tessellator.getInstance(); + final BufferBuilder bufferbuilder = tessellator.getBuffer(); + + bufferbuilder.begin(GL_LINE_STRIP, DefaultVertexFormats.POSITION_COLOR); + bufferbuilder.pos(bb.minX, bb.minY, bb.minZ).color(red, green, blue, 0.0F).endVertex(); + bufferbuilder.pos(bb.minX, bb.minY, bb.minZ).color(red, green, blue, alpha).endVertex(); + bufferbuilder.pos(bb.maxX, bb.minY, bb.minZ).color(red, green, blue, alpha).endVertex(); + bufferbuilder.pos(bb.maxX, bb.minY, bb.maxZ).color(red, green, blue, alpha).endVertex(); + bufferbuilder.pos(bb.minX, bb.minY, bb.maxZ).color(red, green, blue, alpha).endVertex(); + bufferbuilder.pos(bb.minX, bb.minY, bb.minZ).color(red, green, blue, alpha).endVertex(); + bufferbuilder.pos(bb.minX, bb.maxY, bb.minZ).color(red, green, blue, alpha).endVertex(); + bufferbuilder.pos(bb.maxX, bb.maxY, bb.minZ).color(red, green, blue, alpha).endVertex(); + bufferbuilder.pos(bb.maxX, bb.maxY, bb.maxZ).color(red, green, blue, alpha).endVertex(); + bufferbuilder.pos(bb.minX, bb.maxY, bb.maxZ).color(red, green, blue, alpha).endVertex(); + bufferbuilder.pos(bb.minX, bb.maxY, bb.minZ).color(red, green, blue, alpha).endVertex(); + bufferbuilder.pos(bb.minX, bb.maxY, bb.maxZ).color(red, green, blue, 0.0F).endVertex(); + bufferbuilder.pos(bb.minX, bb.minY, bb.maxZ).color(red, green, blue, alpha).endVertex(); + bufferbuilder.pos(bb.maxX, bb.maxY, bb.maxZ).color(red, green, blue, 0.0F).endVertex(); + bufferbuilder.pos(bb.maxX, bb.minY, bb.maxZ).color(red, green, blue, alpha).endVertex(); + bufferbuilder.pos(bb.maxX, bb.maxY, bb.minZ).color(red, green, blue, 0.0F).endVertex(); + bufferbuilder.pos(bb.maxX, bb.minY, bb.minZ).color(red, green, blue, alpha).endVertex(); + bufferbuilder.pos(bb.maxX, bb.minY, bb.minZ).color(red, green, blue, 0.0F).endVertex(); + tessellator.draw(); + glDisable(GL_LINE_SMOOTH); + GlStateManager.depthMask(true); + GlStateManager.enableDepth(); + GlStateManager.enableTexture2D(); + GlStateManager.disableBlend(); + GlStateManager.popMatrix(); + } + + public static void drawPlane(double x, double y, double z, AxisAlignedBB bb, float width, int color) { + GL11.glPushMatrix(); + GL11.glTranslated(x, y, z); + drawPlane(bb, width, color); + GL11.glPopMatrix(); + } + + public static void drawPlane(AxisAlignedBB axisalignedbb, float width, int color) { + GlStateManager.pushMatrix(); + GlStateManager.glLineWidth(width); + GlStateManager.enableBlend(); + GlStateManager.disableDepth(); + GlStateManager.tryBlendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ONE); + GlStateManager.disableTexture2D(); + GlStateManager.depthMask(false); + glEnable(GL_LINE_SMOOTH); + glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); + drawPlane(axisalignedbb, color); + glDisable(GL_LINE_SMOOTH); + GlStateManager.depthMask(true); + GlStateManager.enableDepth(); + GlStateManager.enableTexture2D(); + GlStateManager.disableBlend(); + GlStateManager.popMatrix(); + } + + public static void drawPlane(AxisAlignedBB boundingBox, int color) { + float alpha = (color >> 24 & 0xFF) / 255.0F; + float red = (color >> 16 & 0xFF) / 255.0F; + float green = (color >> 8 & 0xFF) / 255.0F; + float blue = (color & 0xFF) / 255.0F; + + double minX = boundingBox.minX; + double minY = boundingBox.minY; + double minZ = boundingBox.minZ; + + double maxX = boundingBox.maxX; + double maxY = boundingBox.maxY; + double maxZ = boundingBox.maxZ; + + Tessellator tessellator = Tessellator.getInstance(); + BufferBuilder bufferbuilder = tessellator.getBuffer(); + + bufferbuilder.begin(GL_LINE_STRIP, DefaultVertexFormats.POSITION_COLOR); + bufferbuilder.pos(minX, minY, minZ).color(red, green, blue, alpha).endVertex(); + bufferbuilder.pos(maxX, minY, maxZ).color(red, green, blue, alpha).endVertex(); + bufferbuilder.pos(minX, minY, maxZ).color(red, green, blue, 0).endVertex(); + bufferbuilder.pos(maxZ, minY, minZ).color(red, green, blue, alpha).endVertex(); + + tessellator.draw(); + } + + public static void drawFilledBox(AxisAlignedBB bb, int color) { + GlStateManager.pushMatrix(); + GlStateManager.enableBlend(); + GlStateManager.disableDepth(); + GlStateManager.tryBlendFuncSeparate(770, 771, 0, 1); + GlStateManager.disableTexture2D(); + GlStateManager.depthMask(false); + + final float alpha = (color >> 24 & 0xFF) / 255.0F; + final float red = (color >> 16 & 0xFF) / 255.0F; + final float green = (color >> 8 & 0xFF) / 255.0F; + final float blue = (color & 0xFF) / 255.0F; + + final Tessellator tessellator = Tessellator.getInstance(); + final BufferBuilder bufferbuilder = tessellator.getBuffer(); + + bufferbuilder.begin(GL_QUADS, DefaultVertexFormats.POSITION_COLOR); + bufferbuilder.pos(bb.minX, bb.minY, bb.minZ).color(red, green, blue, alpha).endVertex(); + bufferbuilder.pos(bb.maxX, bb.minY, bb.minZ).color(red, green, blue, alpha).endVertex(); + bufferbuilder.pos(bb.maxX, bb.minY, bb.maxZ).color(red, green, blue, alpha).endVertex(); + bufferbuilder.pos(bb.minX, bb.minY, bb.maxZ).color(red, green, blue, alpha).endVertex(); + + bufferbuilder.pos(bb.minX, bb.maxY, bb.minZ).color(red, green, blue, alpha).endVertex(); + bufferbuilder.pos(bb.minX, bb.maxY, bb.maxZ).color(red, green, blue, alpha).endVertex(); + bufferbuilder.pos(bb.maxX, bb.maxY, bb.maxZ).color(red, green, blue, alpha).endVertex(); + bufferbuilder.pos(bb.maxX, bb.maxY, bb.minZ).color(red, green, blue, alpha).endVertex(); + + bufferbuilder.pos(bb.minX, bb.minY, bb.minZ).color(red, green, blue, alpha).endVertex(); + bufferbuilder.pos(bb.minX, bb.maxY, bb.minZ).color(red, green, blue, alpha).endVertex(); + bufferbuilder.pos(bb.maxX, bb.maxY, bb.minZ).color(red, green, blue, alpha).endVertex(); + bufferbuilder.pos(bb.maxX, bb.minY, bb.minZ).color(red, green, blue, alpha).endVertex(); + + bufferbuilder.pos(bb.maxX, bb.minY, bb.minZ).color(red, green, blue, alpha).endVertex(); + bufferbuilder.pos(bb.maxX, bb.maxY, bb.minZ).color(red, green, blue, alpha).endVertex(); + bufferbuilder.pos(bb.maxX, bb.maxY, bb.maxZ).color(red, green, blue, alpha).endVertex(); + bufferbuilder.pos(bb.maxX, bb.minY, bb.maxZ).color(red, green, blue, alpha).endVertex(); + + bufferbuilder.pos(bb.minX, bb.minY, bb.maxZ).color(red, green, blue, alpha).endVertex(); + bufferbuilder.pos(bb.maxX, bb.minY, bb.maxZ).color(red, green, blue, alpha).endVertex(); + bufferbuilder.pos(bb.maxX, bb.maxY, bb.maxZ).color(red, green, blue, alpha).endVertex(); + bufferbuilder.pos(bb.minX, bb.maxY, bb.maxZ).color(red, green, blue, alpha).endVertex(); + + bufferbuilder.pos(bb.minX, bb.minY, bb.minZ).color(red, green, blue, alpha).endVertex(); + bufferbuilder.pos(bb.minX, bb.minY, bb.maxZ).color(red, green, blue, alpha).endVertex(); + bufferbuilder.pos(bb.minX, bb.maxY, bb.maxZ).color(red, green, blue, alpha).endVertex(); + bufferbuilder.pos(bb.minX, bb.maxY, bb.minZ).color(red, green, blue, alpha).endVertex(); + tessellator.draw(); + GlStateManager.depthMask(true); + GlStateManager.enableDepth(); + GlStateManager.enableTexture2D(); + GlStateManager.disableBlend(); + GlStateManager.popMatrix(); + } + + public static void glScissor(float x, float y, float x1, float y1, final ScaledResolution sr) { + GL11.glScissor((int) (x * sr.getScaleFactor()), (int) (Minecraft.getMinecraft().displayHeight - (y1 * sr.getScaleFactor())), (int) ((x1 - x) * sr.getScaleFactor()), (int) ((y1 - y) * sr.getScaleFactor())); + } + + public static void drawTexturedModalRect(float x, float y, float textureX, float textureY, float width, float height) { + float f = 0.00390625F; + float f1 = 0.00390625F; + final Tessellator tessellator = Tessellator.getInstance(); + final BufferBuilder bufferbuilder = tessellator.getBuffer(); + bufferbuilder.begin(7, DefaultVertexFormats.POSITION_TEX); + bufferbuilder.pos(x, (y + height), 0.0D).tex((textureX * f), ((textureY + height) * f1)).endVertex(); + bufferbuilder.pos((x + width), (y + height), 0.0D).tex(((textureX + width) * f), ((textureY + height) * f1)).endVertex(); + bufferbuilder.pos((x + width), y, 0.0D).tex(((textureX + width) * f), (textureY * f1)).endVertex(); + bufferbuilder.pos(x, y, 0.0D).tex((textureX * f), (textureY * f1)).endVertex(); + tessellator.draw(); + } +} diff --git a/src/main/java/me/rigamortis/seppuku/api/util/StringUtil.java b/src/main/java/me/rigamortis/seppuku/api/util/StringUtil.java new file mode 100644 index 0000000..6c60dbe --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/util/StringUtil.java @@ -0,0 +1,119 @@ +package me.rigamortis.seppuku.api.util; + +/** + * Author Seth + * 4/16/2019 @ 8:32 AM. + */ +public final class StringUtil { + + public static boolean isInt(String s) { + try{ + Integer.parseInt(s); + return true; + }catch (Exception e){ + e.printStackTrace(); + } + return false; + } + + public static boolean isFloat(String s) { + try{ + Float.parseFloat(s); + return true; + }catch (Exception e) { + e.printStackTrace(); + } + return false; + } + + public static boolean isDouble(String s) { + try{ + Double.parseDouble(s); + return true; + }catch (Exception e) { + e.printStackTrace(); + } + return false; + } + + public static boolean isBoolean(String s) { + try{ + Boolean.parseBoolean(s); + return true; + }catch (Exception e){ + e.printStackTrace(); + } + return false; + } + + public static boolean isLong(String s, int radix) { + try{ + Long.parseLong(s, radix); + return true; + }catch (Exception e) { + e.printStackTrace(); + } + return false; + } + + public static boolean isNumber(String s) { + if(isInt(s) || isFloat(s) || isDouble(s) || isLong(s, 16)) { + return true; + } + return false; + } + + public static float similarityLength(String first, String second) { + return (float)Math.abs(first.length() - second.length()) / 100; + } + + public static boolean findMatching(String first, String second) { + return second.toLowerCase().contains(first.toLowerCase()); + } + + /** + * Credits https://stackoverflow.com/questions/955110/similarity-string-comparison-in-java + * @param s1 + * @param s2 + * @return + */ + public static double levenshteinDistance(String s1, String s2) { + String longer = s1, shorter = s2; + if (s1.length() < s2.length()) { + longer = s2; shorter = s1; + } + int longerLength = longer.length(); + if (longerLength == 0) { + return 1.0; + } + return (longerLength - editDistance(longer, shorter)) / (double) longerLength; + } + + public static int editDistance(String s1, String s2) { + s1 = s1.toLowerCase(); + s2 = s2.toLowerCase(); + + int[] costs = new int[s2.length() + 1]; + for (int i = 0; i <= s1.length(); i++) { + int lastValue = i; + for (int j = 0; j <= s2.length(); j++) { + if (i == 0) + costs[j] = j; + else { + if (j > 0) { + int newValue = costs[j - 1]; + if (s1.charAt(i - 1) != s2.charAt(j - 1)) + newValue = Math.min(Math.min(newValue, lastValue), + costs[j]) + 1; + costs[j - 1] = lastValue; + lastValue = newValue; + } + } + } + if (i > 0) + costs[s2.length()] = lastValue; + } + return costs[s2.length()]; + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/api/util/Timer.java b/src/main/java/me/rigamortis/seppuku/api/util/Timer.java new file mode 100644 index 0000000..bdcedd1 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/util/Timer.java @@ -0,0 +1,30 @@ +package me.rigamortis.seppuku.api.util; + +/** + * Author Seth + * 4/29/2019 @ 1:26 AM. + */ +public final class Timer { + + private long time; + + public Timer() { + time = -1; + } + + public boolean passed(double ms) { + return System.currentTimeMillis() - this.time >= ms; + } + + public void reset() { + this.time = System.currentTimeMillis(); + } + + public long getTime() { + return time; + } + + public void setTime(long time) { + this.time = time; + } +} diff --git a/src/main/java/me/rigamortis/seppuku/api/value/BooleanValue.java b/src/main/java/me/rigamortis/seppuku/api/value/BooleanValue.java new file mode 100644 index 0000000..c5c41a8 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/value/BooleanValue.java @@ -0,0 +1,24 @@ +package me.rigamortis.seppuku.api.value; + +/** + * Author Seth + * 4/17/2019 @ 5:59 AM. + */ +public class BooleanValue extends Value { + + public BooleanValue() { + } + + public BooleanValue(String displayName, String[] alias, Object value) { + super(displayName, alias, value); + } + + public boolean getBoolean() { + return (Boolean) this.getValue(); + } + + public void setBoolean(boolean val) { + this.setValue(val); + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/api/value/NumberValue.java b/src/main/java/me/rigamortis/seppuku/api/value/NumberValue.java new file mode 100644 index 0000000..320f449 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/value/NumberValue.java @@ -0,0 +1,74 @@ +package me.rigamortis.seppuku.api.value; + +/** + * Author Seth + * 4/17/2019 @ 5:59 AM. + */ +public class NumberValue extends Value { + + private T min; + private T max; + private T increment; + + public NumberValue() { + } + + public NumberValue(String displayName, String[] alias, Object value) { + super(displayName, alias, value); + } + + public NumberValue(String displayName, String[] alias, Object value, Object type, T min, T max, T increment) { + super(displayName, alias, value, type); + this.min = min; + this.max = max; + this.increment = increment; + } + + public float getFloat() { + return (Float) this.getValue(); + } + + public void setFloat(float val) { + this.setValue(val); + } + + public int getInt() { + return (Integer) this.getValue(); + } + + public void setInt(int val) { + this.setValue(val); + } + + public double getDouble() { + return (Double) this.getValue(); + } + + public void setDouble(double val) { + this.setValue(val); + } + + public T getMin() { + return min; + } + + public void setMin(T min) { + this.min = min; + } + + public T getMax() { + return max; + } + + public void setMax(T max) { + this.max = max; + } + + public T getIncrement() { + return increment; + } + + public void setIncrement(T increment) { + this.increment = increment; + } +} \ No newline at end of file diff --git a/src/main/java/me/rigamortis/seppuku/api/value/OptionalValue.java b/src/main/java/me/rigamortis/seppuku/api/value/OptionalValue.java new file mode 100644 index 0000000..e847288 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/value/OptionalValue.java @@ -0,0 +1,46 @@ +package me.rigamortis.seppuku.api.value; + +/** + * Author Seth + * 4/17/2019 @ 6:00 AM. + */ +public class OptionalValue extends NumberValue { + + private String[] options; + + public OptionalValue(String[] options) { + this.options = options; + } + + public OptionalValue(String displayName, String[] alias, Object value, String[] options) { + super(displayName, alias, value); + this.options = options; + } + + public OptionalValue(String displayName, String[] alias, Object value, Object type, Object min, Object max, Object increment, String[] options) { + super(displayName, alias, value, type, min, max, increment); + this.options = options; + } + + public int getOption(String input) { + for(int i = 0; i < this.getOptions().length; i++) { + final String s = this.getOptions()[i]; + if(input.equalsIgnoreCase(s)) { + return i; + } + } + return -1; + } + + public String getSelectedOption() { + return this.getOptions()[this.getInt()]; + } + + public String[] getOptions() { + return options; + } + + public void setOptions(String[] options) { + this.options = options; + } +} diff --git a/src/main/java/me/rigamortis/seppuku/api/value/StringValue.java b/src/main/java/me/rigamortis/seppuku/api/value/StringValue.java new file mode 100644 index 0000000..296da76 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/value/StringValue.java @@ -0,0 +1,24 @@ +package me.rigamortis.seppuku.api.value; + +/** + * Author Seth + * 4/17/2019 @ 6:05 AM. + */ +public class StringValue extends Value { + + public StringValue() { + } + + public StringValue(String displayName, String[] alias, Object value) { + super(displayName, alias, value); + } + + public String getString() { + return (String) this.getValue(); + } + + public void setString(String val) { + this.setValue(val); + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/api/value/Value.java b/src/main/java/me/rigamortis/seppuku/api/value/Value.java new file mode 100644 index 0000000..e154228 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/api/value/Value.java @@ -0,0 +1,72 @@ +package me.rigamortis.seppuku.api.value; + +/** + * Author Seth + * 4/17/2019 @ 5:58 AM. + */ +public class Value { + + private String displayName; + private String[] alias; + private T value; + private T type; + + private Value parent; + + public Value() { + + } + + public Value(String displayName, String[] alias, T value) { + this.displayName = displayName; + this.alias = alias; + this.value = value; + } + + public Value(String displayName, String[] alias, T value, T type) { + this.displayName = displayName; + this.alias = alias; + this.value = value; + this.type = type; + } + + public String getDisplayName() { + return displayName; + } + + public void setDisplayName(String displayName) { + this.displayName = displayName; + } + + public String[] getAlias() { + return alias; + } + + public void setAlias(String[] alias) { + this.alias = alias; + } + + public T getValue() { + return value; + } + + public void setValue(T value) { + this.value = value; + } + + public T getType() { + return type; + } + + public void setType(T type) { + this.type = type; + } + + public Value getParent() { + return parent; + } + + public void setParent(Value parent) { + this.parent = parent; + } +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/command/AutoIgnoreCommand.java b/src/main/java/me/rigamortis/seppuku/impl/command/AutoIgnoreCommand.java new file mode 100644 index 0000000..5263514 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/command/AutoIgnoreCommand.java @@ -0,0 +1,128 @@ +package me.rigamortis.seppuku.impl.command; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.command.Command; +import me.rigamortis.seppuku.impl.module.misc.AutoIgnoreModule; +import net.minecraft.client.Minecraft; +import net.minecraft.util.text.TextComponentString; + +/** + * Author Seth + * 7/1/2019 @ 11:37 PM. + */ +public final class AutoIgnoreCommand extends Command { + + private String[] addAlias = new String[]{"Add", "A"}; + private String[] removeAlias = new String[]{"Remove", "R", "Rem", "Delete", "Del"}; + private String[] listAlias = new String[]{"List", "L"}; + private String[] clearAlias = new String[]{"Clear", "C"}; + + public AutoIgnoreCommand() { + super("AutoIgnore", new String[]{"AutomaticIgnore", "AIG", "AIgnore"}, "Allows you to add or remove phrases from AutoIgnore", "AutoIgnore Add \n" + + "AutoIgnore Remove \n" + + "AutoIgnore List\n" + + "AutoIgnore Clear"); + } + + @Override + public void exec(String input) { + if (!this.clamp(input, 2)) { + this.printUsage(); + return; + } + + final String[] split = input.split(" "); + + final AutoIgnoreModule autoIgnoreModule = (AutoIgnoreModule) Seppuku.INSTANCE.getModuleManager().find(AutoIgnoreModule.class); + + if (autoIgnoreModule == null) { + Seppuku.INSTANCE.errorChat("AutoIgnore is missing"); + return; + } + + if (equals(addAlias, split[1])) { + if (!this.clamp(input, 3)) { + this.printUsage(); + return; + } + final StringBuilder sb = new StringBuilder(); + + for (int i = 2; i < split.length; i++) { + final String s = split[i]; + sb.append(s + (i == split.length - 1 ? "" : " ")); + } + + final String phrase = sb.toString(); + + if (autoIgnoreModule.blacklistContains(phrase.toLowerCase())) { + Seppuku.INSTANCE.logChat("AutoIgnore already contains that phrase"); + } else { + Seppuku.INSTANCE.logChat("Added phrase \"" + phrase + "\""); + autoIgnoreModule.getBlacklist().add(phrase); + Seppuku.INSTANCE.getConfigManager().saveAll(); + } + } else if (equals(removeAlias, split[1])) { + if (!this.clamp(input, 3)) { + this.printUsage(); + return; + } + final StringBuilder sb = new StringBuilder(); + + for (int i = 2; i < split.length; i++) { + final String s = split[i]; + sb.append(s + (i == split.length - 1 ? "" : " ")); + } + + final String phrase = sb.toString(); + + if (autoIgnoreModule.blacklistContains(phrase.toLowerCase())) { + Seppuku.INSTANCE.logChat("Removed phrase \"" + phrase + "\""); + autoIgnoreModule.getBlacklist().remove(phrase); + Seppuku.INSTANCE.getConfigManager().saveAll(); + } else { + Seppuku.INSTANCE.logChat("AutoIgnore does not contain that phrase"); + } + } else if (equals(listAlias, split[1])) { + if (!this.clamp(input, 2, 2)) { + this.printUsage(); + return; + } + + final int size = autoIgnoreModule.getBlacklist().size(); + + if (size > 0) { + final TextComponentString msg = new TextComponentString("\2477Phrases [" + size + "]\247f "); + + for (int i = 0; i < size; i++) { + final String phrase = autoIgnoreModule.getBlacklist().get(i); + if (phrase != null) { + msg.appendSibling(new TextComponentString("\247a" + phrase + "\2477" + ((i == size - 1) ? "" : ", "))); + } + } + + Minecraft.getMinecraft().ingameGUI.getChatGUI().printChatMessage(msg); + } else { + Seppuku.INSTANCE.logChat("You don't have any phrases"); + } + } else if (equals(clearAlias, split[1])) { + if (!this.clamp(input, 2, 2)) { + this.printUsage(); + return; + } + + final int size = autoIgnoreModule.getBlacklist().size(); + + if (size > 0) { + Seppuku.INSTANCE.logChat("Removed \247c" + size + "\247f phrase" + (size > 1 ? "s" : "")); + autoIgnoreModule.getBlacklist().clear(); + Seppuku.INSTANCE.getConfigManager().saveAll(); + } else { + Seppuku.INSTANCE.logChat("You don't have any phrases"); + } + + } else { + Seppuku.INSTANCE.errorChat("Unknown input " + "\247f\"" + input + "\""); + this.printUsage(); + } + } +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/command/BindCommand.java b/src/main/java/me/rigamortis/seppuku/impl/command/BindCommand.java new file mode 100644 index 0000000..c79168f --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/command/BindCommand.java @@ -0,0 +1,86 @@ +package me.rigamortis.seppuku.impl.command; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.command.Command; +import me.rigamortis.seppuku.api.module.Module; +import org.lwjgl.input.Keyboard; + +/** + * Author Seth + * 4/16/2019 @ 10:22 PM. + */ +public final class BindCommand extends Command { + + private String[] clearAlias = new String[]{"Clear", "C"}; + + public BindCommand() { + super("Bind", new String[] {"B"}, "Allows you to change keybinds for modules", "Bind \nBind Clear"); + } + + @Override + public void exec(String input) { + if (!this.clamp(input, 2, 3)) { + this.printUsage(); + return; + } + + final String[] split = input.split(" "); + + if (equals(clearAlias, split[1])) { + if (!this.clamp(input, 2, 2)) { + this.printUsage(); + return; + } + + int count = 0; + + for(Module mod : Seppuku.INSTANCE.getModuleManager().getModuleList()) { + if(mod.getType() != Module.ModuleType.HIDDEN && mod.getKey() != null && !mod.getKey().equals("NONE")) { + count++; + mod.setKey("NONE"); + } + } + + if(count > 0) { + Seppuku.INSTANCE.logChat("Removed " + count + " Bind" + (count > 1 ? "s" : "")); + }else{ + Seppuku.INSTANCE.logChat("You have no binds"); + } + }else{ + if (!this.clamp(input, 3, 3)) { + this.printUsage(); + return; + } + + final Module mod = Seppuku.INSTANCE.getModuleManager().find(split[1]); + + if(mod != null) { + if (mod.getType() == Module.ModuleType.HIDDEN) { + Seppuku.INSTANCE.errorChat("Cannot change bind of " + "\247f\"" + mod.getDisplayName() + "\""); + }else{ + if(split[2].equalsIgnoreCase(mod.getKey())) { + Seppuku.INSTANCE.logChat("\247c" + mod.getDisplayName() + "'s\247f key is already " + split[2].toUpperCase()); + }else{ + if(split[2].equalsIgnoreCase("NONE")) { + Seppuku.INSTANCE.logChat("Bound \247c" + mod.getDisplayName() + "\247f to " + split[2].toUpperCase()); + mod.setKey(split[2].toUpperCase()); + Seppuku.INSTANCE.getConfigManager().saveAll(); + }else if(Keyboard.getKeyIndex(split[2].toUpperCase()) != Keyboard.KEY_NONE) { + Seppuku.INSTANCE.logChat("Bound \247c" + mod.getDisplayName() + "\247f to " + split[2].toUpperCase()); + mod.setKey(split[2].toUpperCase()); + Seppuku.INSTANCE.getConfigManager().saveAll(); + }else{ + Seppuku.INSTANCE.logChat("\247c" + split[2] + "\247f is not a valid key"); + } + } + } + }else{ + Seppuku.INSTANCE.errorChat("Unknown module " + "\247f\"" + split[1] + "\""); + final Module similar = Seppuku.INSTANCE.getModuleManager().findSimilar(split[1]); + if(similar != null) { + Seppuku.INSTANCE.logChat("Did you mean " + "\247c" + similar.getDisplayName() + "\247f?"); + } + } + } + } +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/command/ColorCommand.java b/src/main/java/me/rigamortis/seppuku/impl/command/ColorCommand.java new file mode 100644 index 0000000..ecd1327 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/command/ColorCommand.java @@ -0,0 +1,49 @@ +package me.rigamortis.seppuku.impl.command; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.command.Command; +import me.rigamortis.seppuku.api.module.Module; +import me.rigamortis.seppuku.api.util.StringUtil; + +/** + * Author Seth + * 4/16/2019 @ 10:17 PM. + */ +public final class ColorCommand extends Command { + + public ColorCommand() { + super("Color", new String[]{"Col", "Colour"}, "Allows you to change arraylist colors", "Color "); + } + + @Override + public void exec(String input) { + if (!this.clamp(input, 3, 3)) { + this.printUsage(); + return; + } + + final String[] split = input.split(" "); + + final Module mod = Seppuku.INSTANCE.getModuleManager().find(split[1]); + + if (mod != null) { + if (mod.getType() == Module.ModuleType.HIDDEN) { + Seppuku.INSTANCE.errorChat("Cannot change color of " + "\247f\"" + mod.getDisplayName() + "\""); + } else { + if (StringUtil.isLong(split[2], 16)) { + Seppuku.INSTANCE.logChat("\247c" + mod.getDisplayName() + "\247f color has been set to " + split[2].toUpperCase()); + mod.setColor((int) Long.parseLong(split[2], 16)); + Seppuku.INSTANCE.getConfigManager().saveAll(); + } else { + Seppuku.INSTANCE.errorChat("Invalid input " + "\"" + split[2] + "\" expected a hex value"); + } + } + } else { + Seppuku.INSTANCE.errorChat("Unknown module " + "\247f\"" + split[1] + "\""); + final Module similar = Seppuku.INSTANCE.getModuleManager().findSimilar(split[1]); + if (similar != null) { + Seppuku.INSTANCE.logChat("Did you mean " + "\247c" + similar.getDisplayName() + "\247f?"); + } + } + } +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/command/ConnectCommand.java b/src/main/java/me/rigamortis/seppuku/impl/command/ConnectCommand.java new file mode 100644 index 0000000..d297c01 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/command/ConnectCommand.java @@ -0,0 +1,47 @@ +package me.rigamortis.seppuku.impl.command; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.command.Command; +import me.rigamortis.seppuku.api.util.StringUtil; +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.GuiConnecting; + +/** + * Author Seth + * 5/24/2019 @ 2:47 AM. + */ +public final class ConnectCommand extends Command { + + public ConnectCommand() { + super("Connect", new String[]{"Con"}, "Connects to a server", "Connect "); + } + + @Override + public void exec(String input) { + if (!this.clamp(input, 2, 2)) { + this.printUsage(); + return; + } + + final String[] split = input.split(" "); + + final String[] host = split[1].split(":"); + + int port = 25565; + + if (host.length > 1) { + if (StringUtil.isInt(host[1])) { + port = Integer.parseInt(host[1]); + }else{ + Seppuku.INSTANCE.errorChat("Invalid port \"" + host[1] + "\""); + } + } + + if(Minecraft.getMinecraft().player.connection.getNetworkManager().channel().isOpen()) { + Minecraft.getMinecraft().player.connection.getNetworkManager().closeChannel(null); + } + + Minecraft.getMinecraft().displayGuiScreen(new GuiConnecting(null, Minecraft.getMinecraft(), host[0], port)); + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/command/CoordsCommand.java b/src/main/java/me/rigamortis/seppuku/impl/command/CoordsCommand.java new file mode 100644 index 0000000..1bb298c --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/command/CoordsCommand.java @@ -0,0 +1,35 @@ +package me.rigamortis.seppuku.impl.command; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.command.Command; +import net.minecraft.client.Minecraft; + +import java.awt.*; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.StringSelection; +import java.text.DecimalFormat; + +/** + * Author Seth + * 5/23/2019 @ 8:04 AM. + */ +public final class CoordsCommand extends Command { + + public CoordsCommand() { + super("Coords", new String[] {"Coord", "Coordinates", "Coordinate"}, "Copies your coordinates to the clipboard", "Coords"); + } + + @Override + public void exec(String input) { + if (!this.clamp(input, 1, 1)) { + this.printUsage(); + return; + } + + final DecimalFormat format = new DecimalFormat("#.#"); + final StringSelection contents = new StringSelection(format.format(Minecraft.getMinecraft().player.posX) + ", " + format.format(Minecraft.getMinecraft().player.posY) + ", " + format.format(Minecraft.getMinecraft().player.posZ)); + final Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); + clipboard.setContents(contents, null); + Seppuku.INSTANCE.logChat("Copied coordinates to clipboard"); + } +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/command/CrashSlimeCommand.java b/src/main/java/me/rigamortis/seppuku/impl/command/CrashSlimeCommand.java new file mode 100644 index 0000000..24ce7bc --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/command/CrashSlimeCommand.java @@ -0,0 +1,62 @@ +package me.rigamortis.seppuku.impl.command; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.command.Command; +import net.minecraft.client.Minecraft; +import net.minecraft.init.Items; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.play.client.CPacketCreativeInventoryAction; + +/** + * Author Seth + * 8/18/2019 @ 9:32 PM. + */ +public final class CrashSlimeCommand extends Command { + + public CrashSlimeCommand() { + super("CrashSlime", new String[] {"CSlime", "CrashS"}, "Gives you a slime spawn egg that crashes the server and nearby players while in creative mode", "CrashSlime"); + } + + @Override + public void exec(String input) { + if (!this.clamp(input, 1, 1)) { + this.printUsage(); + return; + } + + final Minecraft mc = Minecraft.getMinecraft(); + + if (!mc.player.isCreative()) { + Seppuku.INSTANCE.errorChat("Creative mode is required to use this command."); + return; + } + + final ItemStack itemStack = new ItemStack(Item.getItemById(383)); + final NBTTagCompound tagCompound = (itemStack.hasTagCompound()) ? itemStack.getTagCompound() : new NBTTagCompound(); + final NBTTagCompound entityTag = new NBTTagCompound(); + + entityTag.setString("id", "minecraft:slime"); + tagCompound.setTag("EntityTag", entityTag); + entityTag.setInteger("Size", Integer.MAX_VALUE); + itemStack.setTagCompound(tagCompound); + + final int slot = this.findEmptyhotbar(); + + mc.player.connection.sendPacket(new CPacketCreativeInventoryAction(36 + (slot != -1 ? slot : mc.player.inventory.currentItem), itemStack)); + Seppuku.INSTANCE.logChat("Gave you a crash slime spawn egg"); + } + + private int findEmptyhotbar() { + for (int i = 0; i < 9; i++) { + final ItemStack stack = Minecraft.getMinecraft().player.inventory.getStackInSlot(i); + + if (stack.getItem() == Items.AIR) { + return i; + } + } + return -1; + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/command/DisconnectCommand.java b/src/main/java/me/rigamortis/seppuku/impl/command/DisconnectCommand.java new file mode 100644 index 0000000..6cb08f8 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/command/DisconnectCommand.java @@ -0,0 +1,44 @@ +package me.rigamortis.seppuku.impl.command; + +import me.rigamortis.seppuku.api.command.Command; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiMainMenu; +import net.minecraft.client.gui.GuiMultiplayer; +import net.minecraft.client.multiplayer.WorldClient; +import net.minecraft.realms.RealmsBridge; + +/** + * Author Seth + * 5/24/2019 @ 3:04 AM. + */ +public final class DisconnectCommand extends Command { + + public DisconnectCommand() { + super("Disconnect", new String[] {"Discon"}, "Disconnects from the current server", "Disconnect"); + } + + @Override + public void exec(String input) { + if (!this.clamp(input, 1, 1)) { + this.printUsage(); + return; + } + + final Minecraft mc = Minecraft.getMinecraft(); + + boolean flag = mc.isIntegratedServerRunning(); + boolean flag1 = mc.isConnectedToRealms(); + mc.world.sendQuittingDisconnectingPacket(); + mc.loadWorld(null); + + if (flag) { + mc.displayGuiScreen(new GuiMainMenu()); + } + else if (flag1) { + RealmsBridge realmsbridge = new RealmsBridge(); + realmsbridge.switchToRealms(new GuiMainMenu()); + } else { + mc.displayGuiScreen(new GuiMultiplayer(new GuiMainMenu())); + } + } +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/command/DupeCommand.java b/src/main/java/me/rigamortis/seppuku/impl/command/DupeCommand.java new file mode 100644 index 0000000..170c16e --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/command/DupeCommand.java @@ -0,0 +1,35 @@ +package me.rigamortis.seppuku.impl.command; + +import me.rigamortis.seppuku.api.command.Command; +import net.minecraft.client.Minecraft; +import net.minecraft.inventory.ClickType; +import net.minecraft.network.play.client.CPacketUseEntity; + +/** + * Author Seth + * 5/12/2019 @ 8:05 PM. + */ +public final class DupeCommand extends Command { + + public DupeCommand() { + super("Dupe", new String[] {"Dup", "Doop"}, "Allows you to dupe your inventory", "Dupe"); + } + + @Override + public void exec(String input) { + if (!this.clamp(input, 1, 1)) { + this.printUsage(); + return; + } + + final Minecraft mc = Minecraft.getMinecraft(); + + if(mc.player != null) { + for (int i = 0; i <= 45; i++) { + mc.playerController.windowClick(mc.player.inventoryContainer.windowId, i, -1, ClickType.THROW, mc.player); + } + + mc.player.connection.sendPacket(new CPacketUseEntity(mc.player)); + } + } +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/command/EnchantCommand.java b/src/main/java/me/rigamortis/seppuku/impl/command/EnchantCommand.java new file mode 100644 index 0000000..6963326 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/command/EnchantCommand.java @@ -0,0 +1,94 @@ +package me.rigamortis.seppuku.impl.command; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.command.Command; +import net.minecraft.client.Minecraft; +import net.minecraft.enchantment.Enchantment; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.network.play.client.CPacketCreativeInventoryAction; + +/** + * created by noil on 8/15/2019 at 7:29 PM + */ +public final class EnchantCommand extends Command { + + public EnchantCommand() { + super("Enchant", new String[]{"Ench"}, "Add enchants to your held item while in creative mode.", "Enchant ([true/false] Disable Curses)"); + } + + @Override + public void exec(String input) { + if (!this.clamp(input, 3, 4)) { + this.printUsage(); + return; + } + + final String[] split = input.split(" "); + + final String enchantToApply = split[1]; + final String levelToApply = split[2]; + + // ensure we got some input to parse + if (enchantToApply != null && levelToApply != null) { + final Minecraft mc = Minecraft.getMinecraft(); + + if (!mc.player.isCreative()) { // need to be in creative + Seppuku.INSTANCE.errorChat("Creative mode is required to use this command."); + return; + } + + final ItemStack itemStack = mc.player.getHeldItemMainhand(); + + if (itemStack.isEmpty()) { // needs an item of some sort to be held + Seppuku.INSTANCE.errorChat("Please hold an item in your main hand to enchant."); + return; + } + + NBTTagCompound tagCompound = itemStack.getTagCompound(); + + if (tagCompound == null) { // we need a tag compound to be valid to do any of this magic, so we'll check for a null compound + tagCompound = new NBTTagCompound(); + itemStack.setTagCompound(tagCompound); + } + + if (!tagCompound.hasKey("ench", 9)) { // check if we have enchantment tag list already or not + tagCompound.setTag("ench", new NBTTagList()); // create new enchantment tag list + } + + NBTTagList enchantments = itemStack.getTagCompound().getTagList("ench", 10); // this is the item's enchant compound list we are going to modify + + // loop thru all the registered enchants and find the ones we need + for (Enchantment enchant : Enchantment.REGISTRY) { + if (enchant == null) + continue; + + // disable curses? (used when doing all enchants) + if (split.length > 3) { + final String disableCurses = split[3]; + if (disableCurses.toLowerCase().equals("true") && enchant.isCurse()) + continue; + } + + final String enchantmentName = enchant.getTranslatedName(0).replaceAll(" ", ""); + + if (enchantToApply.toLowerCase().equals("all") || enchantmentName.toLowerCase().startsWith(enchantToApply.toLowerCase())) { + final NBTTagCompound enchantmentCompound = new NBTTagCompound(); + enchantmentCompound.setShort("id", (short) Enchantment.getEnchantmentID(enchant)); // set the enchant id + if (levelToApply.toLowerCase().startsWith("max")) { + enchantmentCompound.setShort("lvl", Short.MAX_VALUE); // set the level to the max short value + } else { + enchantmentCompound.setShort("lvl", Short.valueOf(levelToApply)); // set the level + } + enchantments.appendTag(enchantmentCompound); // add our new enchantment tag to the enchantment tag list + } + } + + // cr3at1v3 m0d3 0n1y + mc.getConnection().sendPacket(new CPacketCreativeInventoryAction(mc.player.inventory.currentItem, itemStack)); + + Seppuku.INSTANCE.logChat("Enchants have been added to your item."); + } + } +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/command/FakeChatCommand.java b/src/main/java/me/rigamortis/seppuku/impl/command/FakeChatCommand.java new file mode 100644 index 0000000..2337ee7 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/command/FakeChatCommand.java @@ -0,0 +1,36 @@ +package me.rigamortis.seppuku.impl.command; + +import me.rigamortis.seppuku.api.command.Command; +import net.minecraft.client.Minecraft; +import net.minecraft.util.text.TextComponentString; + +/** + * Author Seth + * 8/1/2019 @ 7:22 PM. + */ +public final class FakeChatCommand extends Command { + + public FakeChatCommand() { + super("FakeChat", new String[] {"FChat", "TellRaw"}, "Allows you to add a fake chat message", "FakeChat "); + } + + @Override + public void exec(String input) { + if (!this.clamp(input, 2)) { + this.printUsage(); + return; + } + + final String[] split = input.split(" "); + + final StringBuilder sb = new StringBuilder(); + + for (int i = 1; i < split.length; i++) { + final String s = split[i]; + sb.append(s + (i == split.length - 1 ? "" : " ")); + } + + final String message = sb.toString(); + Minecraft.getMinecraft().ingameGUI.getChatGUI().printChatMessage(new TextComponentString(message.replace("&", "\247"))); + } +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/command/FindEntityCommand.java b/src/main/java/me/rigamortis/seppuku/impl/command/FindEntityCommand.java new file mode 100644 index 0000000..64b454c --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/command/FindEntityCommand.java @@ -0,0 +1,34 @@ +package me.rigamortis.seppuku.impl.command; + +import me.rigamortis.seppuku.api.command.Command; +import net.minecraft.client.Minecraft; +import net.minecraft.entity.EnumCreatureType; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.chunk.Chunk; + +/** + * Author Seth + * 8/6/2019 @ 4:34 PM. + */ +public final class FindEntityCommand extends Command { + + public FindEntityCommand() { + super("FindEntity", new String[]{"FindEnt"}, "Scans nearby chunks for entity spawns", "FindEntity "); + } + + @Override + public void exec(String input) { + if (!this.clamp(input, 2, 2)) { + this.printUsage(); + return; + } + + final Minecraft mc = Minecraft.getMinecraft(); + final BlockPos pos = mc.player.getPosition(); + final Chunk chunk = mc.world.getChunkFromBlockCoords(pos); + final Biome biome = chunk.getBiome(pos, mc.world.getBiomeProvider()); + + System.out.println(biome.getSpawnableList(EnumCreatureType.CREATURE)); + } +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/command/FriendCommand.java b/src/main/java/me/rigamortis/seppuku/impl/command/FriendCommand.java new file mode 100644 index 0000000..ecc1d9c --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/command/FriendCommand.java @@ -0,0 +1,131 @@ +package me.rigamortis.seppuku.impl.command; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.command.Command; +import me.rigamortis.seppuku.api.friend.Friend; +import me.rigamortis.seppuku.api.macro.Macro; +import net.minecraft.client.Minecraft; +import net.minecraft.util.text.Style; +import net.minecraft.util.text.TextComponentString; +import net.minecraft.util.text.event.HoverEvent; + +/** + * Author Seth + * 4/16/2019 @ 11:45 PM. + */ +public final class FriendCommand extends Command { + + private String[] addAlias = new String[]{"Add", "A"}; + private String[] removeAlias = new String[]{"Remove", "R", "Rem", "Delete", "Del"}; + private String[] listAlias = new String[]{"List", "L"}; + private String[] clearAlias = new String[]{"Clear", "C"}; + + public FriendCommand() { + super("Friend", new String[]{"F"}, "Allows you to add or remove friends", "Friend Add \n" + + "Friend Add \n" + + "Friend Remove \n" + + "Friend Clear"); + } + + @Override + public void exec(String input) { + if (!this.clamp(input, 2, 4)) { + this.printUsage(); + return; + } + + final String[] split = input.split(" "); + + if (equals(addAlias, split[1])) { + if (!this.clamp(input, 3, 4)) { + this.printUsage(); + return; + } + + final String username = split[2]; + final Friend friend = Seppuku.INSTANCE.getFriendManager().find(username); + + if (friend != null) { + Seppuku.INSTANCE.logChat("\247c" + username + " \247fis already your friend"); + } else { + if (split.length > 3) { + if (!this.clamp(input, 4, 4)) { + this.printUsage(); + return; + } + final String alias = split[3]; + Seppuku.INSTANCE.logChat("Added \247c" + username + " \247fas \247c" + alias + "\247f"); + Seppuku.INSTANCE.getFriendManager().add(username, alias, true); + } else { + Seppuku.INSTANCE.logChat("Added \247c" + username + " \247f"); + Seppuku.INSTANCE.getFriendManager().add(username, username, true); + } + } + } else if (equals(removeAlias, split[1])) { + if (!this.clamp(input, 3, 3)) { + this.printUsage(); + return; + } + + final int friends = Seppuku.INSTANCE.getFriendManager().getFriendList().size(); + + if (friends == 0) { + Seppuku.INSTANCE.logChat("You don't have any friends :("); + return; + } + + final String username = split[2]; + final Friend friend = Seppuku.INSTANCE.getFriendManager().find(username); + + if (friend != null) { + Seppuku.INSTANCE.logChat("Removed \247c" + friend.getAlias() + " \247f"); + Seppuku.INSTANCE.getFriendManager().getFriendList().remove(friend); + Seppuku.INSTANCE.getConfigManager().saveAll(); + } else { + Seppuku.INSTANCE.logChat("\247c" + username + " \247fis not your friend"); + } + } else if (equals(listAlias, split[1])) { + if (!this.clamp(input, 2, 2)) { + this.printUsage(); + return; + } + + final int size = Seppuku.INSTANCE.getFriendManager().getFriendList().size(); + + if (size > 0) { + final TextComponentString msg = new TextComponentString("\2477Friends [" + size + "]\247f "); + + for (int i = 0; i < size; i++) { + final Friend friend = Seppuku.INSTANCE.getFriendManager().getFriendList().get(i); + if (friend != null) { + msg.appendSibling(new TextComponentString("\247a" + friend.getAlias() + "\2477" + ((i == size - 1) ? "" : ", ")) + .setStyle(new Style() + .setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponentString("Name: " + friend.getName() + "\n" + "UUID: " + friend.getUuid()))))); + } + } + + Minecraft.getMinecraft().ingameGUI.getChatGUI().printChatMessage(msg); + }else{ + Seppuku.INSTANCE.logChat("You don't have any friends :("); + } + } else if (equals(clearAlias, split[1])) { + if (!this.clamp(input, 2, 2)) { + this.printUsage(); + return; + } + + final int friends = Seppuku.INSTANCE.getFriendManager().getFriendList().size(); + + if (friends > 0) { + Seppuku.INSTANCE.logChat("Removed \247c" + friends + "\247f friend" + (friends > 1 ? "s" : "")); + Seppuku.INSTANCE.getFriendManager().getFriendList().clear(); + Seppuku.INSTANCE.getConfigManager().saveAll(); + } else { + Seppuku.INSTANCE.logChat("You don't have any friends :("); + } + } else { + Seppuku.INSTANCE.errorChat("Unknown input " + "\247f\"" + input + "\""); + this.printUsage(); + } + } +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/command/GiveCommand.java b/src/main/java/me/rigamortis/seppuku/impl/command/GiveCommand.java new file mode 100644 index 0000000..b0e2360 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/command/GiveCommand.java @@ -0,0 +1,135 @@ +package me.rigamortis.seppuku.impl.command; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.command.Command; +import me.rigamortis.seppuku.api.util.StringUtil; +import net.minecraft.client.Minecraft; +import net.minecraft.init.Items; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.JsonToNBT; +import net.minecraft.nbt.NBTException; +import net.minecraft.network.play.client.CPacketCreativeInventoryAction; +import net.minecraft.util.ResourceLocation; + +/** + * Author Seth + * 8/18/2019 @ 10:37 PM. + */ +public final class GiveCommand extends Command { + + public GiveCommand() { + super("Give", new String[] {"Giv"}, "Allows you to give yourself any item while in creative", "Give "); + } + + @Override + public void exec(String input) { + if (!this.clamp(input, 2)) { + this.printUsage(); + return; + } + + final Minecraft mc = Minecraft.getMinecraft(); + + if (!mc.player.isCreative()) { + Seppuku.INSTANCE.errorChat("Creative mode is required to use this command."); + return; + } + + final String[] split = input.split(" "); + + final Item item = this.findItem(split[1]); + + if(item != null) { + int amount = 1; + int meta = 0; + + if(split.length >= 3) { + if(StringUtil.isInt(split[2])) { + amount = Integer.parseInt(split[2]); + }else{ + Seppuku.INSTANCE.errorChat("Unknown number " + "\247f\"" + split[2] + "\""); + } + } + + if(split.length >= 4) { + if(StringUtil.isInt(split[3])) { + meta = Integer.parseInt(split[3]); + }else{ + Seppuku.INSTANCE.errorChat("Unknown number " + "\247f\"" + split[3] + "\""); + } + } + + final ItemStack itemStack = new ItemStack(item, amount, meta); + + if(split.length >= 5) { + final String s = this.buildString(split, 4); + + try { + itemStack.setTagCompound(JsonToNBT.getTagFromJson(s)); + } catch (NBTException e) { + e.printStackTrace(); + } + } + + final int slot = this.findEmptyhotbar(); + mc.player.connection.sendPacket(new CPacketCreativeInventoryAction(36 + (slot != -1 ? slot : mc.player.inventory.currentItem), itemStack)); + Seppuku.INSTANCE.logChat("Gave you " + amount + " " + itemStack.getDisplayName()); + }else{ + final ResourceLocation similar = this.findSimilarItem(split[1]); + + if(similar != null) { + Seppuku.INSTANCE.errorChat("Unknown item " + "\247f\"" + split[1] + "\""); + Seppuku.INSTANCE.logChat("Did you mean " + "\247c" + similar.getResourcePath() + "\247f?"); + } + } + } + + private String buildString(String[] args, int startPos) { + final StringBuilder sb = new StringBuilder(); + + for (int i = startPos; i < args.length; ++i) { + if (i > startPos) { + sb.append(" "); + } + + final String s = args[i]; + sb.append(s); + } + + return sb.toString(); + } + + private ResourceLocation findSimilarItem(String name) { + ResourceLocation ret = null; + double similarity = 0.0f; + + for (ResourceLocation res : Item.REGISTRY.getKeys()) { + final double currentSimilarity = StringUtil.levenshteinDistance(name, res.getResourcePath()); + + if (currentSimilarity >= similarity) { + similarity = currentSimilarity; + ret = res; + } + } + + return ret; + } + + private Item findItem(String name) { + final ResourceLocation res = new ResourceLocation(name); + return Item.REGISTRY.getObject(res); + } + + private int findEmptyhotbar() { + for (int i = 0; i < 9; i++) { + final ItemStack stack = Minecraft.getMinecraft().player.inventory.getStackInSlot(i); + + if (stack.getItem() == Items.AIR) { + return i; + } + } + return -1; + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/command/HClipCommand.java b/src/main/java/me/rigamortis/seppuku/impl/command/HClipCommand.java new file mode 100644 index 0000000..6dfd5ac --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/command/HClipCommand.java @@ -0,0 +1,47 @@ +package me.rigamortis.seppuku.impl.command; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.command.Command; +import me.rigamortis.seppuku.api.util.MathUtil; +import me.rigamortis.seppuku.api.util.StringUtil; +import net.minecraft.client.Minecraft; +import net.minecraft.network.play.client.CPacketEntityAction; +import net.minecraft.util.math.Vec3d; + +/** + * Author Seth + * 4/16/2019 @ 9:11 PM. + */ +public final class HClipCommand extends Command { + + public HClipCommand() { + super("HClip", new String[]{"HC", "HorizontalClip"}, "Allows you to teleport horizontally", "HClip "); + } + + @Override + public void exec(String input) { + if (!this.clamp(input, 2, 2)) { + this.printUsage(); + return; + } + + final String[] split = input.split(" "); + + if (StringUtil.isDouble(split[1])) { + final double num = Double.parseDouble(split[1]); + + final Vec3d dir = MathUtil.direction(Minecraft.getMinecraft().player.rotationYaw); + + if (dir != null) { + if (Minecraft.getMinecraft().player.getRidingEntity() != null) { + Minecraft.getMinecraft().player.getRidingEntity().setPosition(Minecraft.getMinecraft().player.getRidingEntity().posX + dir.x * num, Minecraft.getMinecraft().player.getRidingEntity().posY, Minecraft.getMinecraft().player.getRidingEntity().posZ + dir.z * num); + } else { + Minecraft.getMinecraft().player.setPosition(Minecraft.getMinecraft().player.posX + dir.x * num, Minecraft.getMinecraft().player.posY, Minecraft.getMinecraft().player.posZ + dir.z * num); + } + Seppuku.INSTANCE.logChat("Teleported you " + ((num > 0) ? "forward" : "backward") + " " + num); + } + } else { + Seppuku.INSTANCE.errorChat("Unknown number " + "\247f\"" + split[1] + "\""); + } + } +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/command/HelpCommand.java b/src/main/java/me/rigamortis/seppuku/impl/command/HelpCommand.java new file mode 100644 index 0000000..ea36eec --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/command/HelpCommand.java @@ -0,0 +1,42 @@ +package me.rigamortis.seppuku.impl.command; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.command.Command; +import net.minecraft.client.Minecraft; +import net.minecraft.util.text.Style; +import net.minecraft.util.text.TextComponentString; +import net.minecraft.util.text.event.HoverEvent; + +/** + * Author Seth + * 4/16/2019 @ 8:39 AM. + */ +public final class HelpCommand extends Command { + + public HelpCommand() { + super("Help", new String[]{"H", "?"}, "Displays all commands", "Help"); + } + + @Override + public void exec(String input) { + if (!this.clamp(input, 1, 1)) { + this.printUsage(); + return; + } + + final int size = Seppuku.INSTANCE.getCommandManager().getCommandList().size(); + + final TextComponentString msg = new TextComponentString("\2477Commands [" + size + "]\247f "); + + for (int i = 0; i < size; i++) { + final Command cmd = Seppuku.INSTANCE.getCommandManager().getCommandList().get(i); + + msg.appendSibling(new TextComponentString("\247a" + cmd.getDisplayName() + "\2477" + ((i == size - 1) ? "" : ", ")) + .setStyle(new Style() + .setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponentString("\2476" + cmd.getDesc() + "\247f") + .appendSibling(new TextComponentString("\n" + cmd.getUsage())))))); + } + + Minecraft.getMinecraft().ingameGUI.getChatGUI().printChatMessage(msg); + } +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/command/HideCommand.java b/src/main/java/me/rigamortis/seppuku/impl/command/HideCommand.java new file mode 100644 index 0000000..47db71e --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/command/HideCommand.java @@ -0,0 +1,51 @@ +package me.rigamortis.seppuku.impl.command; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.command.Command; +import me.rigamortis.seppuku.api.module.Module; + +/** + * Author Seth + * 4/16/2019 @ 10:01 PM. + */ +public final class HideCommand extends Command { + + public HideCommand() { + super("Hide", new String[] {"Hid"}, "Allows you to hide modules from the arraylist", "Hide "); + } + + @Override + public void exec(String input) { + if (!this.clamp(input, 2, 2)) { + this.printUsage(); + return; + } + + final String[] split = input.split(" "); + + final Module mod = Seppuku.INSTANCE.getModuleManager().find(split[1]); + + if(mod != null) { + if(mod.getType() == Module.ModuleType.HIDDEN) { + Seppuku.INSTANCE.errorChat("Cannot hide " + "\247f\"" + mod.getDisplayName() + "\""); + }else{ + mod.setHidden(!mod.isHidden()); + Seppuku.INSTANCE.getConfigManager().saveAll(); + + if(mod.isHidden()) { + Seppuku.INSTANCE.logChat("\247c" + mod.getDisplayName() + "\247f is now hidden"); + }else{ + Seppuku.INSTANCE.logChat("\247c" + mod.getDisplayName() + "\247f is no longer hidden"); + } + } + //TODO config + }else{ + Seppuku.INSTANCE.errorChat("Unknown module " + "\247f\"" + split[1] + "\""); + final Module similar = Seppuku.INSTANCE.getModuleManager().findSimilar(split[1]); + + if(similar != null) { + Seppuku.INSTANCE.logChat("Did you mean " + "\247c" + similar.getDisplayName() + "\247f?"); + } + } + } +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/command/IPCommand.java b/src/main/java/me/rigamortis/seppuku/impl/command/IPCommand.java new file mode 100644 index 0000000..857e170 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/command/IPCommand.java @@ -0,0 +1,39 @@ +package me.rigamortis.seppuku.impl.command; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.command.Command; +import net.minecraft.client.Minecraft; + +import java.awt.*; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.StringSelection; + +/** + * Author Seth + * 5/23/2019 @ 8:11 AM. + */ +public final class IPCommand extends Command { + + public IPCommand() { + super("IP", new String[] {"IPAddress"}, "Copies the current server ip to your clipboard", "IP"); + } + + @Override + public void exec(String input) { + if (!this.clamp(input, 1, 1)) { + this.printUsage(); + return; + } + + final Minecraft mc = Minecraft.getMinecraft(); + + if(mc.getCurrentServerData() != null) { + final StringSelection contents = new StringSelection(mc.getCurrentServerData().serverIP); + final Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); + clipboard.setContents(contents, null); + Seppuku.INSTANCE.logChat("Copied IP to clipboard"); + }else{ + Seppuku.INSTANCE.errorChat("Error, Join a server"); + } + } +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/command/IgnoreCommand.java b/src/main/java/me/rigamortis/seppuku/impl/command/IgnoreCommand.java new file mode 100644 index 0000000..67d1a40 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/command/IgnoreCommand.java @@ -0,0 +1,113 @@ +package me.rigamortis.seppuku.impl.command; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.command.Command; +import me.rigamortis.seppuku.api.ignore.Ignored; +import net.minecraft.client.Minecraft; +import net.minecraft.util.text.TextComponentString; + +/** + * Author Seth + * 6/29/2019 @ 5:03 AM. + */ +public final class IgnoreCommand extends Command { + + private String[] addAlias = new String[]{"Add", "A"}; + private String[] removeAlias = new String[]{"Remove", "R", "Rem", "Delete", "Del"}; + private String[] listAlias = new String[]{"List", "L"}; + private String[] clearAlias = new String[]{"Clear", "C"}; + + public IgnoreCommand() { + super("Ignore", new String[]{"Ignor"}, "Allows you to ignore other players", "Ignore Add \n" + + "Ignore Remove \n" + + "Ignore List\n" + + "Ignore Clear"); + } + + @Override + public void exec(String input) { + if (!this.clamp(input, 2, 3)) { + this.printUsage(); + return; + } + + final String[] split = input.split(" "); + + if (equals(addAlias, split[1])) { + if (!this.clamp(input, 3, 3)) { + this.printUsage(); + return; + } + + final Ignored ignored = Seppuku.INSTANCE.getIgnoredManager().find(split[2]); + + if (ignored != null) { + Seppuku.INSTANCE.logChat("\247c" + ignored.getName() + " \247fis already ignored"); + } else { + Seppuku.INSTANCE.logChat("Added \247c" + split[2] + "\247f to your ignore list"); + Seppuku.INSTANCE.getIgnoredManager().add(split[2]); + Seppuku.INSTANCE.getConfigManager().saveAll(); + } + } else if (equals(removeAlias, split[1])) { + if (!this.clamp(input, 3, 3)) { + this.printUsage(); + return; + } + + final int size = Seppuku.INSTANCE.getIgnoredManager().getIgnoredList().size(); + + if (size == 0) { + Seppuku.INSTANCE.logChat("You don't have anyone ignored"); + return; + } + + final Ignored ignored = Seppuku.INSTANCE.getIgnoredManager().find(split[2]); + + if (ignored != null) { + Seppuku.INSTANCE.logChat("Removed \247c" + ignored.getName() + "\247f from your ignore list"); + Seppuku.INSTANCE.getIgnoredManager().getIgnoredList().remove(ignored); + Seppuku.INSTANCE.getConfigManager().saveAll(); + } else { + Seppuku.INSTANCE.logChat("\247c" + split[1] + " \247fis not ignored"); + } + } else if (equals(listAlias, split[1])) { + if (!this.clamp(input, 2, 2)) { + this.printUsage(); + return; + } + final int size = Seppuku.INSTANCE.getIgnoredManager().getIgnoredList().size(); + + if (size > 0) { + final TextComponentString msg = new TextComponentString("\2477Ignored [" + size + "]\247f "); + + for (int i = 0; i < size; i++) { + final Ignored ignored = Seppuku.INSTANCE.getIgnoredManager().getIgnoredList().get(i); + if (ignored != null) { + msg.appendSibling(new TextComponentString("\247a" + ignored.getName() + "\2477" + ((i == size - 1) ? "" : ", "))); + } + } + + Minecraft.getMinecraft().ingameGUI.getChatGUI().printChatMessage(msg); + }else{ + Seppuku.INSTANCE.logChat("You don't have anyone ignored"); + } + } else if (equals(clearAlias, split[1])) { + if (!this.clamp(input, 2, 2)) { + this.printUsage(); + return; + } + final int size = Seppuku.INSTANCE.getIgnoredManager().getIgnoredList().size(); + + if (size > 0) { + Seppuku.INSTANCE.logChat("Removed \247c" + size + "\247f ignored player" + (size > 1 ? "s" : "")); + Seppuku.INSTANCE.getIgnoredManager().getIgnoredList().clear(); + Seppuku.INSTANCE.getConfigManager().saveAll(); + } else { + Seppuku.INSTANCE.logChat("You don't have anyone ignored"); + } + } else { + Seppuku.INSTANCE.errorChat("Unknown input " + "\247f\"" + input + "\""); + this.printUsage(); + } + } +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/command/InvSeeCommand.java b/src/main/java/me/rigamortis/seppuku/impl/command/InvSeeCommand.java new file mode 100644 index 0000000..fdcb9f5 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/command/InvSeeCommand.java @@ -0,0 +1,69 @@ +package me.rigamortis.seppuku.impl.command; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.command.Command; +import me.rigamortis.seppuku.api.event.render.EventRender2D; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.inventory.GuiInventory; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.EntityPlayer; +import team.stiff.pomelo.impl.annotated.handler.annotation.Listener; + +/** + * Author Seth + * 5/20/2019 @ 12:25 AM. + */ +public final class InvSeeCommand extends Command { + + private String entity; + + public InvSeeCommand() { + super("InvSee", new String[] {"InventorySee"}, "Allows you to see another players inventory", "InvSee "); + } + + @Override + public void exec(String input) { + if (!this.clamp(input, 2, 2)) { + this.printUsage(); + return; + } + + final String[] split = input.split(" "); + + try { + this.entity = split[1]; + Seppuku.INSTANCE.getEventManager().addEventListener(this); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Listener + public void render(EventRender2D event) { + try{ + final Minecraft mc = Minecraft.getMinecraft(); + + EntityPlayer player = null; + + for(Entity e : mc.world.loadedEntityList) { + if(e != null && e instanceof EntityPlayer) { + if(e.getName().equalsIgnoreCase(this.entity)) { + player = (EntityPlayer)e; + break; + } + } + } + + if(player != null) { + mc.displayGuiScreen(new GuiInventory(player)); + }else{ + Seppuku.INSTANCE.errorChat("\"" + this.entity + "\" is not within range"); + } + }catch (Exception e) { + e.printStackTrace(); + } + + Seppuku.INSTANCE.getEventManager().removeEventListener(this); + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/command/JavaScriptCommand.java b/src/main/java/me/rigamortis/seppuku/impl/command/JavaScriptCommand.java new file mode 100644 index 0000000..62b2da8 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/command/JavaScriptCommand.java @@ -0,0 +1,79 @@ +package me.rigamortis.seppuku.impl.command; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.command.Command; + +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import javax.script.ScriptException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +/** + * Author Seth + * 7/27/2019 @ 7:19 PM. + * Credits https://stackoverflow.com/questions/1601246/java-scripting-api-how-to-stop-the-evaluation + */ +public final class JavaScriptCommand extends Command { + + public JavaScriptCommand() { + super("JavaScript", new String[]{"Js"}, "Allows you to execute javascript client-side", "JavaScript "); + } + + @Override + public void exec(String input) { + if (!this.clamp(input, 2)) { + this.printUsage(); + return; + } + + final String[] split = input.split(" "); + + final StringBuilder sb = new StringBuilder(); + + for (int i = 1; i < split.length; i++) { + final String s = split[i]; + sb.append(s + (i == split.length - 1 ? "" : " ")); + } + + final String syntax = sb.toString(); + + try { + Executors.newCachedThreadPool().submit(new ScriptRunnable(syntax)).get(3, TimeUnit.SECONDS); + } catch (TimeoutException e) { + Seppuku.INSTANCE.errorChat("Took too long to execute"); + Executors.newCachedThreadPool().shutdown(); + } catch (InterruptedException e) { + e.printStackTrace(); + Seppuku.INSTANCE.errorChat(e.getMessage()); + } catch (ExecutionException e) { + e.printStackTrace(); + Seppuku.INSTANCE.errorChat(e.getMessage()); + } + } + + public static class ScriptRunnable implements Runnable { + private String syntax; + + public ScriptRunnable(String syntax) { + this.syntax = syntax; + } + + @Override + public void run() { + try { + final long time = System.nanoTime(); + ScriptEngine scriptEngine = new ScriptEngineManager(null).getEngineByName("nashorn"); + Seppuku.INSTANCE.logChat(scriptEngine.eval(syntax).toString()); + Seppuku.INSTANCE.logChat("Execution time: " + (System.nanoTime() - time) / 1000000 + "ms"); + } catch (ScriptException e) { + e.printStackTrace(); + Seppuku.INSTANCE.errorChat(e.getMessage()); + } + } + + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/command/JoinDateCommand.java b/src/main/java/me/rigamortis/seppuku/impl/command/JoinDateCommand.java new file mode 100644 index 0000000..d4442e4 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/command/JoinDateCommand.java @@ -0,0 +1,99 @@ +package me.rigamortis.seppuku.impl.command; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.command.Command; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.URL; +import java.nio.charset.Charset; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +/** + * created by noil on 8/15/2019 at 4:41 PM + */ +public final class JoinDateCommand extends Command { + + public JoinDateCommand() { + super("JoinDate", new String[]{"Jd"}, "Prints a given 9b9t player's join date (via 9b9t.com) in chat.", "JoinDate "); + } + + @Override + public void exec(String input) { + if (!this.clamp(input, 2, 2)) { + this.printUsage(); + return; + } + + final String[] split = input.split(" "); + + final String givenUsername = split[1]; + + if (givenUsername != null) { + + //fuckin newfags these days + if(givenUsername.equalsIgnoreCase("Miniman392")) { + final Calendar calendar = Calendar.getInstance(); + calendar.add(Calendar.DAY_OF_YEAR, 1); + final SimpleDateFormat formatter = new SimpleDateFormat("MMMM d, yyyy"); + Seppuku.INSTANCE.logChat(givenUsername + " joined on " + formatter.format(calendar.getTime())); + return; + } + + if(givenUsername.equalsIgnoreCase("iSlime")) { + Seppuku.INSTANCE.errorChat("Invalid username or the website is offline."); + Seppuku.INSTANCE.errorChat("Who the fuck is iSlime?"); + return; + } + + if(givenUsername.equalsIgnoreCase("FlashBak_")) { + Seppuku.INSTANCE.logChat(givenUsername + " joined on 2011"); + return; + } + + new Thread(() -> { + final String date = getJoinDate(givenUsername); + if (date != null) { + Seppuku.INSTANCE.logChat(givenUsername + " joined on " + date); + } else { + Seppuku.INSTANCE.errorChat("Invalid username or the website is offline."); + } + }).start(); + } else { + Seppuku.INSTANCE.errorChat("Error in username format " + "\247f\"" + split[1] + "\""); + this.printUsage(); + } + } + + private String getJoinDate(String username) { + try { + String data = this.getDataFromWebSite("http://9b9t.com/join-date/submit/" + username); + if (data.contains("Join Date:")) { + data = data.substring(data.indexOf("Join Date:")).substring(34); + data = data.substring(0, 10); + SimpleDateFormat parser = new SimpleDateFormat("yyyy-MM-dd"); + Date date = parser.parse(data); + SimpleDateFormat formatter = new SimpleDateFormat("MMMM d, yyyy"); + return formatter.format(date); + } + } catch (Exception e) { + return null; + } + return null; + } + + private String getDataFromWebSite(String site) throws Exception { + URL url = new URL(site); + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(url.openStream(), Charset.forName("UTF-8"))); + StringBuilder stringBuilder = new StringBuilder(); + String inputLine; + while ((inputLine = bufferedReader.readLine()) != null) { + stringBuilder.append(inputLine); + } + bufferedReader.close(); + return stringBuilder.toString(); + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/command/MacroCommand.java b/src/main/java/me/rigamortis/seppuku/impl/command/MacroCommand.java new file mode 100644 index 0000000..d753c24 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/command/MacroCommand.java @@ -0,0 +1,134 @@ +package me.rigamortis.seppuku.impl.command; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.command.Command; +import me.rigamortis.seppuku.api.macro.Macro; +import net.minecraft.client.Minecraft; +import net.minecraft.util.text.Style; +import net.minecraft.util.text.TextComponentString; +import net.minecraft.util.text.event.HoverEvent; +import org.lwjgl.input.Keyboard; + +/** + * Author Seth + * 5/7/2019 @ 4:20 AM. + */ +public final class MacroCommand extends Command { + + private String[] addAlias = new String[]{"Add", "A"}; + private String[] removeAlias = new String[]{"Remove", "R", "Rem", "Delete", "Del"}; + private String[] listAlias = new String[]{"List", "L"}; + private String[] clearAlias = new String[]{"Clear", "C"}; + + public MacroCommand() { + super("Macro", new String[]{"Mac"}, "Allows you to create chat macros", "Macro Add \n" + + "Macro Remove \n" + + "Macro List\n" + + "Macro Clear"); + } + + @Override + public void exec(String input) { + if (!this.clamp(input, 2)) { + this.printUsage(); + return; + } + + final String[] split = input.split(" "); + + if (equals(addAlias, split[1])) { + if (!this.clamp(input, 5)) { + this.printUsage(); + return; + } + + final String name = split[2]; + final String key = split[3]; + + final Macro macro = Seppuku.INSTANCE.getMacroManager().find(name); + + if(macro != null) { + Seppuku.INSTANCE.logChat("\247c\"" + name + "\"\247f is already a macro"); + }else{ + if(Keyboard.getKeyIndex(key.toUpperCase()) != Keyboard.KEY_NONE) { + final StringBuilder sb = new StringBuilder(); + + final int size = split.length; + + for (int i = 4; i < size; i++) { + final String arg = split[i]; + sb.append(arg + ((i == size - 1) ? "" : " ")); + } + + Seppuku.INSTANCE.logChat("Added macro \247c" + name + "\247f bound to " + key.toUpperCase()); + Seppuku.INSTANCE.getMacroManager().getMacroList().add(new Macro(name, key.toUpperCase(), sb.toString())); + Seppuku.INSTANCE.getConfigManager().saveAll(); + }else{ + Seppuku.INSTANCE.logChat("\247c" + key + "\247f is not a valid key"); + } + } + } else if (equals(removeAlias, split[1])) { + if (!this.clamp(input, 3, 3)) { + this.printUsage(); + return; + } + + final String name = split[2]; + + final Macro macro = Seppuku.INSTANCE.getMacroManager().find(name); + + if(macro != null) { + Seppuku.INSTANCE.logChat("Removed macro \247c" + macro.getName() + " \247f"); + Seppuku.INSTANCE.getMacroManager().getMacroList().remove(macro); + Seppuku.INSTANCE.getConfigManager().saveAll(); + }else{ + //TODO similar + Seppuku.INSTANCE.errorChat("Unknown macro " + "\247f\"" + name + "\""); + } + } else if (equals(listAlias, split[1])) { + if (!this.clamp(input, 2, 2)) { + this.printUsage(); + return; + } + + final int size = Seppuku.INSTANCE.getMacroManager().getMacroList().size(); + + if(size > 0) { + final TextComponentString msg = new TextComponentString("\2477Macros [" + size + "]\247f "); + + for (int i = 0; i < size; i++) { + final Macro macro = Seppuku.INSTANCE.getMacroManager().getMacroList().get(i); + if (macro != null) { + msg.appendSibling(new TextComponentString("\247a" + macro.getName() + "\2477" + ((i == size - 1) ? "" : ", ")) + .setStyle(new Style() + .setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponentString("Key: " + macro.getKey().toUpperCase() + "\n" + "Macro: " + macro.getMacro()))))); + } + } + + Minecraft.getMinecraft().ingameGUI.getChatGUI().printChatMessage(msg); + }else{ + Seppuku.INSTANCE.logChat("You don't have any macros"); + } + } else if (equals(clearAlias, split[1])) { + if (!this.clamp(input, 2, 2)) { + this.printUsage(); + return; + } + + final int macros = Seppuku.INSTANCE.getMacroManager().getMacroList().size(); + + if(macros > 0) { + Seppuku.INSTANCE.logChat("Removed \247c" + macros + "\247f macro" + (macros > 1 ? "s" : "")); + Seppuku.INSTANCE.getMacroManager().getMacroList().clear(); + Seppuku.INSTANCE.getConfigManager().saveAll(); + }else{ + Seppuku.INSTANCE.logChat("You don't have any macros"); + } + } else { + Seppuku.INSTANCE.errorChat("Unknown input " + "\247f\"" + input + "\""); + this.printUsage(); + } + + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/command/ModuleCommand.java b/src/main/java/me/rigamortis/seppuku/impl/command/ModuleCommand.java new file mode 100644 index 0000000..b2fc7bf --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/command/ModuleCommand.java @@ -0,0 +1,48 @@ +package me.rigamortis.seppuku.impl.command; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.command.Command; +import me.rigamortis.seppuku.api.module.Module; +import me.rigamortis.seppuku.impl.module.hidden.CommandsModule; +import net.minecraft.client.Minecraft; +import net.minecraft.util.text.Style; +import net.minecraft.util.text.TextComponentString; +import net.minecraft.util.text.event.ClickEvent; +import net.minecraft.util.text.event.HoverEvent; + +/** + * Author Seth + * 5/1/2019 @ 7:59 PM. + */ +public final class ModuleCommand extends Command { + + public ModuleCommand() { + super("Modules", new String[]{"Mods"}, "Displays all modules", "Modules"); + } + + @Override + public void exec(String input) { + if (!this.clamp(input, 1, 1)) { + this.printUsage(); + return; + } + + final int size = Seppuku.INSTANCE.getModuleManager().getModuleList().size(); + + final TextComponentString msg = new TextComponentString("\2477Modules [" + size + "]\247f "); + + final CommandsModule commandsModule = (CommandsModule) Seppuku.INSTANCE.getModuleManager().find(CommandsModule.class); + + for (int i = 0; i < size; i++) { + final Module mod = Seppuku.INSTANCE.getModuleManager().getModuleList().get(i); + if (mod != null) { + msg.appendSibling(new TextComponentString((mod.isEnabled() ? "\247a" : "\247c") + mod.getDisplayName() + "\2477" + ((i == size - 1) ? "" : ", ")) + .setStyle(new Style() + .setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponentString("\2476" + (mod.getDesc() == null ? "There is no description for this module" : mod.getDesc()) + "\247f").appendSibling(new TextComponentString((mod.toUsageString() == null ? "" : "\n" + mod.toUsageString()) + "\247f")))) + .setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, commandsModule.getPrefix().getString() + "toggle" + " " + mod.getDisplayName())))); + } + } + + Minecraft.getMinecraft().ingameGUI.getChatGUI().printChatMessage(msg); + } +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/command/NameCommand.java b/src/main/java/me/rigamortis/seppuku/impl/command/NameCommand.java new file mode 100644 index 0000000..6d18068 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/command/NameCommand.java @@ -0,0 +1,34 @@ +package me.rigamortis.seppuku.impl.command; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.command.Command; +import net.minecraft.client.Minecraft; +import net.minecraft.util.Session; + +/** + * Author Seth + * 5/4/2019 @ 3:09 AM. + */ +public final class NameCommand extends Command { + + public NameCommand() { + super("Name", new String[] {"Nam"}, "Allows you to change the case of your name", "Name "); + } + + @Override + public void exec(String input) { + if (!this.clamp(input, 2, 2)) { + this.printUsage(); + return; + } + + final String[] split = input.split(" "); + + if(split[1].equalsIgnoreCase(Minecraft.getMinecraft().session.getUsername())) { + Minecraft.getMinecraft().session = new Session(split[1], Minecraft.getMinecraft().session.getPlayerID(), Minecraft.getMinecraft().session.getToken(), "mojang"); + Seppuku.INSTANCE.logChat("Set username to " + split[1]); + }else{ + Seppuku.INSTANCE.errorChat("Name must match"); + } + } +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/command/PeekCommand.java b/src/main/java/me/rigamortis/seppuku/impl/command/PeekCommand.java new file mode 100644 index 0000000..a292b74 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/command/PeekCommand.java @@ -0,0 +1,151 @@ +package me.rigamortis.seppuku.impl.command; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.command.Command; +import me.rigamortis.seppuku.api.event.render.EventRender2D; +import net.minecraft.block.Block; +import net.minecraft.block.BlockShulkerBox; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.inventory.GuiShulkerBox; +import net.minecraft.entity.Entity; +import net.minecraft.entity.item.EntityItemFrame; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Items; +import net.minecraft.item.Item; +import net.minecraft.item.ItemShulkerBox; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntityShulkerBox; +import net.minecraft.util.math.RayTraceResult; +import team.stiff.pomelo.impl.annotated.handler.annotation.Listener; + +/** + * Author Seth + * 4/17/2019 @ 12:18 AM. + */ +public final class PeekCommand extends Command { + + private String entity; + + public PeekCommand() { + super("Peek", new String[] {"Pk"}, "Allows you to see inside shulker boxes without having to place them", "Peek \nPeek"); + } + + @Override + public void exec(String input) { + if (!this.clamp(input, 1, 2)) { + this.printUsage(); + return; + } + + final String[] split = input.split(" "); + + if(split.length > 1) { + if (!this.clamp(input, 2, 2)) { + this.printUsage(); + return; + } + this.entity = split[1]; + } + + try { + Seppuku.INSTANCE.getEventManager().addEventListener(this); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Listener + public void render(EventRender2D event) { + try{ + final Minecraft mc = Minecraft.getMinecraft(); + + ItemStack stack = null; + + if(this.entity != null) { + EntityPlayer target = null; + + for(Entity e : mc.world.loadedEntityList) { + if(e != null) { + if(e instanceof EntityPlayer && e.getName().equalsIgnoreCase(this.entity)) { + target = (EntityPlayer) e; + } + } + } + + if(target != null) { + stack = getHeldShulker(target); + + if(stack == null) { + Seppuku.INSTANCE.errorChat("\"" + target.getName() + "\" is not holding a shulker box"); + this.entity = null; + Seppuku.INSTANCE.getEventManager().removeEventListener(this); + return; + } + }else{ + Seppuku.INSTANCE.errorChat("\"" + this.entity + "\" is not within range"); + } + this.entity = null; + }else{ + final RayTraceResult ray = mc.objectMouseOver; + + if(ray != null) { + if(ray.entityHit != null && ray.entityHit instanceof EntityItemFrame) { + final EntityItemFrame itemFrame = (EntityItemFrame) ray.entityHit; + if(itemFrame.getDisplayedItem() != null && itemFrame.getDisplayedItem().getItem() instanceof ItemShulkerBox) { + stack = itemFrame.getDisplayedItem(); + }else{ + stack = getHeldShulker(mc.player); + } + }else{ + stack = getHeldShulker(mc.player); + } + }else{ + stack = getHeldShulker(mc.player); + } + } + + if(stack != null) { + final Item item = stack.getItem(); + + if (item instanceof ItemShulkerBox) { + if (Block.getBlockFromItem(item) instanceof BlockShulkerBox) { + final BlockShulkerBox shulkerBox = (BlockShulkerBox) Block.getBlockFromItem(item); + if (shulkerBox != null) { + final NBTTagCompound tag = stack.getTagCompound(); + if(tag != null && tag.hasKey("BlockEntityTag", 10)) { + final NBTTagCompound entityTag = tag.getCompoundTag("BlockEntityTag"); + + final TileEntityShulkerBox te = new TileEntityShulkerBox(); + te.setWorld(mc.world); + te.readFromNBT(entityTag); + mc.displayGuiScreen(new GuiShulkerBox(mc.player.inventory, te)); + }else{ + Seppuku.INSTANCE.errorChat("This shulker box is empty"); + } + } + } + + } else { + Seppuku.INSTANCE.errorChat("Please hold a shulker box"); + } + }else{ + Seppuku.INSTANCE.errorChat("Please hold a shulker box"); + } + }catch (Exception e) { + e.printStackTrace(); + } + Seppuku.INSTANCE.getEventManager().removeEventListener(this); + } + + private ItemStack getHeldShulker(EntityPlayer entity) { + if(entity.getHeldItemMainhand() != null && entity.getHeldItemMainhand().getItem() instanceof ItemShulkerBox) { + return entity.getHeldItemMainhand(); + } + if(entity.getHeldItemOffhand() != null && entity.getHeldItemOffhand().getItem() instanceof ItemShulkerBox) { + return entity.getHeldItemOffhand(); + } + return null; + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/command/PitchCommand.java b/src/main/java/me/rigamortis/seppuku/impl/command/PitchCommand.java new file mode 100644 index 0000000..c243dd1 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/command/PitchCommand.java @@ -0,0 +1,40 @@ +package me.rigamortis.seppuku.impl.command; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.command.Command; +import me.rigamortis.seppuku.api.util.StringUtil; +import net.minecraft.client.Minecraft; + +/** + * Author Seth + * 5/3/2019 @ 5:31 PM. + */ +public final class PitchCommand extends Command { + + public PitchCommand() { + super("Pitch", new String[] {"Pch"}, "Allows you to set your pitch", "Pitch "); + } + + @Override + public void exec(String input) { + if (!this.clamp(input, 2, 2)) { + this.printUsage(); + return; + } + + final String[] split = input.split(" "); + + if (StringUtil.isDouble(split[1])) { + final float num = Float.parseFloat(split[1]); + + Minecraft.getMinecraft().player.rotationPitch = num; + if(Minecraft.getMinecraft().player.getRidingEntity() != null) { + Minecraft.getMinecraft().player.getRidingEntity().rotationPitch = num; + } + + Seppuku.INSTANCE.logChat("Set yaw to " + num); + } else { + Seppuku.INSTANCE.errorChat("Unknown number " + "\247f\"" + split[1] + "\""); + } + } +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/command/ReloadCommand.java b/src/main/java/me/rigamortis/seppuku/impl/command/ReloadCommand.java new file mode 100644 index 0000000..451facc --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/command/ReloadCommand.java @@ -0,0 +1,26 @@ +package me.rigamortis.seppuku.impl.command; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.command.Command; + +/** + * Author Seth + * 5/12/2019 @ 9:10 AM. + */ +public final class ReloadCommand extends Command { + + public ReloadCommand() { + super("Reload", new String[] {"Rload"}, "Reloads the client", "Reload"); + } + + @Override + public void exec(String input) { + if (!this.clamp(input, 1, 1)) { + this.printUsage(); + return; + } + + Seppuku.INSTANCE.reload(); + Seppuku.INSTANCE.logChat("Client Reloaded"); + } +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/command/RenameCommand.java b/src/main/java/me/rigamortis/seppuku/impl/command/RenameCommand.java new file mode 100644 index 0000000..acfb748 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/command/RenameCommand.java @@ -0,0 +1,66 @@ +package me.rigamortis.seppuku.impl.command; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.command.Command; +import net.minecraft.client.Minecraft; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.play.client.CPacketCreativeInventoryAction; + +/** + * Author Seth + * 8/15/2019 @ 10:27 PM. + */ +public final class RenameCommand extends Command { + + public RenameCommand() { + super("Rename", new String[]{"Ren"}, "Allows you to rename your held item while in creative mode(Supports color codes)", "Rename "); + } + + @Override + public void exec(String input) { + if (!this.clamp(input, 2)) { + this.printUsage(); + return; + } + + final Minecraft mc = Minecraft.getMinecraft(); + + if (!mc.player.isCreative()) { + Seppuku.INSTANCE.errorChat("Creative mode is required to use this command."); + return; + } + + final ItemStack itemStack = mc.player.getHeldItemMainhand(); + + if (itemStack.isEmpty()) { + Seppuku.INSTANCE.errorChat("Please hold an item in your main hand to enchant."); + return; + } + + final String[] split = input.split(" "); + + final StringBuilder sb = new StringBuilder(); + + final int size = split.length; + + for (int i = 1; i < size; i++) { + final String arg = split[i]; + sb.append(arg + ((i == size - 1) ? "" : " ")); + } + + final String name = sb.toString().replace("&", "\247"); + + NBTTagCompound tagCompound = itemStack.getTagCompound(); + + if (tagCompound == null) { + tagCompound = new NBTTagCompound(); + itemStack.setTagCompound(tagCompound); + } + + itemStack.getOrCreateSubCompound("display").setString("Name", name); + + mc.getConnection().sendPacket(new CPacketCreativeInventoryAction(mc.player.inventory.currentItem, itemStack)); + Seppuku.INSTANCE.logChat("Renamed your item to " + name); + } +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/command/SayCommand.java b/src/main/java/me/rigamortis/seppuku/impl/command/SayCommand.java new file mode 100644 index 0000000..b94ebc9 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/command/SayCommand.java @@ -0,0 +1,28 @@ +package me.rigamortis.seppuku.impl.command; + +import me.rigamortis.seppuku.api.command.Command; +import net.minecraft.client.Minecraft; +import net.minecraft.network.play.client.CPacketChatMessage; + +/** + * Author Seth + * 5/23/2019 @ 8:14 AM. + */ +public final class SayCommand extends Command { + + public SayCommand() { + super("Say", new String[] {"S"}, "Allows you to send a direct chat message", "Say "); + } + + @Override + public void exec(String input) { + if (!this.clamp(input, 2)) { + this.printUsage(); + return; + } + + final String[] split = input.split(" "); + + Minecraft.getMinecraft().player.connection.sendPacket(new CPacketChatMessage(input.substring(split[0].length() + 1))); + } +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/command/SeedCommand.java b/src/main/java/me/rigamortis/seppuku/impl/command/SeedCommand.java new file mode 100644 index 0000000..7f7bd88 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/command/SeedCommand.java @@ -0,0 +1,50 @@ +package me.rigamortis.seppuku.impl.command; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.command.Command; +import me.rigamortis.seppuku.api.util.StringUtil; +import me.rigamortis.seppuku.impl.management.WorldManager; +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.ServerData; + +/** + * Author Seth + * 6/11/2019 @ 7:15 AM. + */ +public final class SeedCommand extends Command { + + public SeedCommand() { + super("Seed", new String[] {"RandomSeed"}, "Sets the client-side seed used by certain features", "Seed "); + } + + @Override + public void exec(String input) { + if (!this.clamp(input, 2, 2)) { + this.printUsage(); + return; + } + + final String[] split = input.split(" "); + + if(StringUtil.isLong(split[1], 10)) { + final ServerData serverData = Minecraft.getMinecraft().getCurrentServerData(); + if(serverData != null) { + final WorldManager.WorldData worldData = Seppuku.INSTANCE.getWorldManager().find(serverData.serverIP); + if(worldData != null) { + final long seed = Long.parseLong(split[1]); + worldData.setSeed(seed); + Seppuku.INSTANCE.logChat("Set " + serverData.serverIP + "'s seed to " + seed); + }else{ + final long seed = Long.parseLong(split[1]); + Seppuku.INSTANCE.getWorldManager().getWorldDataList().add(new WorldManager.WorldData(serverData.serverIP, seed)); + Seppuku.INSTANCE.logChat("Set " + serverData.serverIP + "'s seed to " + seed); + } + Seppuku.INSTANCE.getConfigManager().saveAll(); + }else{ + Seppuku.INSTANCE.errorChat("Cannot set seed for localhost"); + } + }else{ + Seppuku.INSTANCE.errorChat("Unknown number " + "\247f\"" + split[1] + "\""); + } + } +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/command/SignBookCommand.java b/src/main/java/me/rigamortis/seppuku/impl/command/SignBookCommand.java new file mode 100644 index 0000000..e0d293a --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/command/SignBookCommand.java @@ -0,0 +1,49 @@ +package me.rigamortis.seppuku.impl.command; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.command.Command; +import net.minecraft.client.Minecraft; +import net.minecraft.item.ItemStack; +import net.minecraft.item.ItemWrittenBook; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagString; +import net.minecraft.network.play.client.CPacketCreativeInventoryAction; + +/** + * Author Seth + * 8/18/2019 @ 9:51 PM. + */ +public final class SignBookCommand extends Command { + + public SignBookCommand() { + super("SignBook", new String[] {"SBook", "SignB"}, "Allows you to change the author of a signed book while in creative", "SignBook "); + } + + @Override + public void exec(String input) { + if (!this.clamp(input, 2, 2)) { + this.printUsage(); + return; + } + + final Minecraft mc = Minecraft.getMinecraft(); + + if (!mc.player.isCreative()) { + Seppuku.INSTANCE.errorChat("Creative mode is required to use this command."); + return; + } + + final ItemStack itemStack = mc.player.inventory.getCurrentItem(); + + final String[] split = input.split(" "); + + if(itemStack.getItem() instanceof ItemWrittenBook) { + final NBTTagCompound tagCompound = (itemStack.hasTagCompound()) ? itemStack.getTagCompound() : new NBTTagCompound(); + tagCompound.setTag("author", new NBTTagString(split[1])); + mc.player.connection.sendPacket(new CPacketCreativeInventoryAction(36 + mc.player.inventory.currentItem, itemStack)); + Seppuku.INSTANCE.logChat("Signed book with username " + split[1]); + }else{ + Seppuku.INSTANCE.errorChat("Please hold a signed book"); + } + } +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/command/SkullCommand.java b/src/main/java/me/rigamortis/seppuku/impl/command/SkullCommand.java new file mode 100644 index 0000000..1a09a4e --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/command/SkullCommand.java @@ -0,0 +1,58 @@ +package me.rigamortis.seppuku.impl.command; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.command.Command; +import net.minecraft.client.Minecraft; +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.play.client.CPacketCreativeInventoryAction; + +/** + * Author Seth + * 8/18/2019 @ 10:29 PM. + */ +public final class SkullCommand extends Command { + + public SkullCommand() { + super("Skull", new String[] {"Skll"}, "Allows you to give yourself any player head while in creative", "Skull "); + } + + @Override + public void exec(String input) { + if (!this.clamp(input, 2, 2)) { + this.printUsage(); + return; + } + + final Minecraft mc = Minecraft.getMinecraft(); + + if (!mc.player.isCreative()) { + Seppuku.INSTANCE.errorChat("Creative mode is required to use this command."); + return; + } + + final String[] split = input.split(" "); + + final ItemStack itemStack = new ItemStack(Items.SKULL); + itemStack.setItemDamage(3); + itemStack.setTagCompound(new NBTTagCompound()); + itemStack.getTagCompound().setString("SkullOwner", split[1]); + + final int slot = this.findEmptyhotbar(); + + mc.player.connection.sendPacket(new CPacketCreativeInventoryAction(36 + (slot != -1 ? slot : mc.player.inventory.currentItem), itemStack)); + Seppuku.INSTANCE.logChat("Gave you skull with username " + split[1]); + } + + private int findEmptyhotbar() { + for (int i = 0; i < 9; i++) { + final ItemStack stack = Minecraft.getMinecraft().player.inventory.getStackInSlot(i); + + if (stack.getItem() == Items.AIR) { + return i; + } + } + return -1; + } +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/command/SpawnEggCommand.java b/src/main/java/me/rigamortis/seppuku/impl/command/SpawnEggCommand.java new file mode 100644 index 0000000..50fffa8 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/command/SpawnEggCommand.java @@ -0,0 +1,143 @@ +package me.rigamortis.seppuku.impl.command; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.command.Command; +import me.rigamortis.seppuku.api.util.StringUtil; +import net.minecraft.client.Minecraft; +import net.minecraft.entity.EntityList; +import net.minecraft.init.Items; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.play.client.CPacketCreativeInventoryAction; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.text.TextComponentString; + +import java.util.Iterator; + +/** + * Author Seth + * 8/16/2019 @ 3:30 AM. + */ +public final class SpawnEggCommand extends Command { + + private String[] listAlias = new String[]{"List", "L"}; + private String[] giveAlias = new String[]{"Give", "G"}; + + public SpawnEggCommand() { + super("SpawnEgg", new String[]{"SEgg"}, "Allows you to spawn in any spawn egg while in creative mode", "SpawnEgg Give \n" + + "SpawnEgg List"); + } + + @Override + public void exec(String input) { + if (!this.clamp(input, 2, 3)) { + this.printUsage(); + return; + } + + final String[] split = input.split(" "); + + final Minecraft mc = Minecraft.getMinecraft(); + + if (!mc.player.isCreative()) { + Seppuku.INSTANCE.errorChat("Creative mode is required to use this command."); + return; + } + + if (equals(listAlias, split[1])) { + if (!this.clamp(input, 2, 2)) { + this.printUsage(); + return; + } + + final int size = EntityList.getEntityNameList().size(); + + if (size > 0) { + final TextComponentString msg = new TextComponentString("\2477Entities [" + size + "]\247f "); + + final Iterator it = EntityList.getEntityNameList().iterator(); + + int index = 0; + + while (it.hasNext()) { + final ResourceLocation res = (ResourceLocation) it.next(); + if (res != null) { + msg.appendSibling(new TextComponentString("\247a" + res.getResourceDomain() + ":" + res.getResourcePath() + "\2477" + ((index == size - 1) ? "" : ", "))); + index++; + } + } + + Minecraft.getMinecraft().ingameGUI.getChatGUI().printChatMessage(msg); + } + } else if (equals(giveAlias, split[1])) { + if (!this.clamp(input, 3, 3)) { + this.printUsage(); + return; + } + + final ResourceLocation res = this.find(split[2]); + + if (res == null) { + final ResourceLocation similar = this.findSimilar(split[2]); + if (similar != null) { + Seppuku.INSTANCE.errorChat("Unknown entity " + "\247f\"" + split[2] + "\""); + Seppuku.INSTANCE.logChat("Did you mean " + "\247c" + similar.getResourcePath() + "\247f?"); + } + } else { + final ItemStack itemStack = new ItemStack(Item.getItemById(383)); + final NBTTagCompound tagCompound = (itemStack.hasTagCompound()) ? itemStack.getTagCompound() : new NBTTagCompound(); + final NBTTagCompound entityTag = new NBTTagCompound(); + + entityTag.setString("id", res.getResourceDomain() + ":" + res.getResourcePath()); + tagCompound.setTag("EntityTag", entityTag); + itemStack.setTagCompound(tagCompound); + + final int slot = this.findEmptyhotbar(); + + mc.player.connection.sendPacket(new CPacketCreativeInventoryAction(36 + (slot != -1 ? slot : mc.player.inventory.currentItem), itemStack)); + Seppuku.INSTANCE.logChat("Gave you a spawn egg with entity type: " + res.getResourceDomain() + ":" + res.getResourcePath()); + } + } else { + Seppuku.INSTANCE.errorChat("Unknown input " + "\247f\"" + input + "\""); + this.printUsage(); + } + } + + private ResourceLocation findSimilar(String name) { + ResourceLocation ret = null; + double similarity = 0.0f; + + for (ResourceLocation res : EntityList.getEntityNameList()) { + final double currentSimilarity = StringUtil.levenshteinDistance(name, res.getResourcePath()); + + if (currentSimilarity >= similarity) { + similarity = currentSimilarity; + ret = res; + } + } + + return ret; + } + + private ResourceLocation find(String name) { + for (ResourceLocation res : EntityList.getEntityNameList()) { + if (res.getResourcePath().equalsIgnoreCase(name)) { + return res; + } + } + return null; + } + + private int findEmptyhotbar() { + for (int i = 0; i < 9; i++) { + final ItemStack stack = Minecraft.getMinecraft().player.inventory.getStackInSlot(i); + + if (stack.getItem() == Items.AIR) { + return i; + } + } + return -1; + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/command/SpectateCommand.java b/src/main/java/me/rigamortis/seppuku/impl/command/SpectateCommand.java new file mode 100644 index 0000000..de749b1 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/command/SpectateCommand.java @@ -0,0 +1,47 @@ +package me.rigamortis.seppuku.impl.command; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.command.Command; +import net.minecraft.client.Minecraft; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.EntityPlayer; + +/** + * Author Seth + * 4/21/2019 @ 2:18 PM. + */ +public final class SpectateCommand extends Command { + + public SpectateCommand() { + super("Spectate", new String[]{"Spec"}, "Allows you to spectate nearby players", "Spectate "); + } + + @Override + public void exec(String input) { + if (!this.clamp(input, 2, 2)) { + this.printUsage(); + return; + } + + final String[] split = input.split(" "); + + EntityPlayer target = null; + + for (Entity e : Minecraft.getMinecraft().world.loadedEntityList) { + if (e != null) { + if (e instanceof EntityPlayer && e.getName().equalsIgnoreCase(split[1])) { + target = (EntityPlayer) e; + break; + } + } + } + + if (target != null) { + Seppuku.INSTANCE.logChat("Now spectating " + target.getName()); + Minecraft.getMinecraft().setRenderViewEntity(target); + }else{ + Seppuku.INSTANCE.errorChat("\"" + split[1] + "\" is not within range"); + } + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/command/StackSizeCommand.java b/src/main/java/me/rigamortis/seppuku/impl/command/StackSizeCommand.java new file mode 100644 index 0000000..8a82e4e --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/command/StackSizeCommand.java @@ -0,0 +1,51 @@ +package me.rigamortis.seppuku.impl.command; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.command.Command; +import me.rigamortis.seppuku.api.util.StringUtil; +import net.minecraft.client.Minecraft; +import net.minecraft.item.ItemStack; + +/** + * Author Seth + * 8/16/2019 @ 4:27 AM. + */ +public final class StackSizeCommand extends Command { + + public StackSizeCommand() { + super("StackSize", new String[]{"SS"}, "Allows you to change your held item stack size while in creative mode", "StackSize "); + } + + @Override + public void exec(String input) { + if (!this.clamp(input, 2, 2)) { + this.printUsage(); + return; + } + + final Minecraft mc = Minecraft.getMinecraft(); + + if (!mc.player.isCreative()) { + Seppuku.INSTANCE.errorChat("Creative mode is required to use this command."); + return; + } + + final ItemStack itemStack = mc.player.getHeldItemMainhand(); + + if (itemStack.isEmpty()) { + Seppuku.INSTANCE.errorChat("Please hold an item in your main hand to enchant."); + return; + } + + final String[] split = input.split(" "); + + if (StringUtil.isInt(split[1])) { + final int num = Integer.parseInt(split[1]); + itemStack.setCount(num); + itemStack.getItem().updateItemStackNBT(itemStack.getTagCompound()); + Seppuku.INSTANCE.logChat("Set your stack size to " + num); + } else { + Seppuku.INSTANCE.errorChat("Unknown number " + "\247f\"" + split[1] + "\""); + } + } +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/command/TeleportCommand.java b/src/main/java/me/rigamortis/seppuku/impl/command/TeleportCommand.java new file mode 100644 index 0000000..ce9b8cc --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/command/TeleportCommand.java @@ -0,0 +1,52 @@ +package me.rigamortis.seppuku.impl.command; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.command.Command; +import me.rigamortis.seppuku.api.util.StringUtil; +import net.minecraft.client.Minecraft; + +import java.text.DecimalFormat; + +/** + * Author Seth + * 6/18/2019 @ 9:24 AM. + */ +public final class TeleportCommand extends Command { + + public TeleportCommand() { + super("Teleport", new String[] {"Tp"}, "Allows you to teleport to coordinates", "Teleport "); + } + + @Override + public void exec(String input) { + if (!this.clamp(input, 4, 4)) { + this.printUsage(); + return; + } + + final String[] split = input.split(" "); + + if (StringUtil.isDouble(split[1])) { + if (StringUtil.isDouble(split[2])) { + if (StringUtil.isDouble(split[3])) { + final double x = Double.parseDouble(split[1]); + final double y = Double.parseDouble(split[2]); + final double z = Double.parseDouble(split[3]); + if (Minecraft.getMinecraft().player.getRidingEntity() != null) { + Minecraft.getMinecraft().player.getRidingEntity().setPosition(x, y, z); + } else { + Minecraft.getMinecraft().player.setPosition(x, y, z); + } + final DecimalFormat format = new DecimalFormat("##.##"); + Seppuku.INSTANCE.logChat("Teleported you to X: " + format.format(x) + " Y: " + format.format(y) + " Z: " + format.format(z)); + }else{ + Seppuku.INSTANCE.errorChat("Unknown number " + "\247f\"" + split[3] + "\""); + } + }else{ + Seppuku.INSTANCE.errorChat("Unknown number " + "\247f\"" + split[2] + "\""); + } + }else{ + Seppuku.INSTANCE.errorChat("Unknown number " + "\247f\"" + split[1] + "\""); + } + } +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/command/ToggleCommand.java b/src/main/java/me/rigamortis/seppuku/impl/command/ToggleCommand.java new file mode 100644 index 0000000..dadc491 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/command/ToggleCommand.java @@ -0,0 +1,87 @@ +package me.rigamortis.seppuku.impl.command; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.command.Command; +import me.rigamortis.seppuku.api.module.Module; +import me.rigamortis.seppuku.api.value.OptionalValue; + +/** + * Author Seth + * 4/16/2019 @ 9:01 PM. + */ +public final class ToggleCommand extends Command { + + public ToggleCommand() { + super("Toggle", new String[] {"T", "Tog"}, "Allows you to toggle modules or between two mode options", "Toggle \nToggle

+ * This results in perfect predictions when disregarding + * the randomness in the trajectory. + *

+ * todo; remove un-needed flightPoint collection + * + * @author Ddong + * @since Feb 18, 2017 + */ +public final class ProjectilesModule extends Module { + + private final Queue flightPoint = new ConcurrentLinkedQueue<>(); + + public ProjectilesModule() { + super("Projectiles", new String[]{"Proj"}, "Projects the possible path of an entity that was fired.", "NONE", -1, ModuleType.RENDER); + } + + @Listener + public void onRender(EventRender3D event) { + final Minecraft mc = Minecraft.getMinecraft(); + + ThrowableType throwingType = this.getTypeFromCurrentItem(mc.player); + + if (throwingType == ThrowableType.NONE) { + return; + } + + FlightPath flightPath = new FlightPath(mc.player, throwingType); + + while (!flightPath.isCollided()) { + flightPath.onUpdate(); + + flightPoint.offer(new Vec3d(flightPath.position.x - mc.getRenderManager().viewerPosX, + flightPath.position.y - mc.getRenderManager().viewerPosY, + flightPath.position.z - mc.getRenderManager().viewerPosZ)); + } + + final int hex = 0xFF9900EE; + float red = (hex >> 16 & 0xFF) / 255.0F; + float green = (hex >> 8 & 0xFF) / 255.0F; + float blue = (hex & 0xFF) / 255.0F; + float alpha = (hex >> 24 & 0xFF) / 255.0F; + + final boolean bobbing = mc.gameSettings.viewBobbing; + mc.gameSettings.viewBobbing = false; + mc.entityRenderer.setupCameraTransform(event.getPartialTicks(), 0); + GlStateManager.pushMatrix(); + GlStateManager.disableTexture2D(); + GlStateManager.enableBlend(); + GlStateManager.disableAlpha(); + GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0); + GlStateManager.shadeModel(GL_SMOOTH); + glLineWidth(1.5f); + glEnable(GL_LINE_SMOOTH); + glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); + GlStateManager.disableDepth(); + glEnable(GL32.GL_DEPTH_CLAMP); + final Tessellator tessellator = Tessellator.getInstance(); + final BufferBuilder bufferbuilder = tessellator.getBuffer(); + + while (!flightPoint.isEmpty()) { + bufferbuilder.begin(GL11.GL_LINE_STRIP, DefaultVertexFormats.POSITION_COLOR); + Vec3d head = flightPoint.poll(); + bufferbuilder.pos(head.x, head.y, head.z).color(red, green, blue, alpha).endVertex(); + + if (flightPoint.peek() != null) { + Vec3d point = flightPoint.peek(); + bufferbuilder.pos(point.x, point.y, point.z).color(red, green, blue, alpha).endVertex(); + } + + tessellator.draw(); + } + + GlStateManager.shadeModel(GL_FLAT); + glDisable(GL_LINE_SMOOTH); + GlStateManager.enableDepth(); + glDisable(GL32.GL_DEPTH_CLAMP); + GlStateManager.disableBlend(); + GlStateManager.enableAlpha(); + GlStateManager.enableTexture2D(); + GlStateManager.popMatrix(); + + mc.gameSettings.viewBobbing = bobbing; + mc.entityRenderer.setupCameraTransform(event.getPartialTicks(), 0); + + if (flightPath.collided) { + final RayTraceResult hit = flightPath.target; + AxisAlignedBB bb = null; + + if (hit.typeOfHit == RayTraceResult.Type.BLOCK) { + final BlockPos blockpos = hit.getBlockPos(); + final IBlockState iblockstate = mc.world.getBlockState(blockpos); + + if (iblockstate.getMaterial() != Material.AIR && mc.world.getWorldBorder().contains(blockpos)) { + final Vec3d interp = MathUtil.interpolateEntity(mc.player, mc.getRenderPartialTicks()); + bb = iblockstate.getSelectedBoundingBox(mc.world, blockpos).grow(0.0020000000949949026D).offset(-interp.x, -interp.y, -interp.z); + } + } else if (hit.typeOfHit == RayTraceResult.Type.ENTITY && hit.entityHit != null) { + final AxisAlignedBB entityBB = hit.entityHit.getEntityBoundingBox(); + if (entityBB != null) { + bb = new AxisAlignedBB(entityBB.minX - mc.getRenderManager().viewerPosX, entityBB.minY - mc.getRenderManager().viewerPosY, entityBB.minZ - mc.getRenderManager().viewerPosZ, entityBB.maxX - mc.getRenderManager().viewerPosX, entityBB.maxY - mc.getRenderManager().viewerPosY, entityBB.maxZ - mc.getRenderManager().viewerPosZ); + } + } + + if (bb != null) { + RenderUtil.drawBoundingBox(bb, 1.5f, hex); + } + } + } + + private ThrowableType getTypeFromCurrentItem(EntityPlayerSP player) { + // Check if we're holding an item first + if (player.getHeldItemMainhand() == null) { + return ThrowableType.NONE; + } + + final ItemStack itemStack = player.getHeldItem(EnumHand.MAIN_HAND); + // Check what type of item this is + switch (Item.getIdFromItem(itemStack.getItem())) { + case 261: // ItemBow + if (player.isHandActive()) + return ThrowableType.ARROW; + break; + case 346: // ItemFishingRod + return ThrowableType.FISHING_ROD; + case 438: //splash potion + case 441: //splash potion linger + return ThrowableType.POTION; + case 384: // ItemExpBottle + return ThrowableType.EXPERIENCE; + case 332: // ItemSnowball + case 344: // ItemEgg + case 368: // ItemEnderPearl + return ThrowableType.NORMAL; + default: + break; + } + + return ThrowableType.NONE; + } + + enum ThrowableType { + /** + * Represents a non-throwable object. + */ + NONE(0.0f, 0.0f), + + /** + * Arrows fired from a bow. + */ + ARROW(1.5f, 0.05f), + + /** + * Splash potion entities + */ + POTION(0.5f, 0.05f), + + /** + * Experience bottles. + */ + EXPERIENCE(0.7F, 0.07f), + + /** + * The fishhook entity with a fishing rod. + */ + FISHING_ROD(1.5f, 0.04f), + + /** + * Any throwable entity that doesn't have unique + * world velocity/gravity constants. + */ + NORMAL(1.5f, 0.03f); + + private final float velocity; + private final float gravity; + + ThrowableType(float velocity, float gravity) { + this.velocity = velocity; + this.gravity = gravity; + } + + /** + * The initial velocity of the entity. + * + * @return entity velocity + */ + + public float getVelocity() { + return velocity; + } + + /** + * The constant gravity applied to the entity. + * + * @return constant world gravity + */ + public float getGravity() { + return gravity; + } + } + + /** + * A class used to mimic the flight of an entity. Actual + * implementation resides in multiple classes but the parent of all + * of them is {@link net.minecraft.entity.projectile.EntityThrowable} + */ + final class FlightPath { + private EntityPlayerSP shooter; + private Vec3d position; + private Vec3d motion; + private float yaw; + private float pitch; + private AxisAlignedBB boundingBox; + private boolean collided; + private RayTraceResult target; + private ThrowableType throwableType; + + FlightPath(EntityPlayerSP player, ThrowableType throwableType) { + this.shooter = player; + this.throwableType = throwableType; + + // Set the starting angles of the entity + this.setLocationAndAngles(this.shooter.posX, this.shooter.posY + this.shooter.getEyeHeight(), this.shooter.posZ, + this.shooter.rotationYaw, this.shooter.rotationPitch); + + Vec3d startingOffset = new Vec3d(MathHelper.cos(this.yaw / 180.0F * (float) Math.PI) * 0.16F, 0.1d, + MathHelper.sin(this.yaw / 180.0F * (float) Math.PI) * 0.16F); + + this.position = this.position.subtract(startingOffset); + // Update the entity's bounding box + this.setPosition(this.position); + + // Set the entity's motion based on the shooter's rotations + this.motion = new Vec3d(-MathHelper.sin(this.yaw / 180.0F * (float) Math.PI) * MathHelper.cos(this.pitch / 180.0F * (float) Math.PI), + -MathHelper.sin(this.pitch / 180.0F * (float) Math.PI), + MathHelper.cos(this.yaw / 180.0F * (float) Math.PI) * MathHelper.cos(this.pitch / 180.0F * (float) Math.PI)); + + this.setThrowableHeading(this.motion, this.getInitialVelocity()); + } + + /** + * Update the entity's data in the world. + */ + public void onUpdate() { + // Get the predicted positions in the world + Vec3d prediction = this.position.add(this.motion); + // Check if we've collided with a block in the same time + RayTraceResult blockCollision = this.shooter.getEntityWorld().rayTraceBlocks(this.position, prediction, + this.throwableType == ThrowableType.FISHING_ROD, !this.collidesWithNoBoundingBox(), false); + // Check if we got a block collision + if (blockCollision != null) { + prediction = blockCollision.hitVec; + } + + // Check entity collision + this.onCollideWithEntity(prediction, blockCollision); + + // Check if we had a collision + if (this.target != null) { + this.collided = true; + // Update position + this.setPosition(this.target.hitVec); + return; + } + + // Sanity check to see if we've gone below the world (if we have we will never collide) + if (this.position.y <= 0.0d) { + // Force this to true even though we haven't collided with anything + this.collided = true; + return; + } + + // Update the entity's position based on velocity + this.position = this.position.add(this.motion); + float motionModifier = 0.99F; + // Check if our path will collide with water + if (this.shooter.getEntityWorld().isMaterialInBB(this.boundingBox, Material.WATER)) { + // Arrows move slower in water than normal throwables + motionModifier = this.throwableType == ThrowableType.ARROW ? 0.6F : 0.8F; + } + + // Apply the fishing rod specific motion modifier + if (this.throwableType == ThrowableType.FISHING_ROD) { + motionModifier = 0.92f; + } + + // Slowly decay the velocity of the path + this.motion = MathUtil.mult(this.motion, motionModifier); + // Drop the motionY by the constant gravity + this.motion = this.motion.subtract(0.0d, this.getGravityVelocity(), 0.0d); + // Update the position and bounding box + this.setPosition(this.position); + } + + /** + * Checks if a specific item type will collide + * with a block that has no collision bounding box. + * + * @return true if type collides + */ + private boolean collidesWithNoBoundingBox() { + switch (this.throwableType) { + case FISHING_ROD: + case NORMAL: + return true; + default: + return false; + } + } + + /** + * Check if our path collides with an entity. + * + * @param prediction the predicted position + * @param blockCollision block collision if we had one + */ + private void onCollideWithEntity(Vec3d prediction, RayTraceResult blockCollision) { + Entity collidingEntity = null; + RayTraceResult collidingPosition = null; + + double currentDistance = 0.0d; + // Get all possible collision entities disregarding the local player + List collisionEntities = Minecraft.getMinecraft().world.getEntitiesWithinAABBExcludingEntity(this.shooter, this.boundingBox.expand(this.motion.x, this.motion.y, this.motion.z).grow(1.0D, 1.0D, 1.0D)); + + // Loop through every loaded entity in the world + for (Entity entity : collisionEntities) { + // Check if we can collide with the entity or it's ourself + if (!entity.canBeCollidedWith()) { + continue; + } + + // Check if we collide with our bounding box + float collisionSize = entity.getCollisionBorderSize(); + AxisAlignedBB expandedBox = entity.getEntityBoundingBox().expand(collisionSize, collisionSize, collisionSize); + RayTraceResult objectPosition = expandedBox.calculateIntercept(this.position, prediction); + + // Check if we have a collision + if (objectPosition != null) { + double distanceTo = this.position.distanceTo(objectPosition.hitVec); + + // Check if we've gotten a closer entity + if (distanceTo < currentDistance || currentDistance == 0.0D) { + collidingEntity = entity; + collidingPosition = objectPosition; + currentDistance = distanceTo; + } + } + } + + // Check if we had an entity + if (collidingEntity != null) { + // Set our target to the result + this.target = new RayTraceResult(collidingEntity, collidingPosition.hitVec); + } else { + // Fallback to the block collision + this.target = blockCollision; + } + } + + /** + * Return the initial velocity of the entity at it's exact starting + * moment in flight. + * + * @return entity velocity in flight + */ + private float getInitialVelocity() { + switch (this.throwableType) { + // Arrows use the current use duration as a velocity multplier + case ARROW: + // Check how long we've been using the bow + int useDuration = this.shooter.getHeldItem(EnumHand.MAIN_HAND).getItem().getMaxItemUseDuration(this.shooter.getHeldItem(EnumHand.MAIN_HAND)) - this.shooter.getItemInUseCount(); + float velocity = (float) useDuration / 20.0F; + velocity = (velocity * velocity + velocity * 2.0F) / 3.0F; + if (velocity > 1.0F) { + velocity = 1.0F; + } + + // When the arrow is spawned inside of ItemBow, they multiply it by 2 + return (velocity * 2.0f) * throwableType.getVelocity(); + default: + return throwableType.getVelocity(); + } + } + + /** + * Get the constant gravity of the item in use. + * + * @return gravity relating to item + */ + private float getGravityVelocity() { + return throwableType.getGravity(); + } + + /** + * Set the position and rotation of the entity in the world. + * + * @param x x position in world + * @param y y position in world + * @param z z position in world + * @param yaw yaw rotation axis + * @param pitch pitch rotation axis + */ + private void setLocationAndAngles(double x, double y, double z, float yaw, float pitch) { + this.position = new Vec3d(x, y, z); + this.yaw = yaw; + this.pitch = pitch; + } + + /** + * Sets the x,y,z of the entity from the given parameters. Also seems to set + * up a bounding box. + * + * @param position position in world + */ + private void setPosition(Vec3d position) { + this.position = new Vec3d(position.x, position.y, position.z); + // Usually this is this.width / 2.0f but throwables change + double entitySize = (this.throwableType == ThrowableType.ARROW ? 0.5d : 0.25d) / 2.0d; + // Update the path's current bounding box + this.boundingBox = new AxisAlignedBB(position.x - entitySize, + position.y - entitySize, + position.z - entitySize, + position.x + entitySize, + position.y + entitySize, + position.z + entitySize); + } + + /** + * Set the entity's velocity and position in the world. + * + * @param motion velocity in world + * @param velocity starting velocity + */ + private void setThrowableHeading(Vec3d motion, float velocity) { + // Divide the current motion by the length of the vector + this.motion = MathUtil.div(motion, (float) motion.lengthVector()); + // Multiply by the velocity + this.motion = MathUtil.mult(this.motion, velocity); + } + + /** + * Check if the path has collided with an object. + * + * @return path collides with ground + */ + public boolean isCollided() { + return collided; + } + + /** + * Get the target we've collided with if it exists. + * + * @return moving object target + */ + public RayTraceResult getCollidingTarget() { + return target; + } + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/module/render/SmallShieldModule.java b/src/main/java/me/rigamortis/seppuku/impl/module/render/SmallShieldModule.java new file mode 100644 index 0000000..c24636e --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/module/render/SmallShieldModule.java @@ -0,0 +1,26 @@ +package me.rigamortis.seppuku.impl.module.render; + +import me.rigamortis.seppuku.api.module.Module; +import net.minecraft.client.renderer.ItemRenderer; +import net.minecraft.client.Minecraft; +import team.stiff.pomelo.impl.annotated.handler.annotation.Listener; +import me.rigamortis.seppuku.api.event.player.EventPlayerUpdate; + +/** + * Author fsck + * 2019-10-20. + */ +public final class SmallShieldModule extends Module { + + final Minecraft mc = Minecraft.getMinecraft(); + ItemRenderer itemRenderer = Minecraft.getMinecraft().entityRenderer.itemRenderer; + + public SmallShieldModule() { + super("SmallShield", new String[]{"SmallShield", "SS"}, "Smaller shield", "NONE", -1, ModuleType.RENDER); + } + + @Listener + public void changeOffhandProgress(EventPlayerUpdate event){ + itemRenderer.equippedProgressOffHand = 0.5F; + } +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/module/render/StorageESPModule.java b/src/main/java/me/rigamortis/seppuku/impl/module/render/StorageESPModule.java new file mode 100644 index 0000000..00d68e3 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/module/render/StorageESPModule.java @@ -0,0 +1,262 @@ +package me.rigamortis.seppuku.impl.module.render; + +import me.rigamortis.seppuku.api.event.render.EventRender2D; +import me.rigamortis.seppuku.api.event.render.EventRender3D; +import me.rigamortis.seppuku.api.module.Module; +import me.rigamortis.seppuku.api.util.ColorUtil; +import me.rigamortis.seppuku.api.util.GLUProjection; +import me.rigamortis.seppuku.api.util.RenderUtil; +import me.rigamortis.seppuku.api.value.BooleanValue; +import me.rigamortis.seppuku.api.value.NumberValue; +import me.rigamortis.seppuku.api.value.OptionalValue; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.culling.Frustum; +import net.minecraft.client.renderer.culling.ICamera; +import net.minecraft.tileentity.*; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.Vec3d; +import org.lwjgl.opengl.GL11; +import team.stiff.pomelo.impl.annotated.handler.annotation.Listener; + +/** + * Author Seth + * 5/17/2019 @ 8:45 PM. + */ +public final class StorageESPModule extends Module { + + public final OptionalValue mode = new OptionalValue("Mode", new String[]{"Mode", "M"}, 1, new String[]{"2D", "3D"}); + public final BooleanValue name = new BooleanValue("Name", new String[]{"Nam", "N", "Names"}, true); + public final NumberValue opacity = new NumberValue("Opacity", new String[]{"Opacity", "Transparency", "Alpha"}, 128, Integer.class, 0, 255, 1); + //(String displayName, String[] alias, Object value, Object type, T min, T max, T increment + + private ICamera camera = new Frustum(); + + public StorageESPModule() { + super("Storage", new String[]{"StorageESP", "ChestFinder", "ChestESP"}, "Highlights different types of storage entities", "NONE", -1, ModuleType.RENDER); + } + + @Listener + public void render2D(EventRender2D event) { + final Minecraft mc = Minecraft.getMinecraft(); + + if (this.mode.getInt() == 1 && !this.name.getBoolean()) // if 3D and names are off, return + return; + + for (TileEntity te : mc.world.loadedTileEntityList) { + if (te != null) { + if (this.isTileStorage(te)) { + final AxisAlignedBB bb = this.boundingBoxForEnt(te); + if (bb != null) { + final float[] bounds = this.convertBounds(bb, event.getScaledResolution().getScaledWidth(), event.getScaledResolution().getScaledHeight()); + if (bounds != null) { + if (this.mode.getInt() == 0) { // 2D + RenderUtil.drawOutlineRect(bounds[0], bounds[1], bounds[2], bounds[3], 1.5f, ColorUtil.changeAlpha(0xAA000000, opacity.getInt())); + RenderUtil.drawOutlineRect(bounds[0] - 0.5f, bounds[1] - 0.5f, bounds[2] + 0.5f, bounds[3] + 0.5f, 0.5f, ColorUtil.changeAlpha(this.getColor(te), opacity.getInt())); + } + + if (this.name.getBoolean()) { + final String name = te.getBlockType().getLocalizedName(); + GL11.glEnable(GL11.GL_BLEND); + mc.fontRenderer.drawStringWithShadow(name, bounds[0] + (bounds[2] - bounds[0]) / 2 - mc.fontRenderer.getStringWidth(name) / 2, bounds[1] + (bounds[3] - bounds[1]) - mc.fontRenderer.FONT_HEIGHT - 1, ColorUtil.changeAlpha(0xFFFFFFFF, opacity.getInt())); + GL11.glDisable(GL11.GL_BLEND); + } + } + } + } + } + } + } + + @Listener + public void render3D(EventRender3D event) { + final Minecraft mc = Minecraft.getMinecraft(); + if (this.mode.getInt() == 1) { + for (TileEntity te : mc.world.loadedTileEntityList) { + if (te != null) { + if (this.isTileStorage(te)) { + final AxisAlignedBB bb = this.boundingBoxForEnt(te); + if (bb != null) { + camera.setPosition(mc.getRenderViewEntity().posX, mc.getRenderViewEntity().posY, mc.getRenderViewEntity().posZ); + + if (camera.isBoundingBoxInFrustum(new AxisAlignedBB(bb.minX + mc.getRenderManager().viewerPosX, + bb.minY + mc.getRenderManager().viewerPosY, + bb.minZ + mc.getRenderManager().viewerPosZ, + bb.maxX + mc.getRenderManager().viewerPosX, + bb.maxY + mc.getRenderManager().viewerPosY, + bb.maxZ + mc.getRenderManager().viewerPosZ))) { + RenderUtil.drawFilledBox(bb, ColorUtil.changeAlpha(this.getColor(te), opacity.getInt())); + RenderUtil.drawBoundingBox(bb, 1.5f, ColorUtil.changeAlpha(this.getColor(te), opacity.getInt())); + } + } + } + } + } + } + } + + private boolean isTileStorage(TileEntity te) { + if (te instanceof TileEntityChest) { + return true; + } + if (te instanceof TileEntityDispenser) { + return true; + } + if (te instanceof TileEntityDropper) { + return true; + } + if (te instanceof TileEntityFurnace) { + return true; + } + if (te instanceof TileEntityBrewingStand) { + return true; + } + if (te instanceof TileEntityEnderChest) { + return true; + } + if (te instanceof TileEntityHopper) { + return true; + } + if (te instanceof TileEntityShulkerBox) { + return true; + } + return false; + } + + private AxisAlignedBB boundingBoxForEnt(TileEntity te) { + final Minecraft mc = Minecraft.getMinecraft(); + + if (te != null) { + if (te instanceof TileEntityChest) { + TileEntityChest chest = (TileEntityChest) te; + if (chest.adjacentChestXNeg != null) { + return new AxisAlignedBB( + te.getPos().getX() + 0.0625d - 1 - mc.getRenderManager().viewerPosX, + te.getPos().getY() - mc.getRenderManager().viewerPosY, + te.getPos().getZ() + 0.0625d - mc.getRenderManager().viewerPosZ, + + te.getPos().getX() + 0.9375d - mc.getRenderManager().viewerPosX, + te.getPos().getY() + 0.875d - mc.getRenderManager().viewerPosY, + te.getPos().getZ() + 0.9375d - mc.getRenderManager().viewerPosZ); + } else if (chest.adjacentChestZPos != null) { + return new AxisAlignedBB( + te.getPos().getX() + 0.0625d - mc.getRenderManager().viewerPosX, + te.getPos().getY() - mc.getRenderManager().viewerPosY, + te.getPos().getZ() + 0.0625d - mc.getRenderManager().viewerPosZ, + + te.getPos().getX() + 0.9375d - mc.getRenderManager().viewerPosX, + te.getPos().getY() + 0.875d - mc.getRenderManager().viewerPosY, + te.getPos().getZ() + 0.9375d + 1 - mc.getRenderManager().viewerPosZ); + } else if (chest.adjacentChestXPos == null && chest.adjacentChestZPos == null && chest.adjacentChestZNeg == null && chest.adjacentChestXNeg == null) { + return new AxisAlignedBB( + te.getPos().getX() + 0.0625d - mc.getRenderManager().viewerPosX, + te.getPos().getY() - mc.getRenderManager().viewerPosY, + te.getPos().getZ() + 0.0625d - mc.getRenderManager().viewerPosZ, + + te.getPos().getX() + 0.9375d - mc.getRenderManager().viewerPosX, + te.getPos().getY() + 0.875d - mc.getRenderManager().viewerPosY, + te.getPos().getZ() + 0.9375d - mc.getRenderManager().viewerPosZ); + } + } else if (te instanceof TileEntityEnderChest) { + return new AxisAlignedBB( + te.getPos().getX() + 0.0625d - mc.getRenderManager().viewerPosX, + te.getPos().getY() - mc.getRenderManager().viewerPosY, + te.getPos().getZ() + 0.0625d - mc.getRenderManager().viewerPosZ, + + te.getPos().getX() + 0.9375d - mc.getRenderManager().viewerPosX, + te.getPos().getY() + 0.875d - mc.getRenderManager().viewerPosY, + te.getPos().getZ() + 0.9375d - mc.getRenderManager().viewerPosZ); + } else { + return new AxisAlignedBB( + te.getPos().getX() - mc.getRenderManager().viewerPosX, + te.getPos().getY() - mc.getRenderManager().viewerPosY, + te.getPos().getZ() - mc.getRenderManager().viewerPosZ, + + te.getPos().getX() + 1 - mc.getRenderManager().viewerPosX, + te.getPos().getY() + 1 - mc.getRenderManager().viewerPosY, + te.getPos().getZ() + 1 - mc.getRenderManager().viewerPosZ); + } + } + + return null; + } + + + private int getColor(TileEntity te) { + if (te instanceof TileEntityChest) { + return 0xFFFFC417; + } + if (te instanceof TileEntityDispenser) { + return 0xFF4E4E4E; + } + if (te instanceof TileEntityDropper) { + return 0xFF4E4E4E; + } + if (te instanceof TileEntityHopper) { + return 0xFF4E4E4E; + } + if (te instanceof TileEntityFurnace) { + return 0xFF2D2D2D; + } + if (te instanceof TileEntityBrewingStand) { + return 0xFF17B9D2; + } + if (te instanceof TileEntityEnderChest) { + return 0xFF17A25C; + } + if (te instanceof TileEntityShulkerBox) { + final TileEntityShulkerBox shulkerBox = (TileEntityShulkerBox) te; + return (255 << 24) | shulkerBox.getColor().getColorValue() & 0xFFFFFFFF; + } + return 0xFFFFFFFF; + } + + private float[] convertBounds(AxisAlignedBB bb, int width, int height) { + float x = -1; + float y = -1; + float w = width + 1; + float h = height + 1; + + camera.setPosition(Minecraft.getMinecraft().getRenderViewEntity().posX, Minecraft.getMinecraft().getRenderViewEntity().posY, Minecraft.getMinecraft().getRenderViewEntity().posZ); + + if (!camera.isBoundingBoxInFrustum(new AxisAlignedBB(bb.minX + Minecraft.getMinecraft().getRenderManager().viewerPosX, + bb.minY + Minecraft.getMinecraft().getRenderManager().viewerPosY, + bb.minZ + Minecraft.getMinecraft().getRenderManager().viewerPosZ, + bb.maxX + Minecraft.getMinecraft().getRenderManager().viewerPosX, + bb.maxY + Minecraft.getMinecraft().getRenderManager().viewerPosY, + bb.maxZ + Minecraft.getMinecraft().getRenderManager().viewerPosZ))) { + return null; + } + + final Vec3d corners[] = { + new Vec3d(bb.minX, bb.minY, bb.minZ), + new Vec3d(bb.maxX, bb.maxY, bb.maxZ), + new Vec3d(bb.minX, bb.maxY, bb.maxZ), + new Vec3d(bb.minX, bb.minY, bb.maxZ), + new Vec3d(bb.maxX, bb.minY, bb.maxZ), + new Vec3d(bb.maxX, bb.minY, bb.minZ), + new Vec3d(bb.maxX, bb.maxY, bb.minZ), + new Vec3d(bb.minX, bb.maxY, bb.minZ) + }; + + for (Vec3d vec : corners) { + final GLUProjection.Projection projection = GLUProjection.getInstance().project(vec.x, vec.y, vec.z, GLUProjection.ClampMode.NONE, true); + + if (projection == null) { + return null; + } + + x = Math.max(x, (float) projection.getX()); + y = Math.max(y, (float) projection.getY()); + + w = Math.min(w, (float) projection.getX()); + h = Math.min(h, (float) projection.getY()); + } + + if (x != -1 && y != -1 && w != width + 1 && h != height + 1) { + return new float[]{x, y, w, h}; + } + + return null; + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/module/render/TracersModule.java b/src/main/java/me/rigamortis/seppuku/impl/module/render/TracersModule.java new file mode 100644 index 0000000..31e70f7 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/module/render/TracersModule.java @@ -0,0 +1,145 @@ +package me.rigamortis.seppuku.impl.module.render; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.event.render.EventRender2D; +import me.rigamortis.seppuku.api.event.render.EventRender3D; +import me.rigamortis.seppuku.api.module.Module; +import me.rigamortis.seppuku.api.util.GLUProjection; +import me.rigamortis.seppuku.api.util.MathUtil; +import me.rigamortis.seppuku.api.util.RenderUtil; +import me.rigamortis.seppuku.api.value.BooleanValue; +import me.rigamortis.seppuku.api.value.NumberValue; +import me.rigamortis.seppuku.api.value.OptionalValue; +import net.minecraft.client.Minecraft; +import net.minecraft.entity.Entity; +import net.minecraft.entity.item.EntityBoat; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.entity.item.EntityMinecart; +import net.minecraft.entity.item.EntityMinecartContainer; +import net.minecraft.entity.monster.IMob; +import net.minecraft.entity.passive.IAnimals; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.math.Vec2f; +import net.minecraft.util.math.Vec3d; +import team.stiff.pomelo.impl.annotated.handler.annotation.Listener; + +/** + * Author Seth + * 4/23/2019 @ 4:05 AM. + */ +public final class TracersModule extends Module { + + public final BooleanValue players = new BooleanValue("Players", new String[]{"Player"}, true); + public final BooleanValue mobs = new BooleanValue("Mobs", new String[]{"Mob"}, true); + public final BooleanValue animals = new BooleanValue("Animals", new String[]{"Animal"}, true); + public final BooleanValue vehicles = new BooleanValue("Vehicles", new String[]{"Vehic", "Vehicle"}, true); + public final BooleanValue items = new BooleanValue("Items", new String[]{"Item"}, true); + + public final OptionalValue mode = new OptionalValue("Mode", new String[]{"Mode"}, 0, new String[]{"2D", "3D"}); + + public final NumberValue width = new NumberValue("Width", new String[]{"Wid"}, 0.5f, Float.class, 0.0f, 5.0f, 0.1f); + + public TracersModule() { + super("Tracers", new String[]{"Trace", "Tracer", "Snapline", "Snaplines"}, "Draws a line to entities", "NONE", -1, ModuleType.RENDER); + } + + @Override + public String getMetaData() { + return this.mode.getSelectedOption(); + } + + @Listener + public void render2D(EventRender2D event) { + if (this.mode.getInt() == 0) { + final Minecraft mc = Minecraft.getMinecraft(); + + for (Entity e : mc.world.loadedEntityList) { + if (e != null) { + if (this.checkFilter(e)) { + final Vec3d pos = MathUtil.interpolateEntity(e, event.getPartialTicks()); + + if (pos != null) { + final GLUProjection.Projection projection = GLUProjection.getInstance().project(pos.x - mc.getRenderManager().viewerPosX, pos.y - mc.getRenderManager().viewerPosY, pos.z - mc.getRenderManager().viewerPosZ, GLUProjection.ClampMode.NONE, true); + if (projection != null) { + RenderUtil.drawLine((float) projection.getX(), (float) projection.getY(), event.getScaledResolution().getScaledWidth() / 2, event.getScaledResolution().getScaledHeight() / 2, this.width.getFloat(), this.getColor(e)); + } + } + } + } + } + } + } + + @Listener + public void render3D(EventRender3D event) { + if (this.mode.getInt() == 1) { + final Minecraft mc = Minecraft.getMinecraft(); + + for (Entity e : mc.world.loadedEntityList) { + if (e != null) { + if (this.checkFilter(e)) { + final Vec3d pos = MathUtil.interpolateEntity(e, event.getPartialTicks()).subtract(mc.getRenderManager().renderPosX, mc.getRenderManager().renderPosY, mc.getRenderManager().renderPosZ); + + if (pos != null) { + final boolean bobbing = mc.gameSettings.viewBobbing; + mc.gameSettings.viewBobbing = false; + mc.entityRenderer.setupCameraTransform(event.getPartialTicks(), 0); + final Vec3d forward = new Vec3d(0, 0, 1).rotatePitch(-(float) Math.toRadians(Minecraft.getMinecraft().player.rotationPitch)).rotateYaw(-(float) Math.toRadians(Minecraft.getMinecraft().player.rotationYaw)); + RenderUtil.drawLine3D((float) forward.x, (float) forward.y + mc.player.getEyeHeight(), (float) forward.z, (float) pos.x, (float) pos.y, (float) pos.z, this.width.getFloat(), this.getColor(e)); + mc.gameSettings.viewBobbing = bobbing; + mc.entityRenderer.setupCameraTransform(event.getPartialTicks(), 0); + } + } + } + } + } + } + + private boolean checkFilter(Entity entity) { + boolean ret = false; + + if (this.players.getBoolean() && entity instanceof EntityPlayer && entity != Minecraft.getMinecraft().player) { + ret = true; + } + if (this.mobs.getBoolean() && entity instanceof IMob) { + ret = true; + } + if (this.animals.getBoolean() && entity instanceof IAnimals && !(entity instanceof IMob)) { + ret = true; + } + if (this.vehicles.getBoolean() && (entity instanceof EntityBoat || entity instanceof EntityMinecart || entity instanceof EntityMinecartContainer)) { + ret = true; + } + if (this.items.getBoolean() && entity instanceof EntityItem) { + ret = true; + } + + return ret; + } + + private int getColor(Entity entity) { + int ret = -1; + + if (entity instanceof IAnimals && !(entity instanceof IMob)) { + ret = 0xFF00FF44; + } + if (entity instanceof IMob) { + ret = 0xFFFFAA00; + } + if (entity instanceof EntityBoat || entity instanceof EntityMinecart || entity instanceof EntityMinecartContainer) { + ret = 0xFF00FFAA; + } + if (entity instanceof EntityItem) { + ret = 0xFF00FFAA; + } + if (entity instanceof EntityPlayer) { + ret = 0xFFFF4444; + + if (Seppuku.INSTANCE.getFriendManager().isFriend(entity) != null) { + ret = 0xFF9900EE; + } + } + return ret; + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/module/render/ViewClipModule.java b/src/main/java/me/rigamortis/seppuku/impl/module/render/ViewClipModule.java new file mode 100644 index 0000000..b7933ac --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/module/render/ViewClipModule.java @@ -0,0 +1,22 @@ +package me.rigamortis.seppuku.impl.module.render; + +import me.rigamortis.seppuku.api.event.render.EventOrientCamera; +import me.rigamortis.seppuku.api.module.Module; +import team.stiff.pomelo.impl.annotated.handler.annotation.Listener; + +/** + * Author Seth + * 7/22/2019 @ 8:54 AM. + */ +public final class ViewClipModule extends Module { + + public ViewClipModule() { + super("ViewClip", new String[] {"ViewC"}, "Prevents the third person camera from ray-tracing", "NONE", -1, ModuleType.RENDER); + } + + @Listener + public void orientCamera(EventOrientCamera event) { + event.setCanceled(true); + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/module/render/WallHackModule.java b/src/main/java/me/rigamortis/seppuku/impl/module/render/WallHackModule.java new file mode 100644 index 0000000..83707c1 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/module/render/WallHackModule.java @@ -0,0 +1,578 @@ +package me.rigamortis.seppuku.impl.module.render; + +import com.google.common.collect.Lists; +import com.mojang.realmsclient.gui.ChatFormatting; +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.event.EventStageable; +import me.rigamortis.seppuku.api.event.network.EventReceivePacket; +import me.rigamortis.seppuku.api.event.render.EventRender2D; +import me.rigamortis.seppuku.api.event.render.EventRenderName; +import me.rigamortis.seppuku.api.friend.Friend; +import me.rigamortis.seppuku.api.module.Module; +import me.rigamortis.seppuku.api.util.*; +import me.rigamortis.seppuku.api.value.BooleanValue; +import me.rigamortis.seppuku.api.value.OptionalValue; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.client.renderer.culling.Frustum; +import net.minecraft.client.renderer.culling.ICamera; +import net.minecraft.enchantment.Enchantment; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.item.*; +import net.minecraft.entity.monster.IMob; +import net.minecraft.entity.passive.IAnimals; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Items; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.network.play.server.SPacketSoundEffect; +import net.minecraft.potion.Potion; +import net.minecraft.potion.PotionEffect; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.StringUtils; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.Vec3d; +import team.stiff.pomelo.impl.annotated.handler.annotation.Listener; + +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +/** + * Author Seth + * 4/20/2019 @ 10:07 AM. + */ +public final class WallHackModule extends Module { + + public final OptionalValue mode = new OptionalValue("Mode", new String[]{"Mode", "M"}, 0, new String[]{"None", "Box"}); + + public final BooleanValue players = new BooleanValue("Players", new String[]{"Player"}, true); + public final BooleanValue mobs = new BooleanValue("Mobs", new String[]{"Mob"}, true); + public final BooleanValue animals = new BooleanValue("Animals", new String[]{"Animal"}, true); + public final BooleanValue vehicles = new BooleanValue("Vehicles", new String[]{"Vehic", "Vehicle"}, true); + public final BooleanValue local = new BooleanValue("Local", new String[]{"Self"}, true); + public final BooleanValue items = new BooleanValue("Items", new String[]{"Item"}, true); + public final BooleanValue footsteps = new BooleanValue("FootSteps", new String[]{"FootStep", "Steps"}, true); + public final BooleanValue armorStand = new BooleanValue("ArmorStands", new String[]{"ArmorStand", "ArmourStand", "ArmourStands", "ArmStand"}, true); + + public final BooleanValue name = new BooleanValue("Name", new String[]{"Nam"}, true); + public final BooleanValue ping = new BooleanValue("Ping", new String[]{"Ms"}, true); + public final BooleanValue armor = new BooleanValue("Armor", new String[]{"Arm"}, true); + public final BooleanValue hearts = new BooleanValue("Hearts", new String[]{"Hrts"}, true); + public final BooleanValue enchants = new BooleanValue("Enchants", new String[]{"Ench"}, true); + public final OptionalValue potions = new OptionalValue("Potions", new String[]{"Pot", "Pots", "PotsMode"}, 1, new String[]{"None", "Icons", "Text"}); + + public final BooleanValue background = new BooleanValue("Background", new String[]{"Bg"}, true); + + public final OptionalValue hpMode = new OptionalValue("Hp", new String[]{"Health", "HpMode"}, 0, new String[]{"None", "Bar", "BarText"}); + + private ICamera camera = new Frustum(); + private final ResourceLocation inventory = new ResourceLocation("textures/gui/container/inventory.png"); + + //i cba + private List footstepDataList = new CopyOnWriteArrayList<>(); + + public WallHackModule() { + super("WallHack", new String[]{"Esp"}, "Highlights entities", "NONE", -1, ModuleType.RENDER); + } + + @Listener + public void render2D(EventRender2D event) { + final Minecraft mc = Minecraft.getMinecraft(); + + if (this.footsteps.getBoolean()) { + for (FootstepData data : this.footstepDataList) { + final GLUProjection.Projection projection = GLUProjection.getInstance().project(data.x - mc.getRenderManager().viewerPosX, data.y - mc.getRenderManager().viewerPosY, data.z - mc.getRenderManager().viewerPosZ, GLUProjection.ClampMode.NONE, false); + if (projection != null && projection.getType() == GLUProjection.Projection.Type.INSIDE) { + mc.fontRenderer.drawStringWithShadow("*step*", (float) projection.getX() - mc.fontRenderer.getStringWidth("*step*") / 2, (float) projection.getY(), -1); + } + + if (Math.abs(System.currentTimeMillis() - data.getTime()) >= 3000) { + this.footstepDataList.remove(data); + } + } + } + + for (Entity e : mc.world.loadedEntityList) { + if (e != null) { + if (this.checkFilter(e)) { + final float[] bounds = this.convertBounds(e, event.getPartialTicks(), event.getScaledResolution().getScaledWidth(), event.getScaledResolution().getScaledHeight()); + + if (bounds != null) { + if (this.mode.getInt() == 1) { + RenderUtil.drawOutlineRect(bounds[0], bounds[1], bounds[2], bounds[3], 1.5f, 0xAA000000); + RenderUtil.drawOutlineRect(bounds[0] - 0.5f, bounds[1] - 0.5f, bounds[2] + 0.5f, bounds[3] + 0.5f, 0.5f, this.getColor(e)); + } + + String name = StringUtils.stripControlCodes(getNameForEntity(e)); + String heartsFormatted = null; + String pingFormatted = null; + + if (this.name.getBoolean()) { + int color = -1; + + final Friend friend = Seppuku.INSTANCE.getFriendManager().isFriend(e); + + if (friend != null) { + name = friend.getAlias(); + color = 0xFF9900EE; + } + + if (this.background.getBoolean()) { + RenderUtil.drawRect(bounds[0] + (bounds[2] - bounds[0]) / 2 - mc.fontRenderer.getStringWidth(name) / 2 - 1, bounds[1] + (bounds[3] - bounds[1]) - mc.fontRenderer.FONT_HEIGHT - 2, bounds[0] + (bounds[2] - bounds[0]) / 2 + mc.fontRenderer.getStringWidth(name) / 2 + 1, bounds[1] + (bounds[3] - bounds[1]) - 1, 0x75101010); + } + + mc.fontRenderer.drawStringWithShadow(name, bounds[0] + (bounds[2] - bounds[0]) / 2 - mc.fontRenderer.getStringWidth(name) / 2, bounds[1] + (bounds[3] - bounds[1]) - mc.fontRenderer.FONT_HEIGHT - 1, color); + } + + if (e instanceof EntityPlayer) { + final EntityPlayer player = (EntityPlayer) e; + if (this.ping.getBoolean()) { + final int responseTime = (int) MathUtil.clamp(mc.getConnection().getPlayerInfo(player.getUniqueID()).getResponseTime(), 0, 300); + pingFormatted = responseTime + "ms"; + + float startX = -mc.fontRenderer.getStringWidth(pingFormatted) / 2.0f; + if (this.name.getBoolean()) + startX = (mc.fontRenderer.getStringWidth(name) / 2.0f) + 2.0f; + else if (this.hearts.getBoolean()) + startX = (mc.fontRenderer.getStringWidth(heartsFormatted) / 2.0f) + (mc.fontRenderer.getStringWidth(heartsFormatted) / 2.0f); + + int pingRounded = Math.round(255.0f - (responseTime * 255.0f / 300.0f)); // 300 = max response time (red, laggy) + int pingColor = 255 - pingRounded << 16 | pingRounded << 8; + + if (this.background.getBoolean()) { + RenderUtil.drawRect(bounds[0] + (bounds[2] - bounds[0]) / 2 + startX, bounds[1] + (bounds[3] - bounds[1]) - mc.fontRenderer.FONT_HEIGHT - 2, bounds[0] + (bounds[2] - bounds[0]) / 2 + startX + mc.fontRenderer.getStringWidth(pingFormatted), bounds[1] + (bounds[3] - bounds[1]) - 1, 0x75101010); + } + + mc.fontRenderer.drawStringWithShadow(pingFormatted, bounds[0] + (bounds[2] - bounds[0]) / 2 + startX, bounds[1] + (bounds[3] - bounds[1]) - mc.fontRenderer.FONT_HEIGHT - 1, pingColor); + } + } + + if (e instanceof EntityLivingBase) { + final EntityLivingBase entityLiving = (EntityLivingBase) e; + + if (this.hearts.getBoolean()) { + final float hearts = entityLiving.getHealth() / 2.0f; + heartsFormatted = (Math.floor(hearts) == hearts ? (int) hearts : String.format("%.1f", hearts)) + "♥"; + + float startX = -mc.fontRenderer.getStringWidth(heartsFormatted) / 2.0f; + if (this.name.getBoolean()) + startX = -(mc.fontRenderer.getStringWidth(name) / 2.0f) - 2.0f - mc.fontRenderer.getStringWidth(heartsFormatted); + else if (this.ping.getBoolean() && entityLiving instanceof EntityPlayer) + startX = -(mc.fontRenderer.getStringWidth(pingFormatted) / 2.0f) - (mc.fontRenderer.getStringWidth(heartsFormatted) / 2.0f); + + int heartsRounded = Math.round(255.0f - (hearts * 255.0f / (entityLiving.getMaxHealth() / 2))); + int heartsColor = 255 - heartsRounded << 8 | heartsRounded << 16; + + if (this.background.getBoolean()) { + RenderUtil.drawRect(bounds[0] + (bounds[2] - bounds[0]) / 2 + startX, bounds[1] + (bounds[3] - bounds[1]) - mc.fontRenderer.FONT_HEIGHT - 2, bounds[0] + (bounds[2] - bounds[0]) / 2 + startX + mc.fontRenderer.getStringWidth(heartsFormatted), bounds[1] + (bounds[3] - bounds[1]) - 1, 0x75101010); + } + + mc.fontRenderer.drawStringWithShadow(heartsFormatted, bounds[0] + (bounds[2] - bounds[0]) / 2 + startX, bounds[1] + (bounds[3] - bounds[1]) - mc.fontRenderer.FONT_HEIGHT - 1, heartsColor); + } + + if (this.hpMode.getInt() != 0) { + RenderUtil.drawRect(bounds[2] - 0.5f, bounds[1], bounds[2] - 2, bounds[3], 0xAA000000); + final float hpHeight = ((((EntityLivingBase) e).getHealth() * (bounds[3] - bounds[1])) / ((EntityLivingBase) e).getMaxHealth()); + + RenderUtil.drawRect(bounds[2] - 1, bounds[1] - 0.5f, bounds[2] - 1.5f, (bounds[1] - bounds[3]) + bounds[3] + hpHeight + 0.5f, getHealthColor(e)); + + if (this.hpMode.getInt() == 2) { + if (((EntityLivingBase) e).getHealth() < ((EntityLivingBase) e).getMaxHealth() && ((EntityLivingBase) e).getHealth() > 0) { + final String hp = new DecimalFormat("#.#").format((int) ((EntityLivingBase) e).getHealth()); + mc.fontRenderer.drawStringWithShadow(hp, (bounds[2] - 1 - mc.fontRenderer.getStringWidth(hp) / 2), ((bounds[1] - bounds[3]) + bounds[3] + hpHeight + 0.5f - mc.fontRenderer.FONT_HEIGHT / 2), -1); + } + } + } + + if (this.potions.getInt() != 0) { + float scale = 0.5f; + int offsetX = 0; + int offsetY = 0; + + for (PotionEffect effect : entityLiving.getActivePotionEffects()) { + if (effect.getDuration() <= 0) + continue; + final Potion potion = effect.getPotion(); + if (this.potions.getInt() == 1) { + if (potion.hasStatusIcon()) { + GlStateManager.pushMatrix(); + mc.getTextureManager().bindTexture(this.inventory);// bind the inventory texture + int iconIndex = potion.getStatusIconIndex(); + GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); + GlStateManager.translate(bounds[0] + 1, bounds[3], 0); + GlStateManager.scale(scale, scale, 0); + + // scoot it over to the right + if (offsetY > 16) { + offsetY = 0; + offsetX += 16; + } + + // check to draw the transparent background behind the icon + if (this.background.getBoolean()) { + RenderUtil.drawRect(offsetX, offsetY, offsetX + 16, offsetY + 16, 0x75101010); + } + + // draw the textured icon + RenderUtil.drawTexturedModalRect(offsetX, offsetY, iconIndex % 8 * 18, 198 + iconIndex / 8 * 18, 18, 18); + GlStateManager.popMatrix(); + + offsetY += 16; + } + } else if (this.potions.getInt() == 2) { + final List potStringsToDraw = Lists.newArrayList(); + final String effectString = PotionUtil.getNameDurationString(effect); + + if (effectString != null) { // will return null if it doesn't exist as a valid formatted name + potStringsToDraw.add(effectString); + } + + for (String pString : potStringsToDraw) { + GlStateManager.pushMatrix(); + GlStateManager.disableDepth(); + GlStateManager.translate(bounds[0] + 1, bounds[3] + offsetY, 0); + + GlStateManager.scale(0.5f, 0.5f, 0.5f); + + if (offsetY > 16) { + offsetY = 0; + offsetX += 16; + } + if (this.background.getBoolean()) { + RenderUtil.drawRect(0, 0, mc.fontRenderer.getStringWidth(pString), mc.fontRenderer.FONT_HEIGHT - 1, 0x75101010); + } + mc.fontRenderer.drawStringWithShadow(pString, 0, 0, -1); + + GlStateManager.scale(2, 2, 2); + GlStateManager.enableDepth(); + GlStateManager.popMatrix(); + + offsetY += 4; + } + } + } + } + } + + if (this.armor.getBoolean()) { + final Iterator items = e.getEquipmentAndArmor().iterator(); + final ArrayList stacks = new ArrayList<>(); + + while (items.hasNext()) { + final ItemStack stack = items.next(); + if (stack != null && stack.getItem() != Items.AIR) { + stacks.add(stack); + } + } + + Collections.reverse(stacks); + + int x = 0; + + for (ItemStack stack : stacks) { + if (stack != null) { + final Item item = stack.getItem(); + if (item != Items.AIR) { + GlStateManager.pushMatrix(); + GlStateManager.enableBlend(); + GlStateManager.tryBlendFuncSeparate(770, 771, 1, 0); + RenderHelper.enableGUIStandardItemLighting(); + GlStateManager.translate(bounds[0] + (bounds[2] - bounds[0]) / 2 + x - (16 * stacks.size() / 2), bounds[1] + (bounds[3] - bounds[1]) - mc.fontRenderer.FONT_HEIGHT - 19, 0); + if (this.background.getBoolean()) { + RenderUtil.drawRect(0, 0, 16, 16, 0x75101010); + } + mc.getRenderItem().renderItemAndEffectIntoGUI(stack, 0, 0); + mc.getRenderItem().renderItemOverlays(mc.fontRenderer, stack, 0, 0); + RenderHelper.disableStandardItemLighting(); + GlStateManager.disableBlend(); + GlStateManager.color(1, 1, 1, 1); + GlStateManager.popMatrix(); + x += 16; + + if (this.enchants.getBoolean()) { + final List stringsToDraw = Lists.newArrayList(); + int y = 0; + + if (stack.getEnchantmentTagList() != null) { + final NBTTagList tags = stack.getEnchantmentTagList(); + for (int i = 0; i < tags.tagCount(); i++) { + final NBTTagCompound tagCompound = tags.getCompoundTagAt(i); + if (tagCompound != null && Enchantment.getEnchantmentByID(tagCompound.getByte("id")) != null) { + final Enchantment enchantment = Enchantment.getEnchantmentByID(tagCompound.getShort("id")); + final short lvl = tagCompound.getShort("lvl"); + if (enchantment != null) { + String ench = ""; + if (enchantment.isCurse()) { + ench = ChatFormatting.RED + enchantment.getTranslatedName(lvl).substring(11).substring(0, 3) + ChatFormatting.GRAY + lvl; + } else if (ItemUtil.isIllegalEnchant(enchantment, lvl)) { + ench = ChatFormatting.AQUA + enchantment.getTranslatedName(lvl).substring(0, 3) + ChatFormatting.GRAY + lvl; + } else { + ench = enchantment.getTranslatedName(lvl).substring(0, 3) + ChatFormatting.GRAY + lvl; + } + stringsToDraw.add(ench); + } + } + } + } + + // Enchanted gapple + if (item == Items.GOLDEN_APPLE) { + if (stack.getItemDamage() == 1) { + stringsToDraw.add(ChatFormatting.YELLOW + "God"); + } + } + + for (String string : stringsToDraw) { + GlStateManager.pushMatrix(); + GlStateManager.disableDepth(); + GlStateManager.translate(bounds[0] + (bounds[2] - bounds[0]) / 2 + x - ((16.0f * stacks.size()) / 2.0f) - (16.0f / 2.0f) - (mc.fontRenderer.getStringWidth(string) / 4.0f), bounds[1] + (bounds[3] - bounds[1]) - mc.fontRenderer.FONT_HEIGHT - 23 - y, 0); + GlStateManager.scale(0.5f, 0.5f, 0.5f); + if (this.background.getBoolean()) { + RenderUtil.drawRect(0, 0, mc.fontRenderer.getStringWidth(string), mc.fontRenderer.FONT_HEIGHT - 1, 0x75101010); + } + mc.fontRenderer.drawStringWithShadow(string, 0, 0, -1); + GlStateManager.scale(2, 2, 2); + GlStateManager.enableDepth(); + GlStateManager.popMatrix(); + y += 4; + } + } + } + } + } + } + } + } + } + } + } + + @Listener + public void receivePacket(EventReceivePacket event) { + if (event.getStage() == EventStageable.EventStage.PRE) { + if (event.getPacket() instanceof SPacketSoundEffect) { + final SPacketSoundEffect packet = (SPacketSoundEffect) event.getPacket(); + + if (packet.getCategory() == SoundCategory.NEUTRAL || packet.getCategory() == SoundCategory.PLAYERS) { + final String sound = packet.getSound().getSoundName().getResourcePath(); + if (sound.endsWith(".step") || sound.endsWith(".paddle_land") || sound.endsWith(".gallop")) { + this.footstepDataList.add(new FootstepData(packet.getX(), packet.getY(), packet.getZ(), System.currentTimeMillis())); + } + } + } + } + } + + private int getHealthColor(Entity entity) { + int scale = (int) Math.round(255.0 - (double) ((EntityLivingBase) entity).getHealth() * 255.0 / (double) ((EntityLivingBase) entity).getMaxHealth()); + int damageColor = 255 - scale << 8 | scale << 16; + + return (255 << 24) | damageColor; + } + + @Listener + public void renderName(EventRenderName event) { + if (event.getEntity() instanceof EntityPlayer) { + event.setCanceled(true); + } + } + + private String getNameForEntity(Entity entity) { + if (entity instanceof EntityItem) { + final EntityItem item = (EntityItem) entity; + String itemName = ""; + + final int stackSize = item.getItem().getCount(); + if (stackSize > 1) { + itemName = item.getItem().getDisplayName() + "(" + item.getItem().getCount() + ")"; + } else { + itemName = item.getItem().getDisplayName(); + } + return itemName; + } + if (entity instanceof EntityMinecart) { + final EntityMinecart minecart = (EntityMinecart) entity; + return minecart.getCartItem().getDisplayName(); + } + return entity.getName(); + } + + private boolean checkFilter(Entity entity) { + boolean ret = false; + + if (this.local.getBoolean() && (entity == Minecraft.getMinecraft().player) && (Minecraft.getMinecraft().gameSettings.thirdPersonView != 0)) { + ret = true; + } + if (this.players.getBoolean() && entity instanceof EntityPlayer && entity != Minecraft.getMinecraft().player) { + ret = true; + } + if (this.mobs.getBoolean() && entity instanceof IMob) { + ret = true; + } + if (this.animals.getBoolean() && entity instanceof IAnimals && !(entity instanceof IMob)) { + ret = true; + } + if (this.items.getBoolean() && entity instanceof EntityItem) { + ret = true; + } + if (this.vehicles.getBoolean() && (entity instanceof EntityBoat || entity instanceof EntityMinecart || entity instanceof EntityMinecartContainer)) { + ret = true; + } + if (this.armorStand.getBoolean() && entity instanceof EntityArmorStand) { + ret = true; + } + if (Minecraft.getMinecraft().player.getRidingEntity() != null && entity == Minecraft.getMinecraft().player.getRidingEntity()) { + ret = false; + } + + return ret; + } + + private int getColor(Entity entity) { + int ret = -1; + + if (entity instanceof IAnimals && !(entity instanceof IMob)) { + ret = 0xFF00FF44; + } + if (entity instanceof IMob) { + ret = 0xFFFFAA00; + } + if (entity instanceof EntityBoat || entity instanceof EntityMinecart || entity instanceof EntityMinecartContainer) { + ret = 0xFF00FFAA; + } + if (entity instanceof EntityItem) { + ret = 0xFF00FFAA; + } + if (entity instanceof EntityPlayer) { + ret = 0xFFFF4444; + + if (entity == Minecraft.getMinecraft().player) { + ret = -1; + } + + if (entity.isSneaking()) { + ret = 0xFFEE9900; + } + + if (Seppuku.INSTANCE.getFriendManager().isFriend(entity) != null) { + ret = 0xFF9900EE; + } + } + return ret; + } + + private float[] convertBounds(Entity e, float partialTicks, int width, int height) { + float x = -1; + float y = -1; + float w = width + 1; + float h = height + 1; + + final Vec3d pos = MathUtil.interpolateEntity(e, partialTicks); + + if (pos == null) { + return null; + } + + AxisAlignedBB bb = e.getEntityBoundingBox(); + + if (e instanceof EntityItem) { + bb = new AxisAlignedBB(bb.minX, bb.minY + 0.7f, bb.minZ, bb.maxX, bb.maxY, bb.maxZ); + } + + bb = bb.expand(0.15f, 0.1f, 0.15f); + + camera.setPosition(Minecraft.getMinecraft().getRenderViewEntity().posX, Minecraft.getMinecraft().getRenderViewEntity().posY, Minecraft.getMinecraft().getRenderViewEntity().posZ); + + if (!camera.isBoundingBoxInFrustum(bb)) { + return null; + } + + final Vec3d corners[] = { + new Vec3d(bb.minX - bb.maxX + e.width / 2, 0, bb.minZ - bb.maxZ + e.width / 2), + new Vec3d(bb.maxX - bb.minX - e.width / 2, 0, bb.minZ - bb.maxZ + e.width / 2), + new Vec3d(bb.minX - bb.maxX + e.width / 2, 0, bb.maxZ - bb.minZ - e.width / 2), + new Vec3d(bb.maxX - bb.minX - e.width / 2, 0, bb.maxZ - bb.minZ - e.width / 2), + + new Vec3d(bb.minX - bb.maxX + e.width / 2, bb.maxY - bb.minY, bb.minZ - bb.maxZ + e.width / 2), + new Vec3d(bb.maxX - bb.minX - e.width / 2, bb.maxY - bb.minY, bb.minZ - bb.maxZ + e.width / 2), + new Vec3d(bb.minX - bb.maxX + e.width / 2, bb.maxY - bb.minY, bb.maxZ - bb.minZ - e.width / 2), + new Vec3d(bb.maxX - bb.minX - e.width / 2, bb.maxY - bb.minY, bb.maxZ - bb.minZ - e.width / 2) + }; + + for (Vec3d vec : corners) { + final GLUProjection.Projection projection = GLUProjection.getInstance().project(pos.x + vec.x - Minecraft.getMinecraft().getRenderManager().viewerPosX, pos.y + vec.y - Minecraft.getMinecraft().getRenderManager().viewerPosY, pos.z + vec.z - Minecraft.getMinecraft().getRenderManager().viewerPosZ, GLUProjection.ClampMode.NONE, false); + + if (projection == null) { + return null; + } + + x = Math.max(x, (float) projection.getX()); + y = Math.max(y, (float) projection.getY()); + + w = Math.min(w, (float) projection.getX()); + h = Math.min(h, (float) projection.getY()); + } + + if (x != -1 && y != -1 && w != width + 1 && h != height + 1) { + return new float[]{x, y, w, h}; + } + + return null; + } + + public static class FootstepData { + private double x; + private double y; + private double z; + private long time; + + public FootstepData(double x, double y, double z, long time) { + this.x = x; + this.y = y; + this.z = z; + this.time = time; + } + + public double getX() { + return x; + } + + public void setX(double x) { + this.x = x; + } + + public double getY() { + return y; + } + + public void setY(double y) { + this.y = y; + } + + public double getZ() { + return z; + } + + public void setZ(double z) { + this.z = z; + } + + public long getTime() { + return time; + } + + public void setTime(long time) { + this.time = time; + } + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/module/render/XrayModule.java b/src/main/java/me/rigamortis/seppuku/impl/module/render/XrayModule.java new file mode 100644 index 0000000..73b3521 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/module/render/XrayModule.java @@ -0,0 +1,138 @@ +package me.rigamortis.seppuku.impl.module.render; + +import me.rigamortis.seppuku.api.event.render.EventRenderBlockModel; +import me.rigamortis.seppuku.api.event.render.EventRenderBlockSide; +import me.rigamortis.seppuku.api.event.render.EventRenderFluid; +import me.rigamortis.seppuku.api.event.world.EventSetOpaqueCube; +import me.rigamortis.seppuku.api.module.Module; +import net.minecraft.block.Block; +import net.minecraft.block.BlockLiquid; +import net.minecraft.client.Minecraft; +import team.stiff.pomelo.impl.annotated.handler.annotation.Listener; + +import java.util.ArrayList; +import java.util.List; + +/** + * Author Seth + * 4/9/2019 @ 12:58 PM. + */ +public final class XrayModule extends Module { + + private List ids = new ArrayList<>(); + + private float lastGamma; + private int lastAO; + + public XrayModule() { + super("Xray", new String[]{"JadeVision", "Jade"}, "Allows you to filter what the world renders", "NONE", -1, ModuleType.RENDER); + this.setHidden(true); + } + + @Override + public void onEnable() { + super.onEnable(); + final Minecraft mc = Minecraft.getMinecraft(); + lastGamma = mc.gameSettings.gammaSetting; + lastAO = mc.gameSettings.ambientOcclusion; + + mc.gameSettings.gammaSetting = 100; + mc.gameSettings.ambientOcclusion = 0; + } + + @Override + public void onDisable() { + super.onDisable(); + Minecraft.getMinecraft().gameSettings.gammaSetting = lastGamma; + Minecraft.getMinecraft().gameSettings.ambientOcclusion = lastAO; + } + + @Override + public void onToggle() { + super.onToggle(); + Minecraft.getMinecraft().renderGlobal.loadRenderers(); + } + + @Listener + public void shouldSideBeRendered(EventRenderBlockSide event) { + if(this.contains(Block.getIdFromBlock(event.getBlock()))) { + event.setRenderable(true); + } + event.setCanceled(true); + } + + @Listener + public void renderBlockModel(EventRenderBlockModel event) { + final Block block = event.getBlockState().getBlock(); + if(this.contains(Block.getIdFromBlock(block))) { + if (Minecraft.getMinecraft().getBlockRendererDispatcher().getBlockModelRenderer().renderModelFlat(event.getBlockAccess(), event.getBakedModel(), event.getBlockState(), event.getBlockPos(), event.getBufferBuilder(), event.isCheckSides(), event.getRand())) { + event.setRenderable(true); + } + } + event.setCanceled(true); + } + + @Listener + public void setOpaqueCube(EventSetOpaqueCube event) { + event.setCanceled(true); + } + + public void updateRenders() { + //Minecraft.getMinecraft().renderGlobal.loadRenderers(); + final Minecraft mc = Minecraft.getMinecraft(); + mc.renderGlobal.markBlockRangeForRenderUpdate( + (int)mc.player.posX - 256, + (int)mc.player.posY - 256, + (int)mc.player.posZ - 256, + (int)mc.player.posX + 256, + (int)mc.player.posY + 256, + (int)mc.player.posZ + 256); + } + + public boolean contains(int id) { + return this.ids.contains(id); + } + + public void add(int id) { + if(!contains(id)) { + this.ids.add(id); + } + } + + public void add(String name) { + final int id = Block.getIdFromBlock(Block.getBlockFromName(name)); + if(!contains(id)) { + this.ids.add(id); + } + } + + public void remove(int id) { + for(Integer i : this.ids) { + if(id == i.intValue()) { + this.ids.remove(i); + break; + } + } + } + + public void remove(String name) { + final int id = Block.getIdFromBlock(Block.getBlockFromName(name)); + if(contains(id)) { + this.ids.remove(id); + } + } + + public int clear() { + final int count = this.ids.size(); + this.ids.clear(); + return count; + } + + public List getIds() { + return ids; + } + + public void setIds(List ids) { + this.ids = ids; + } +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/module/ui/HudEditorModule.java b/src/main/java/me/rigamortis/seppuku/impl/module/ui/HudEditorModule.java new file mode 100644 index 0000000..561c32c --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/module/ui/HudEditorModule.java @@ -0,0 +1,34 @@ +package me.rigamortis.seppuku.impl.module.ui; + +import me.rigamortis.seppuku.api.module.Module; +import me.rigamortis.seppuku.impl.gui.hud.GuiHudEditor; +import net.minecraft.client.Minecraft; + +/** + * Author Seth + * 7/25/2019 @ 4:16 AM. + */ +public final class HudEditorModule extends Module { + + private boolean open; + + public HudEditorModule() { + super("HudEditor", new String[] {"HudEdit", "HEdit"}, "Displays a menu to modify the hud", "NONE", -1, ModuleType.UI); + this.setHidden(true); + } + + @Override + public void onToggle() { + super.onToggle(); + Minecraft.getMinecraft().displayGuiScreen(new GuiHudEditor()); + this.open = true; + } + + public boolean isOpen() { + return open; + } + + public void setOpen(boolean open) { + this.open = open; + } +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/module/world/AutoToolModule.java b/src/main/java/me/rigamortis/seppuku/impl/module/world/AutoToolModule.java new file mode 100644 index 0000000..2c74a48 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/module/world/AutoToolModule.java @@ -0,0 +1,237 @@ +package me.rigamortis.seppuku.impl.module.world; + +import me.rigamortis.seppuku.api.event.EventStageable; +import me.rigamortis.seppuku.api.event.network.EventSendPacket; +import me.rigamortis.seppuku.api.event.player.EventPlayerDamageBlock; +import me.rigamortis.seppuku.api.module.Module; +import me.rigamortis.seppuku.api.value.BooleanValue; +import net.minecraft.block.Block; +import net.minecraft.block.material.Material; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.Minecraft; +import net.minecraft.enchantment.EnchantmentHelper; +import net.minecraft.init.Enchantments; +import net.minecraft.init.MobEffects; +import net.minecraft.inventory.ClickType; +import net.minecraft.item.ItemStack; +import net.minecraft.network.play.client.CPacketPlayerDigging; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; +import team.stiff.pomelo.impl.annotated.handler.annotation.Listener; + +/** + * Author Seth + * 4/24/2019 @ 3:04 PM. + */ +public final class AutoToolModule extends Module { + + public final BooleanValue silent = new BooleanValue("Silent", new String[]{"Sil"}, true); + + private boolean send; + + public BlockPos position; + public EnumFacing facing; + + public AutoToolModule() { + super("AutoTool", new String[]{"Tool"}, "Automatically switches to the best tool", "NONE", -1, ModuleType.WORLD); + } + + private float blockStrength(BlockPos pos, ItemStack stack) { + final Minecraft mc = Minecraft.getMinecraft(); + + float hardness = mc.world.getBlockState(pos).getBlockHardness(mc.world, pos); + + if (hardness < 0.0F) { + return 0.0F; + } + + if (!canHarvestBlock(mc.world.getBlockState(pos).getBlock(), pos, stack)) { + return getDigSpeed(mc.world.getBlockState(pos), pos, stack) / hardness / 100F; + } else { + return getDigSpeed(mc.world.getBlockState(pos), pos, stack) / hardness / 30F; + } + } + + private boolean canHarvestBlock(Block block, BlockPos pos, ItemStack stack) { + final Minecraft mc = Minecraft.getMinecraft(); + IBlockState state = mc.world.getBlockState(pos); + state = state.getBlock().getActualState(state, mc.world, pos); + + if (state.getMaterial().isToolNotRequired()) { + return true; + } + + String tool = block.getHarvestTool(state); + + if (stack.isEmpty() || tool == null) { + return mc.player.canHarvestBlock(state); + } + + final int toolLevel = stack.getItem().getHarvestLevel(stack, tool, mc.player, state); + + if (toolLevel < 0) { + return mc.player.canHarvestBlock(state); + } + + return toolLevel >= block.getHarvestLevel(state); + } + + private float getDestroySpeed(IBlockState state, ItemStack stack) { + float f = 1.0F; + + f *= stack.getDestroySpeed(state); + + return f; + } + + private float getDigSpeed(IBlockState state, BlockPos pos, ItemStack stack) { + final Minecraft mc = Minecraft.getMinecraft(); + float f = getDestroySpeed(state, stack); + + if (f > 1.0F) { + int i = EnchantmentHelper.getEfficiencyModifier(mc.player); + + if (i > 0 && !stack.isEmpty()) { + f += (float) (i * i + 1); + } + } + + if (mc.player.isPotionActive(MobEffects.HASTE)) { + f *= 1.0F + (float) (mc.player.getActivePotionEffect(MobEffects.HASTE).getAmplifier() + 1) * 0.2F; + } + + if (mc.player.isPotionActive(MobEffects.MINING_FATIGUE)) { + float f1; + + switch (mc.player.getActivePotionEffect(MobEffects.MINING_FATIGUE).getAmplifier()) { + case 0: + f1 = 0.3F; + break; + case 1: + f1 = 0.09F; + break; + case 2: + f1 = 0.0027F; + break; + case 3: + default: + f1 = 8.1E-4F; + } + + f *= f1; + } + + if (mc.player.isInsideOfMaterial(Material.WATER) && !EnchantmentHelper.getAquaAffinityModifier(mc.player)) { + f /= 5.0F; + } + + if (!mc.player.onGround) { + f /= 5.0F; + } + + f = net.minecraftforge.event.ForgeEventFactory.getBreakSpeed(mc.player, state, f, pos); + return (f < 0 ? 0 : f); + } + + @Listener + public void damageBlock(EventPlayerDamageBlock event) { + final Minecraft mc = Minecraft.getMinecraft(); + if (this.silent.getBoolean()) { + final int slot = getToolInventory(event.getPos()); + if (slot != -1) { + mc.playerController.curBlockDamageMP += blockStrength(event.getPos(), mc.player.inventoryContainer.getSlot(slot).getStack()); + } else { + final int hotbar = getToolHotbar(event.getPos()); + if (hotbar != -1) { + mc.playerController.curBlockDamageMP += blockStrength(event.getPos(), mc.player.inventory.getStackInSlot(hotbar)); + } + } + } else { + final int slot = getToolHotbar(event.getPos()); + if (slot != -1) { + mc.player.inventory.currentItem = slot; + mc.playerController.updateController(); + } + } + } + + @Listener + public void sendPacket(EventSendPacket event) { + if (event.getStage() == EventStageable.EventStage.PRE) { + if (this.send) { + this.send = false; + return; + } + if (event.getPacket() instanceof CPacketPlayerDigging && this.silent.getBoolean()) { + final CPacketPlayerDigging packet = (CPacketPlayerDigging) event.getPacket(); + if (packet.getAction() == CPacketPlayerDigging.Action.STOP_DESTROY_BLOCK) { + this.position = packet.getPosition(); + this.facing = packet.getFacing(); + + if (this.position != null && this.facing != null) { + final int slot = getToolInventory(packet.getPosition()); + if (slot != -1) { + event.setCanceled(true); + Minecraft.getMinecraft().playerController.windowClick(Minecraft.getMinecraft().player.inventoryContainer.windowId, slot, Minecraft.getMinecraft().player.inventory.currentItem, ClickType.SWAP, Minecraft.getMinecraft().player); + send = true; + Minecraft.getMinecraft().player.connection.sendPacket(new CPacketPlayerDigging(CPacketPlayerDigging.Action.STOP_DESTROY_BLOCK, this.position, this.facing)); + Minecraft.getMinecraft().playerController.windowClick(Minecraft.getMinecraft().player.inventoryContainer.windowId, slot, Minecraft.getMinecraft().player.inventory.currentItem, ClickType.SWAP, Minecraft.getMinecraft().player); + } else { + final int hotbar = getToolHotbar(packet.getPosition()); + if (hotbar != -1) { + event.setCanceled(true); + Minecraft.getMinecraft().playerController.windowClick(Minecraft.getMinecraft().player.inventoryContainer.windowId, hotbar, Minecraft.getMinecraft().player.inventory.currentItem, ClickType.SWAP, Minecraft.getMinecraft().player); + send = true; + Minecraft.getMinecraft().player.connection.sendPacket(new CPacketPlayerDigging(CPacketPlayerDigging.Action.STOP_DESTROY_BLOCK, this.position, this.facing)); + Minecraft.getMinecraft().playerController.windowClick(Minecraft.getMinecraft().player.inventoryContainer.windowId, hotbar, Minecraft.getMinecraft().player.inventory.currentItem, ClickType.SWAP, Minecraft.getMinecraft().player); + } + } + } + } + } + } + } + + private int getToolInventory(BlockPos pos) { + int index = -1; + + float speed = 1.0f; + + for (int i = 9; i < 36; i++) { + final ItemStack stack = Minecraft.getMinecraft().player.inventoryContainer.getSlot(i).getStack(); + if (stack != null && stack != ItemStack.EMPTY) { + final float digSpeed = EnchantmentHelper.getEnchantmentLevel(Enchantments.EFFICIENCY, stack); + final float destroySpeed = stack.getDestroySpeed(Minecraft.getMinecraft().world.getBlockState(pos)); + + if ((digSpeed + destroySpeed) > speed) { + speed = (digSpeed + destroySpeed); + index = i; + } + } + } + + return index; + } + + private int getToolHotbar(BlockPos pos) { + int index = -1; + + float speed = 1.0f; + + for (int i = 0; i <= 9; i++) { + final ItemStack stack = Minecraft.getMinecraft().player.inventory.getStackInSlot(i); + if (stack != null && stack != ItemStack.EMPTY) { + final float digSpeed = EnchantmentHelper.getEnchantmentLevel(Enchantments.EFFICIENCY, stack); + final float destroySpeed = stack.getDestroySpeed(Minecraft.getMinecraft().world.getBlockState(pos)); + + if ((digSpeed + destroySpeed) > speed) { + speed = (digSpeed + destroySpeed); + index = i; + } + } + } + + return index; + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/module/world/FastPlaceModule.java b/src/main/java/me/rigamortis/seppuku/impl/module/world/FastPlaceModule.java new file mode 100644 index 0000000..e4c57ab --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/module/world/FastPlaceModule.java @@ -0,0 +1,32 @@ +package me.rigamortis.seppuku.impl.module.world; + +import me.rigamortis.seppuku.api.event.EventStageable; +import me.rigamortis.seppuku.api.event.player.EventPlayerUpdate; +import me.rigamortis.seppuku.api.module.Module; +import net.minecraft.client.Minecraft; +import team.stiff.pomelo.impl.annotated.handler.annotation.Listener; + +/** + * Author Seth + * 4/23/2019 @ 12:58 PM. + */ +public final class FastPlaceModule extends Module { + + public FastPlaceModule() { + super("FastPlace", new String[] {"Fp"}, "Removes place delay", "NONE", -1, ModuleType.WORLD); + } + + @Override + public void onDisable() { + super.onDisable(); + Minecraft.getMinecraft().rightClickDelayTimer = 6; + } + + @Listener + public void onUpdate(EventPlayerUpdate event) { + if(event.getStage() == EventStageable.EventStage.PRE) { + Minecraft.getMinecraft().rightClickDelayTimer = 0; + } + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/module/world/LiquidInteractModule.java b/src/main/java/me/rigamortis/seppuku/impl/module/world/LiquidInteractModule.java new file mode 100644 index 0000000..f8b7ba7 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/module/world/LiquidInteractModule.java @@ -0,0 +1,22 @@ +package me.rigamortis.seppuku.impl.module.world; + +import me.rigamortis.seppuku.api.event.world.EventCanCollide; +import me.rigamortis.seppuku.api.module.Module; +import team.stiff.pomelo.impl.annotated.handler.annotation.Listener; + +/** + * Author Seth + * 6/5/2019 @ 9:03 PM. + */ +public final class LiquidInteractModule extends Module { + + public LiquidInteractModule() { + super("LiquidInteract", new String[] {"LiquidInt", "LiqInt"}, "Allows you to interact with liquids", "NONE", -1, ModuleType.WORLD); + } + + @Listener + public void canCollide(EventCanCollide event) { + event.setCanceled(true); + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/module/world/NewChunksModule.java b/src/main/java/me/rigamortis/seppuku/impl/module/world/NewChunksModule.java new file mode 100644 index 0000000..3eff23e --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/module/world/NewChunksModule.java @@ -0,0 +1,98 @@ +package me.rigamortis.seppuku.impl.module.world; + +import me.rigamortis.seppuku.api.event.EventStageable; +import me.rigamortis.seppuku.api.event.network.EventReceivePacket; +import me.rigamortis.seppuku.api.event.render.EventRender3D; +import me.rigamortis.seppuku.api.module.Module; +import me.rigamortis.seppuku.api.util.RenderUtil; +import me.rigamortis.seppuku.api.value.OptionalValue; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.culling.Frustum; +import net.minecraft.client.renderer.culling.ICamera; +import net.minecraft.network.play.server.SPacketChunkData; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.chunk.Chunk; +import team.stiff.pomelo.impl.annotated.handler.annotation.Listener; + +import java.util.ArrayList; +import java.util.List; + +/** + * Author Seth + * 5/11/2019 @ 7:46 AM. + */ +public final class NewChunksModule extends Module { + + private ICamera frustum = new Frustum(); + + private List chunkDataList = new ArrayList<>(); + + public NewChunksModule() { + super("NewChunks", new String[] {"ChunkGen"}, "Highlights newly generated chunks", "NONE", -1, ModuleType.WORLD); + } + + @Listener + public void onToggle() { + super.onToggle(); + this.chunkDataList.clear(); + } + + @Listener + public void receivePacket(EventReceivePacket event) { + if(event.getStage() == EventStageable.EventStage.PRE) { + if(event.getPacket() instanceof SPacketChunkData) { + final SPacketChunkData packet = (SPacketChunkData) event.getPacket(); + if(!packet.isFullChunk()) { + final ChunkData chunk = new ChunkData(packet.getChunkX() * 16, packet.getChunkZ() * 16); + + if(!this.chunkDataList.contains(chunk)) { + this.chunkDataList.add(chunk); + } + } + } + } + } + + @Listener + public void render3D(EventRender3D event) { + for(ChunkData chunkData : this.chunkDataList) { + if(chunkData != null) { + this.frustum.setPosition(Minecraft.getMinecraft().getRenderViewEntity().posX, Minecraft.getMinecraft().getRenderViewEntity().posY, Minecraft.getMinecraft().getRenderViewEntity().posZ); + + final AxisAlignedBB bb = new AxisAlignedBB(chunkData.x, 0, chunkData.z, chunkData.x + 16, 1, chunkData.z + 16); + + if (frustum.isBoundingBoxInFrustum(bb)) { + RenderUtil.drawPlane(chunkData.x - Minecraft.getMinecraft().getRenderManager().viewerPosX, -Minecraft.getMinecraft().getRenderManager().viewerPosY, chunkData.z - Minecraft.getMinecraft().getRenderManager().viewerPosZ, new AxisAlignedBB(0, 0, 0, 16, 1, 16), 1, 0xFF9900EE); + } + } + } + } + + public static class ChunkData { + private int x; + private int z; + + public ChunkData(int x, int z) { + this.x = x; + this.z = z; + } + + public int getX() { + return x; + } + + public void setX(int x) { + this.x = x; + } + + public int getZ() { + return z; + } + + public void setZ(int z) { + this.z = z; + } + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/module/world/NoChunkModule.java b/src/main/java/me/rigamortis/seppuku/impl/module/world/NoChunkModule.java new file mode 100644 index 0000000..b3d3b6d --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/module/world/NoChunkModule.java @@ -0,0 +1,28 @@ +package me.rigamortis.seppuku.impl.module.world; + +import me.rigamortis.seppuku.api.event.EventStageable; +import me.rigamortis.seppuku.api.event.network.EventReceivePacket; +import me.rigamortis.seppuku.api.module.Module; +import net.minecraft.network.play.server.SPacketChunkData; +import team.stiff.pomelo.impl.annotated.handler.annotation.Listener; + +/** + * Author Seth + * 6/2/2019 @ 1:30 PM. + */ +public final class NoChunkModule extends Module { + + public NoChunkModule() { + super("NoChunk", new String[]{"AntiChunk"}, "Prevents processing of chunk data packets", "NONE", -1, ModuleType.WORLD); + } + + @Listener + public void onReceivePacket(EventReceivePacket event) { + if (event.getStage() == EventStageable.EventStage.PRE) { + if (event.getPacket() instanceof SPacketChunkData) { + event.setCanceled(true); + } + } + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/module/world/NoWeatherModule.java b/src/main/java/me/rigamortis/seppuku/impl/module/world/NoWeatherModule.java new file mode 100644 index 0000000..7628850 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/module/world/NoWeatherModule.java @@ -0,0 +1,44 @@ +package me.rigamortis.seppuku.impl.module.world; + +import me.rigamortis.seppuku.api.event.EventStageable; +import me.rigamortis.seppuku.api.event.player.EventPlayerUpdate; +import me.rigamortis.seppuku.api.module.Module; +import me.rigamortis.seppuku.api.value.OptionalValue; +import net.minecraft.client.Minecraft; +import team.stiff.pomelo.impl.annotated.handler.annotation.Listener; + +/** + * Author Seth + * 8/14/2019 @ 1:45 AM. + */ +public final class NoWeatherModule extends Module { + + public final OptionalValue mode = new OptionalValue("Mode", new String[]{"Mode", "M"}, 0, new String[]{"Remove", "Rain"}); + + public NoWeatherModule() { + super("NoWeather", new String[]{"AntiWeather"}, "Allows you to control the weather client-side", "NONE", -1, ModuleType.WORLD); + } + + @Override + public String getMetaData() { + return this.mode.getSelectedOption(); + } + + @Listener + public void onUpdate(EventPlayerUpdate event) { + if (event.getStage() == EventStageable.EventStage.PRE) { + final Minecraft mc = Minecraft.getMinecraft(); + switch (this.mode.getInt()) { + case 0: + mc.world.setRainStrength(0); + mc.world.setThunderStrength(0); + break; + case 1: + mc.world.setRainStrength(1.0f); + mc.world.setThunderStrength(0); + break; + } + } + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/module/world/NukerModule.java b/src/main/java/me/rigamortis/seppuku/impl/module/world/NukerModule.java new file mode 100644 index 0000000..3fcef5b --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/module/world/NukerModule.java @@ -0,0 +1,143 @@ +package me.rigamortis.seppuku.impl.module.world; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.event.EventStageable; +import me.rigamortis.seppuku.api.event.player.EventRightClickBlock; +import me.rigamortis.seppuku.api.event.player.EventUpdateWalkingPlayer; +import me.rigamortis.seppuku.api.module.Module; +import me.rigamortis.seppuku.api.util.MathUtil; +import me.rigamortis.seppuku.api.value.NumberValue; +import me.rigamortis.seppuku.api.value.OptionalValue; +import net.minecraft.block.Block; +import net.minecraft.block.BlockLiquid; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.Minecraft; +import net.minecraft.init.Blocks; +import net.minecraft.util.EnumHand; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; +import team.stiff.pomelo.impl.annotated.handler.annotation.Listener; + +/** + * Author Seth + * 6/10/2019 @ 2:31 PM. + */ +public final class NukerModule extends Module { + + public final OptionalValue mode = new OptionalValue("Mode", new String[]{"Mode", "M"}, 0, new String[]{"Selection", "All"}); + + public final NumberValue distance = new NumberValue("Distance", new String[]{"Dist", "D"}, 4.5f, Float.class, 0.0f, 5.0f, 0.1f); + + private Block selected; + + public NukerModule() { + super("Nuker", new String[]{"Nuke"}, "Automatically mines blocks within reach", "NONE", -1, ModuleType.WORLD); + } + + @Override + public void onToggle() { + super.onToggle(); + this.selected = null; + } + + @Override + public String getMetaData() { + return this.mode.getSelectedOption(); + } + + @Listener + public void onWalkingUpdate(EventUpdateWalkingPlayer event) { + if (event.getStage() == EventStageable.EventStage.PRE) { + BlockPos pos = null; + + switch (this.mode.getInt()) { + case 0: + pos = this.getClosestBlockSelection(); + break; + case 1: + pos = this.getClosestBlockAll(); + break; + } + + if (pos != null) { + final Minecraft mc = Minecraft.getMinecraft(); + + final float[] angle = MathUtil.calcAngle(mc.player.getPositionEyes(mc.getRenderPartialTicks()), new Vec3d(pos.getX() + 0.5f, pos.getY() + 0.5f, pos.getZ() + 0.5f)); + Seppuku.INSTANCE.getRotationManager().setPlayerRotations(angle[0], angle[1]); + + if (canBreak(pos)) { + mc.playerController.onPlayerDamageBlock(pos, mc.player.getHorizontalFacing()); + mc.player.swingArm(EnumHand.MAIN_HAND); + } + } + } + } + + @Listener + public void clickBlock(EventRightClickBlock event) { + if (this.mode.getInt() == 0) { + final Block block = Minecraft.getMinecraft().world.getBlockState(event.getPos()).getBlock(); + if (block != null && block != this.selected) { + this.selected = block; + Seppuku.INSTANCE.logChat("Nuker block set to " + block.getLocalizedName()); + event.setCanceled(true); + } + } + } + + private boolean canBreak(BlockPos pos) { + final IBlockState blockState = Minecraft.getMinecraft().world.getBlockState(pos); + final Block block = blockState.getBlock(); + + return block.getBlockHardness(blockState, Minecraft.getMinecraft().world, pos) != -1; + } + + private BlockPos getClosestBlockAll() { + final Minecraft mc = Minecraft.getMinecraft(); + float maxDist = this.distance.getFloat(); + + BlockPos ret = null; + + for (float x = maxDist; x >= -maxDist; x--) { + for (float y = maxDist; y >= -maxDist; y--) { + for (float z = maxDist; z >= -maxDist; z--) { + final BlockPos pos = new BlockPos(mc.player.posX + x, mc.player.posY + y, mc.player.posZ + z); + final double dist = mc.player.getDistance(pos.getX(), pos.getY(), pos.getZ()); + if (dist <= maxDist && (mc.world.getBlockState(pos).getBlock() != Blocks.AIR && !(mc.world.getBlockState(pos).getBlock() instanceof BlockLiquid)) && canBreak(pos)) { + if (pos.getY() >= mc.player.posY) { + maxDist = (float) dist; + ret = pos; + } + } + } + } + } + + return ret; + } + + private BlockPos getClosestBlockSelection() { + final Minecraft mc = Minecraft.getMinecraft(); + float maxDist = this.distance.getFloat(); + + BlockPos ret = null; + + for (float x = maxDist; x >= -maxDist; x--) { + for (float y = maxDist; y >= -maxDist; y--) { + for (float z = maxDist; z >= -maxDist; z--) { + final BlockPos pos = new BlockPos(mc.player.posX + x, mc.player.posY + y, mc.player.posZ + z); + final double dist = mc.player.getDistance(pos.getX(), pos.getY(), pos.getZ()); + if (dist <= maxDist && (mc.world.getBlockState(pos).getBlock() != Blocks.AIR && !(mc.world.getBlockState(pos).getBlock() instanceof BlockLiquid)) && mc.world.getBlockState(pos).getBlock() == this.selected && canBreak(pos)) { + if (pos.getY() >= mc.player.posY) { + maxDist = (float) dist; + ret = pos; + } + } + } + } + } + + return ret; + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/module/world/PhaseModule.java b/src/main/java/me/rigamortis/seppuku/impl/module/world/PhaseModule.java new file mode 100644 index 0000000..594f981 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/module/world/PhaseModule.java @@ -0,0 +1,188 @@ +package me.rigamortis.seppuku.impl.module.world; + +import me.rigamortis.seppuku.api.event.EventStageable; +import me.rigamortis.seppuku.api.event.gui.EventRenderHelmet; +import me.rigamortis.seppuku.api.event.network.EventSendPacket; +import me.rigamortis.seppuku.api.event.player.*; +import me.rigamortis.seppuku.api.event.render.EventRenderOverlay; +import me.rigamortis.seppuku.api.event.world.EventAddCollisionBox; +import me.rigamortis.seppuku.api.event.world.EventSetOpaqueCube; +import me.rigamortis.seppuku.api.module.Module; +import me.rigamortis.seppuku.api.util.MathUtil; +import me.rigamortis.seppuku.api.value.BooleanValue; +import me.rigamortis.seppuku.api.value.OptionalValue; +import net.minecraft.client.Minecraft; +import net.minecraft.entity.item.EntityBoat; +import net.minecraft.network.play.client.CPacketPlayer; +import net.minecraft.util.math.Vec3d; +import team.stiff.pomelo.impl.annotated.handler.annotation.Listener; + +/** + * Author Seth + * 4/26/2019 @ 11:56 AM. + */ +public final class PhaseModule extends Module { + + public final OptionalValue mode = new OptionalValue("Mode", new String[]{"Mode", "M"}, 0, new String[]{"Sand", "Packet", "Skip", "NoClip"}); + + public final BooleanValue floor = new BooleanValue("Floor", new String[]{"Fl"}, true); + + public PhaseModule() { + super("Phase", new String[]{"NoClip"}, "Allows you to glitch through blocks", "NONE", -1, ModuleType.WORLD); + } + + @Override + public String getMetaData() { + return this.mode.getSelectedOption(); + } + + @Listener + public void setOpaqueCube(EventSetOpaqueCube event) { + event.setCanceled(true); + } + + @Listener + public void renderOverlay(EventRenderOverlay event) { + event.setCanceled(true); + } + + @Listener + public void renderHelmet(EventRenderHelmet event) { + event.setCanceled(true); + } + + @Listener + public void pushOutOfBlocks(EventPushOutOfBlocks event) { + event.setCanceled(true); + } + + @Listener + public void pushedByWater(EventPushedByWater event) { + event.setCanceled(true); + } + + @Listener + public void applyCollision(EventApplyCollision event) { + event.setCanceled(true); + } + + @Listener + public void collideWithBlock(EventAddCollisionBox event) { + final Minecraft mc = Minecraft.getMinecraft(); + + if (mc.player != null) { + + final boolean floor = this.floor.getBoolean() ? event.getPos().getY() >= 1 : true; + + if (this.mode.getInt() == 0) { + if (mc.player.getRidingEntity() != null && event.getEntity() == mc.player.getRidingEntity()) { + if (mc.gameSettings.keyBindSprint.isKeyDown() && floor) { + event.setCanceled(true); + } else { + if (mc.gameSettings.keyBindJump.isKeyDown() && event.getPos().getY() >= mc.player.getRidingEntity().posY) { + event.setCanceled(true); + } + if (event.getPos().getY() >= mc.player.getRidingEntity().posY) { + event.setCanceled(true); + } + } + } else if (event.getEntity() == mc.player) { + if (mc.gameSettings.keyBindSneak.isKeyDown() && floor) { + event.setCanceled(true); + } else { + if (mc.gameSettings.keyBindJump.isKeyDown() && event.getPos().getY() >= mc.player.posY) { + event.setCanceled(true); + } + if (event.getPos().getY() >= mc.player.posY) { + event.setCanceled(true); + } + } + } + } + } + + if (this.mode.getInt() == 3) { + if (event.getEntity() == mc.player || mc.player.getRidingEntity() != null && event.getEntity() == mc.player.getRidingEntity()) { + event.setCanceled(true); + } + } + } + + @Listener + public void sendPacket(EventSendPacket event) { + if (event.getStage() == EventStageable.EventStage.PRE) { + if (this.mode.getInt() == 3) { + if (event.getPacket() instanceof CPacketPlayer && !(event.getPacket() instanceof CPacketPlayer.Position)) { + event.setCanceled(true); + } + } + } + } + + @Listener + public void onWalkingUpdate(EventUpdateWalkingPlayer event) { + if (event.getStage() == EventStageable.EventStage.PRE) { + final Minecraft mc = Minecraft.getMinecraft(); + + if (this.mode.getInt() == 3) { + mc.player.setVelocity(0, 0, 0); + if (mc.gameSettings.keyBindForward.isKeyDown() || mc.gameSettings.keyBindBack.isKeyDown() || mc.gameSettings.keyBindLeft.isKeyDown() || mc.gameSettings.keyBindRight.isKeyDown()) { + final double[] speed = MathUtil.directionSpeed(0.06f); + mc.player.connection.sendPacket(new CPacketPlayer.Position(mc.player.posX + speed[0], mc.player.posY, mc.player.posZ + speed[1], mc.player.onGround)); + mc.player.connection.sendPacket(new CPacketPlayer.Position(mc.player.posX, 0, mc.player.posZ, mc.player.onGround)); + } + if (mc.gameSettings.keyBindSneak.isKeyDown()) { + mc.player.connection.sendPacket(new CPacketPlayer.Position(mc.player.posX, mc.player.posY - 0.06f, mc.player.posZ, mc.player.onGround)); + mc.player.connection.sendPacket(new CPacketPlayer.Position(mc.player.posX, 0, mc.player.posZ, mc.player.onGround)); + } + + if (mc.gameSettings.keyBindJump.isKeyDown()) { + mc.player.connection.sendPacket(new CPacketPlayer.Position(mc.player.posX, mc.player.posY + 0.06f, mc.player.posZ, mc.player.onGround)); + mc.player.connection.sendPacket(new CPacketPlayer.Position(mc.player.posX, 0, mc.player.posZ, mc.player.onGround)); + } + } + } + } + + @Listener + public void onUpdate(EventPlayerUpdate event) { + if (event.getStage() == EventStageable.EventStage.PRE) { + final Minecraft mc = Minecraft.getMinecraft(); + + if (this.mode.getInt() == 0) { + + if (mc.gameSettings.keyBindJump.isKeyDown()) { + if (mc.player.getRidingEntity() != null && mc.player.getRidingEntity() instanceof EntityBoat) { + final EntityBoat boat = (EntityBoat) mc.player.getRidingEntity(); + if (boat.onGround) { + boat.motionY = 0.42f; + } + } + } + } + + if (this.mode.getInt() == 1) { + final Vec3d dir = MathUtil.direction(mc.player.rotationYaw); + if (dir != null) { + if (mc.player.onGround && mc.player.collidedHorizontally) { + mc.player.connection.sendPacket(new CPacketPlayer.Position(mc.player.posX + dir.x * 0.00001f, mc.player.posY, mc.player.posZ + dir.z * 0.0001f, mc.player.onGround)); + mc.player.connection.sendPacket(new CPacketPlayer.Position(mc.player.posX + dir.x * 2.0f, mc.player.posY, mc.player.posZ + dir.z * 2.0f, mc.player.onGround)); + } + } + } + + if (this.mode.getInt() == 2) { + final Vec3d dir = MathUtil.direction(mc.player.rotationYaw); + if (dir != null) { + if (mc.player.onGround && mc.player.collidedHorizontally) { + mc.player.connection.sendPacket(new CPacketPlayer.Position(mc.player.posX, mc.player.posY, mc.player.posZ, mc.player.onGround)); + mc.player.connection.sendPacket(new CPacketPlayer.Position(mc.player.posX + dir.x * 0.001f, mc.player.posY + 0.1f, mc.player.posZ + dir.z * 0.001f, mc.player.onGround)); + mc.player.connection.sendPacket(new CPacketPlayer.Position(mc.player.posX + dir.x * 0.03f, 0, mc.player.posZ + dir.z * 0.03f, mc.player.onGround)); + mc.player.connection.sendPacket(new CPacketPlayer.Position(mc.player.posX + dir.x * 0.06f, mc.player.posY, mc.player.posZ + dir.z * 0.06f, mc.player.onGround)); + } + } + } + } + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/module/world/SlimeChunksModule.java b/src/main/java/me/rigamortis/seppuku/impl/module/world/SlimeChunksModule.java new file mode 100644 index 0000000..9fd798d --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/module/world/SlimeChunksModule.java @@ -0,0 +1,113 @@ +package me.rigamortis.seppuku.impl.module.world; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.event.EventStageable; +import me.rigamortis.seppuku.api.event.network.EventReceivePacket; +import me.rigamortis.seppuku.api.event.render.EventRender3D; +import me.rigamortis.seppuku.api.module.Module; +import me.rigamortis.seppuku.api.util.RenderUtil; +import me.rigamortis.seppuku.impl.management.WorldManager; +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.ServerData; +import net.minecraft.client.renderer.culling.Frustum; +import net.minecraft.client.renderer.culling.ICamera; +import net.minecraft.network.play.server.SPacketChunkData; +import net.minecraft.util.math.AxisAlignedBB; +import team.stiff.pomelo.impl.annotated.handler.annotation.Listener; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +/** + * Author Seth + * 6/11/2019 @ 4:23 AM. + */ +public final class SlimeChunksModule extends Module { + + private ICamera frustum = new Frustum(); + + private List slimeChunkList = new ArrayList<>(); + + public SlimeChunksModule() { + super("SlimeChunks", new String[]{"SlimesChunks", "SlimeC"}, "Highlights slime chunks(Requires the seed)", "NONE", -1, ModuleType.WORLD); + } + + @Listener + public void onToggle() { + super.onToggle(); + this.slimeChunkList.clear(); + } + + @Listener + public void render3D(EventRender3D event) { + for (SlimeChunk slimeChunk : this.slimeChunkList) { + if (slimeChunk != null) { + this.frustum.setPosition(Minecraft.getMinecraft().getRenderViewEntity().posX, Minecraft.getMinecraft().getRenderViewEntity().posY, Minecraft.getMinecraft().getRenderViewEntity().posZ); + + final AxisAlignedBB bb = new AxisAlignedBB(slimeChunk.x, 0, slimeChunk.z, slimeChunk.x + 16, 1, slimeChunk.z + 16); + + if (frustum.isBoundingBoxInFrustum(bb)) { + RenderUtil.drawPlane(slimeChunk.x - Minecraft.getMinecraft().getRenderManager().viewerPosX, -Minecraft.getMinecraft().getRenderManager().viewerPosY, slimeChunk.z - Minecraft.getMinecraft().getRenderManager().viewerPosZ, new AxisAlignedBB(0, 0, 0, 16, 1, 16), 2, 0xFF00FF00); + } + } + } + } + + @Listener + public void receivePacket(EventReceivePacket event) { + if (event.getStage() == EventStageable.EventStage.PRE) { + if (event.getPacket() instanceof SPacketChunkData) { + final SPacketChunkData packet = (SPacketChunkData) event.getPacket(); + final SlimeChunk chunk = new SlimeChunk(packet.getChunkX() * 16, packet.getChunkZ() * 16); + + final ServerData serverData = Minecraft.getMinecraft().getCurrentServerData(); + if (serverData != null) { + final WorldManager.WorldData worldData = Seppuku.INSTANCE.getWorldManager().find(serverData.serverIP); + if (worldData != null) { + if (!this.slimeChunkList.contains(chunk) && this.isSlimeChunk(worldData.getSeed(), packet.getChunkX(), packet.getChunkZ())) { + this.slimeChunkList.add(chunk); + } + } + } + } + } + } + + private boolean isSlimeChunk(final long seed, int x, int z) { + final Random rand = new Random(seed + + (long) (x * x * 0x4c1906) + + (long) (x * 0x5ac0db) + + (long) (z * z) * 0x4307a7L + + (long) (z * 0x5f24f) ^ 0x3ad8025f); + return rand.nextInt(10) == 0; + } + + public static class SlimeChunk { + private int x; + private int z; + + public SlimeChunk(int x, int z) { + this.x = x; + this.z = z; + } + + public int getX() { + return x; + } + + public void setX(int x) { + this.x = x; + } + + public int getZ() { + return z; + } + + public void setZ(int z) { + this.z = z; + } + } + + +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/module/world/SpeedMineModule.java b/src/main/java/me/rigamortis/seppuku/impl/module/world/SpeedMineModule.java new file mode 100644 index 0000000..40cf6c3 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/module/world/SpeedMineModule.java @@ -0,0 +1,117 @@ +package me.rigamortis.seppuku.impl.module.world; + +import me.rigamortis.seppuku.api.event.EventStageable; +import me.rigamortis.seppuku.api.event.player.*; +import me.rigamortis.seppuku.api.module.Module; +import me.rigamortis.seppuku.api.value.BooleanValue; +import me.rigamortis.seppuku.api.value.OptionalValue; +import net.minecraft.block.Block; +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.Minecraft; +import net.minecraft.network.play.client.CPacketPlayerDigging; +import net.minecraft.util.EnumHand; +import net.minecraft.util.math.BlockPos; +import team.stiff.pomelo.impl.annotated.handler.annotation.Listener; + +/** + * Author Seth + * 4/24/2019 @ 12:16 PM. + */ +public final class SpeedMineModule extends Module { + + public final OptionalValue mode = new OptionalValue("Mode", new String[]{"Mode", "M"}, 0, new String[]{"Packet", "Damage", "Instant"}); + + public final BooleanValue reset = new BooleanValue("Reset", new String[]{"Res"}, true); + public final BooleanValue doubleBreak = new BooleanValue("DoubleBreak", new String[]{"DoubleBreak", "Double", "DB"}, false); + + public SpeedMineModule() { + super("SpeedMine", new String[]{"FastMine"}, "Allows you to break blocks faster", "NONE", -1, ModuleType.WORLD); + } + + @Override + public String getMetaData() { + return this.mode.getSelectedOption(); + } + + @Listener + public void onUpdate(EventPlayerUpdate event) { + if (event.getStage() == EventStageable.EventStage.PRE) { + Minecraft.getMinecraft().playerController.blockHitDelay = 0; + + if (this.reset.getBoolean() && Minecraft.getMinecraft().gameSettings.keyBindUseItem.isKeyDown()) { + Minecraft.getMinecraft().playerController.isHittingBlock = false; + } + } + } + + @Listener + public void resetBlockDamage(EventResetBlockRemoving event) { + if (this.reset.getBoolean()) { + event.setCanceled(true); + } + } + + @Listener + public void clickBlock(EventClickBlock event) { + if (this.reset.getBoolean()) { + if (Minecraft.getMinecraft().playerController.curBlockDamageMP > 0.1f) { + Minecraft.getMinecraft().playerController.isHittingBlock = true; + } + } + } + + @Listener + public void damageBlock(EventPlayerDamageBlock event) { + if (canBreak(event.getPos())) { + + final Minecraft mc = Minecraft.getMinecraft(); + + if (this.reset.getBoolean()) { + mc.playerController.isHittingBlock = false; + } + + switch (this.mode.getInt()) { + case 0: + mc.player.swingArm(EnumHand.MAIN_HAND); + mc.player.connection.sendPacket(new CPacketPlayerDigging(CPacketPlayerDigging.Action.START_DESTROY_BLOCK, event.getPos(), event.getFace())); + mc.player.connection.sendPacket(new CPacketPlayerDigging(CPacketPlayerDigging.Action.STOP_DESTROY_BLOCK, event.getPos(), event.getFace())); + event.setCanceled(true); + break; + case 1: + if (mc.playerController.curBlockDamageMP >= 0.7f) { + mc.playerController.curBlockDamageMP = 1.0f; + } + break; + case 2: + mc.player.swingArm(EnumHand.MAIN_HAND); + mc.player.connection.sendPacket(new CPacketPlayerDigging(CPacketPlayerDigging.Action.START_DESTROY_BLOCK, event.getPos(), event.getFace())); + mc.player.connection.sendPacket(new CPacketPlayerDigging(CPacketPlayerDigging.Action.STOP_DESTROY_BLOCK, event.getPos(), event.getFace())); + mc.playerController.onPlayerDestroyBlock(event.getPos()); + mc.world.setBlockToAir(event.getPos()); + break; + } + } + + if (this.doubleBreak.getBoolean()) { + final BlockPos above = event.getPos().add(0, 1, 0); + + final Minecraft mc = Minecraft.getMinecraft(); + + if (canBreak(above) && mc.player.getDistance(above.getX(), above.getY(), above.getZ()) <= 5f) { + mc.player.swingArm(EnumHand.MAIN_HAND); + mc.player.connection.sendPacket(new CPacketPlayerDigging(CPacketPlayerDigging.Action.START_DESTROY_BLOCK, above, event.getFace())); + mc.player.connection.sendPacket(new CPacketPlayerDigging(CPacketPlayerDigging.Action.STOP_DESTROY_BLOCK, above, event.getFace())); + mc.playerController.onPlayerDestroyBlock(above); + mc.world.setBlockToAir(above); + } + } + } + + private boolean canBreak(BlockPos pos) { + final IBlockState blockState = Minecraft.getMinecraft().world.getBlockState(pos); + final Block block = blockState.getBlock(); + + return block.getBlockHardness(blockState, Minecraft.getMinecraft().world, pos) != -1; + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/module/world/TimerModule.java b/src/main/java/me/rigamortis/seppuku/impl/module/world/TimerModule.java new file mode 100644 index 0000000..ae03bcf --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/module/world/TimerModule.java @@ -0,0 +1,40 @@ +package me.rigamortis.seppuku.impl.module.world; + +import me.rigamortis.seppuku.api.event.EventStageable; +import me.rigamortis.seppuku.api.event.player.EventPlayerUpdate; +import me.rigamortis.seppuku.api.module.Module; +import me.rigamortis.seppuku.api.value.NumberValue; +import net.minecraft.client.Minecraft; +import team.stiff.pomelo.impl.annotated.handler.annotation.Listener; + +/** + * Author Seth + * 4/19/2019 @ 10:06 PM. + */ +public final class TimerModule extends Module { + + public final NumberValue speed = new NumberValue("Speed", new String[]{"Spd"}, 4.0f, Float.class, 0.0f, 10.0f, 0.1f); + + public TimerModule() { + super("Timer", new String[] {"Time", "Tmr"}, "Speeds up the client tick rate", "NONE", -1, ModuleType.WORLD); + } + + @Override + public void onDisable() { + super.onDisable(); + Minecraft.getMinecraft().timer.tickLength = 50; + } + + @Override + public String getMetaData() { + return "" + this.speed.getFloat(); + } + + @Listener + public void onUpdate(EventPlayerUpdate event) { + if(event.getStage() == EventStageable.EventStage.PRE) { + Minecraft.getMinecraft().timer.tickLength = 50.0f / speed.getFloat(); + } + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/module/world/WaypointsModule.java b/src/main/java/me/rigamortis/seppuku/impl/module/world/WaypointsModule.java new file mode 100644 index 0000000..815454c --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/module/world/WaypointsModule.java @@ -0,0 +1,137 @@ +package me.rigamortis.seppuku.impl.module.world; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.event.render.EventRender2D; +import me.rigamortis.seppuku.api.module.Module; +import me.rigamortis.seppuku.api.util.ColorUtil; +import me.rigamortis.seppuku.api.util.GLUProjection; +import me.rigamortis.seppuku.api.util.RenderUtil; +import me.rigamortis.seppuku.api.value.BooleanValue; +import me.rigamortis.seppuku.api.value.NumberValue; +import net.minecraft.client.Minecraft; +import team.stiff.pomelo.impl.annotated.handler.annotation.Listener; + +import java.text.DecimalFormat; + +/** + * Author Seth + * 5/8/2019 @ 6:46 AM. + */ +public final class WaypointsModule extends Module { + + public final BooleanValue tracers = new BooleanValue("Tracers", new String[]{"Tracer", "Trace"}, false); + + public final NumberValue width = new NumberValue("Width", new String[]{"Wid"}, 0.5f, Float.class, 0.0f, 5.0f, 0.1f); + + public WaypointsModule() { + super("Waypoints", new String[] {"Wp", "Waypoint"}, "Highlights waypoints", "NONE", -1, ModuleType.WORLD); + } + + @Listener + public void render2D(EventRender2D event) { + final Minecraft mc = Minecraft.getMinecraft(); + + final String host = mc.getCurrentServerData() == null ? "localhost" : mc.getCurrentServerData().serverIP; + + for(WaypointData waypointData : Seppuku.INSTANCE.getWaypointManager().getWaypointDataList()) { + if(waypointData != null) { + if(host.equalsIgnoreCase(waypointData.getHost()) && mc.player.dimension == waypointData.dimension) { + final double dist = mc.player.getDistance(waypointData.getX(), waypointData.getY(), waypointData.getZ()); + if(dist >= 5.0f) { + final GLUProjection.Projection projection = GLUProjection.getInstance().project(waypointData.getX() - mc.getRenderManager().viewerPosX, waypointData.getY() - mc.getRenderManager().viewerPosY, waypointData.getZ() - mc.getRenderManager().viewerPosZ, GLUProjection.ClampMode.NONE, false); + + if (projection != null && projection.getType() == GLUProjection.Projection.Type.INSIDE) { + final String name = "\247f" + waypointData.getName() + " \247r(\2477" + new DecimalFormat("#.#").format(dist) + "m\247r)"; + mc.fontRenderer.drawStringWithShadow(name, (float) projection.getX() - mc.fontRenderer.getStringWidth(name) / 2, (float) projection.getY() - mc.fontRenderer.FONT_HEIGHT / 2, waypointData.getColor()); + } + + if(this.tracers.getBoolean()) { + final GLUProjection.Projection screen = GLUProjection.getInstance().project(waypointData.getX() - mc.getRenderManager().viewerPosX, waypointData.getY() - mc.getRenderManager().viewerPosY, waypointData.getZ() - mc.getRenderManager().viewerPosZ, GLUProjection.ClampMode.NONE, true); + + if (screen != null) { + RenderUtil.drawLine((float) screen.getX(), (float) screen.getY(), event.getScaledResolution().getScaledWidth() / 2, event.getScaledResolution().getScaledHeight() / 2, this.width.getFloat(), -1); + } + } + } + } + } + } + } + + public static final class WaypointData { + private String host; + private String name; + private int dimension; + private double x; + private double y; + private double z; + private int color; + + public WaypointData(String host, String name, int dimension, double x, double y, double z) { + this.host = host; + this.name = name; + this.dimension = dimension; + this.x = x; + this.y = y; + this.z = z; + this.color = ColorUtil.getRandomColor(); + } + + public String getHost() { + return host; + } + + public void setHost(String host) { + this.host = host; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getDimension() { + return dimension; + } + + public void setDimension(int dimension) { + this.dimension = dimension; + } + + public double getX() { + return x; + } + + public void setX(double x) { + this.x = x; + } + + public double getY() { + return y; + } + + public void setY(double y) { + this.y = y; + } + + public double getZ() { + return z; + } + + public void setZ(double z) { + this.z = z; + } + + public int getColor() { + return color; + } + + public void setColor(int color) { + this.color = color; + } + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/patch/AbstractClientPlayerPatch.java b/src/main/java/me/rigamortis/seppuku/impl/patch/AbstractClientPlayerPatch.java new file mode 100644 index 0000000..91e8777 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/patch/AbstractClientPlayerPatch.java @@ -0,0 +1,42 @@ +package me.rigamortis.seppuku.impl.patch; + +import me.rigamortis.seppuku.api.patch.ClassPatch; +import me.rigamortis.seppuku.api.patch.MethodPatch; +import me.rigamortis.seppuku.impl.management.PatchManager; +import org.objectweb.asm.tree.*; + +import static org.objectweb.asm.Opcodes.*; + +/** + * Author Seth + * 7/9/2019 @ 3:34 AM. + */ +public final class AbstractClientPlayerPatch extends ClassPatch { + + public AbstractClientPlayerPatch() { + super("net.minecraft.client.entity.AbstractClientPlayer", "bua"); + } + + @MethodPatch( + mcpName = "getLocationCape", + notchName = "q", + mcpDesc = "()Lnet/minecraft/util/ResourceLocation;", + notchDesc = "()Lnf;") + public void getLocationCape(MethodNode methodNode, PatchManager.Environment env) { + final InsnList insnList = new InsnList(); + insnList.add(new FieldInsnNode(GETSTATIC, "me/rigamortis/seppuku/Seppuku", "INSTANCE", "Lme/rigamortis/seppuku/Seppuku;")); + insnList.add(new MethodInsnNode(INVOKEVIRTUAL, "me/rigamortis/seppuku/Seppuku", "getCapeManager", "()Lme/rigamortis/seppuku/impl/management/CapeManager;", false)); + insnList.add(new VarInsnNode(ALOAD, 0)); + insnList.add(new MethodInsnNode(INVOKEVIRTUAL, "me/rigamortis/seppuku/impl/management/CapeManager", "getCape", env == PatchManager.Environment.IDE ? "(Lnet/minecraft/client/entity/AbstractClientPlayer;)Lnet/minecraft/util/ResourceLocation;" : "(Lbua;)Lnf;", false)); + insnList.add(new VarInsnNode(ASTORE, 2)); + + insnList.add(new VarInsnNode(ALOAD, 2)); + final LabelNode labelNode = new LabelNode(); + insnList.add(new JumpInsnNode(IFNULL, labelNode)); + insnList.add(new VarInsnNode(ALOAD, 2)); + insnList.add(new InsnNode(ARETURN)); + insnList.add(labelNode); + methodNode.instructions.insert(insnList); + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/patch/AbstractHorsePatch.java b/src/main/java/me/rigamortis/seppuku/impl/patch/AbstractHorsePatch.java new file mode 100644 index 0000000..516ae7c --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/patch/AbstractHorsePatch.java @@ -0,0 +1,107 @@ +package me.rigamortis.seppuku.impl.patch; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.event.entity.EventHorseSaddled; +import me.rigamortis.seppuku.api.event.entity.EventSteerEntity; +import me.rigamortis.seppuku.api.patch.ClassPatch; +import me.rigamortis.seppuku.api.patch.MethodPatch; +import me.rigamortis.seppuku.impl.management.PatchManager; +import org.objectweb.asm.Type; +import org.objectweb.asm.tree.*; + +import static org.objectweb.asm.Opcodes.*; + +/** + * Author Seth + * 4/9/2019 @ 11:45 AM. + */ +public final class AbstractHorsePatch extends ClassPatch { + + public AbstractHorsePatch() { + super("net.minecraft.entity.passive.AbstractHorse", "aao"); + } + + /** + * This is where minecraft checks if you can steer horses + * @param methodNode + * @param env + */ + @MethodPatch( + mcpName = "canBeSteered", + notchName = "cV", + mcpDesc = "()Z") + public void canBeSteered(MethodNode methodNode, PatchManager.Environment env) { + //create a list of instructions and add the needed instructions to call our hook function + final InsnList insnList = new InsnList(); + //call our hook function + insnList.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "canBeSteeredHook", "()Z", false)); + //add a label to jump to + final LabelNode jmp = new LabelNode(); + //add if equals and pass the label + insnList.add(new JumpInsnNode(IFEQ, jmp)); + //add 1 or true + insnList.add(new InsnNode(ICONST_1)); + //add return so the rest of the function doesn't get called + insnList.add(new InsnNode(IRETURN)); + //add our label + insnList.add(jmp); + //insert the list of instructions at the top of the function + methodNode.instructions.insert(insnList); + } + + /** + * Our canBeSteered hook + * Used to allow us to steer and control horses without a saddle + * @return + */ + public static boolean canBeSteeredHook() { + //dispatch our event + final EventSteerEntity event = new EventSteerEntity(); + Seppuku.INSTANCE.getEventManager().dispatchEvent(event); + + return event.isCanceled(); + } + + /** + * This is where minecraft handles steering horses if they have a saddle on + * @param methodNode + * @param env + */ + @MethodPatch( + mcpName = "isHorseSaddled", + notchName = "dG", + mcpDesc = "()Z") + public void isHorseSaddled(MethodNode methodNode, PatchManager.Environment env) { + //create a list of instructions and add the needed instructions to call our hook function + final InsnList insnList = new InsnList(); + //call our hook function + insnList.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "isHorseSaddledHook", "()Z", false)); + //add a label to jump to + final LabelNode jmp = new LabelNode(); + //add if equals and pass the label + insnList.add(new JumpInsnNode(IFEQ, jmp)); + //add 1 or true + insnList.add(new InsnNode(ICONST_1)); + //add return so the rest of the function doesn't get called + insnList.add(new InsnNode(IRETURN)); + //add our label + insnList.add(jmp); + //insert the list of instructions at the top of the function + methodNode.instructions.insert(insnList); + } + + /** + * Our isHorseSaddled hook + * Allows us to control and ride horses without actually + * having a saddle + * @return + */ + public static boolean isHorseSaddledHook() { + //dispatch our event + final EventHorseSaddled event = new EventHorseSaddled(); + Seppuku.INSTANCE.getEventManager().dispatchEvent(event); + + return event.isCanceled(); + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/patch/ActiveRenderInfoPatch.java b/src/main/java/me/rigamortis/seppuku/impl/patch/ActiveRenderInfoPatch.java new file mode 100644 index 0000000..037d32d --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/patch/ActiveRenderInfoPatch.java @@ -0,0 +1,49 @@ +package me.rigamortis.seppuku.impl.patch; + +import me.rigamortis.seppuku.api.patch.ClassPatch; +import me.rigamortis.seppuku.api.patch.MethodPatch; +import me.rigamortis.seppuku.api.util.RenderUtil; +import me.rigamortis.seppuku.impl.management.PatchManager; +import org.objectweb.asm.Type; +import org.objectweb.asm.tree.InsnList; +import org.objectweb.asm.tree.MethodInsnNode; +import org.objectweb.asm.tree.MethodNode; + +import static org.objectweb.asm.Opcodes.*; + +/** + * Author Seth + * 4/16/2019 @ 2:39 AM. + */ +public final class ActiveRenderInfoPatch extends ClassPatch { + + public ActiveRenderInfoPatch() { + super("net.minecraft.client.renderer.ActiveRenderInfo", "bhv"); + } + + /** + * This is where minecraft updates the ModelViewProjection matrix + * @param methodNode + * @param env + */ + @MethodPatch( + mcpName = "updateRenderInfo", + notchName = "updateRenderInfo", + mcpDesc = "(Lnet/minecraft/entity/Entity;Z)V", + notchDesc = "(Lvg;Z)V") + public void updateRenderInfo(MethodNode methodNode, PatchManager.Environment env) { + //create a list of instructions + final InsnList insnList = new InsnList(); + //call our hook function + insnList.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "updateRenderInfoHook", "()V", false)); + //insert the list of instructions at the bottom of the function + methodNode.instructions.insert(insnList); + } + + public static void updateRenderInfoHook() { + //update our model view projection matrix used to converting 3D world coordinates + //to 2D screen coordinates + RenderUtil.updateModelViewProjectionMatrix(); + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/patch/BiomeColorHelperPatch.java b/src/main/java/me/rigamortis/seppuku/impl/patch/BiomeColorHelperPatch.java new file mode 100644 index 0000000..a4b508b --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/patch/BiomeColorHelperPatch.java @@ -0,0 +1,113 @@ +package me.rigamortis.seppuku.impl.patch; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.event.world.EventFoliageColor; +import me.rigamortis.seppuku.api.event.world.EventGrassColor; +import me.rigamortis.seppuku.api.event.world.EventWaterColor; +import me.rigamortis.seppuku.api.patch.ClassPatch; +import me.rigamortis.seppuku.api.patch.MethodPatch; +import me.rigamortis.seppuku.impl.management.PatchManager; +import org.objectweb.asm.Type; +import org.objectweb.asm.tree.*; +import team.stiff.pomelo.EventManager; + +import static org.objectweb.asm.Opcodes.*; + +/** + * Author Seth + * 8/11/2019 @ 1:46 AM. + */ +public final class BiomeColorHelperPatch extends ClassPatch { + + public BiomeColorHelperPatch() { + super("net.minecraft.world.biome.BiomeColorHelper", "anj"); + } + + @MethodPatch( + mcpName = "getGrassColorAtPos", + notchName = "a", + mcpDesc = "(Lnet/minecraft/world/IBlockAccess;Lnet/minecraft/util/math/BlockPos;)I", + notchDesc = "(Lamy;Let;)I") + public void getGrassColorAtPos(MethodNode methodNode, PatchManager.Environment env) { + final InsnList insnList = new InsnList(); + insnList.add(new TypeInsnNode(NEW, Type.getInternalName(EventGrassColor.class))); + insnList.add(new InsnNode(DUP)); + insnList.add(new MethodInsnNode(INVOKESPECIAL, Type.getInternalName(EventGrassColor.class), "", "()V", false)); + insnList.add(new VarInsnNode(ASTORE, 2)); + + insnList.add(new FieldInsnNode(GETSTATIC, Type.getInternalName(Seppuku.class), "INSTANCE", "Lme/rigamortis/seppuku/Seppuku;")); + insnList.add(new MethodInsnNode(INVOKEVIRTUAL, Type.getInternalName(Seppuku.class), "getEventManager", "()Lteam/stiff/pomelo/EventManager;", false)); + insnList.add(new VarInsnNode(ALOAD, 2)); + insnList.add(new MethodInsnNode(INVOKEINTERFACE, Type.getInternalName(EventManager.class), "dispatchEvent", "(Ljava/lang/Object;)Ljava/lang/Object;", true)); + insnList.add(new InsnNode(POP)); + + insnList.add(new VarInsnNode(ALOAD, 2)); + insnList.add(new MethodInsnNode(INVOKEVIRTUAL, Type.getInternalName(EventGrassColor.class), "isCanceled", "()Z", false)); + final LabelNode label = new LabelNode(); + insnList.add(new JumpInsnNode(IFEQ, label)); + insnList.add(new VarInsnNode(ALOAD, 2)); + insnList.add(new MethodInsnNode(INVOKEVIRTUAL, Type.getInternalName(EventGrassColor.class), "getColor", "()I", false)); + insnList.add(new InsnNode(IRETURN)); + insnList.add(label); + methodNode.instructions.insert(insnList); + } + + @MethodPatch( + mcpName = "getFoliageColorAtPos", + notchName = "b", + mcpDesc = "(Lnet/minecraft/world/IBlockAccess;Lnet/minecraft/util/math/BlockPos;)I", + notchDesc = "(Lamy;Let;)I") + public void getFoliageColorAtPos(MethodNode methodNode, PatchManager.Environment env) { + final InsnList insnList = new InsnList(); + insnList.add(new TypeInsnNode(NEW, Type.getInternalName(EventFoliageColor.class))); + insnList.add(new InsnNode(DUP)); + insnList.add(new MethodInsnNode(INVOKESPECIAL, Type.getInternalName(EventFoliageColor.class), "", "()V", false)); + insnList.add(new VarInsnNode(ASTORE, 2)); + + insnList.add(new FieldInsnNode(GETSTATIC, Type.getInternalName(Seppuku.class), "INSTANCE", "Lme/rigamortis/seppuku/Seppuku;")); + insnList.add(new MethodInsnNode(INVOKEVIRTUAL, Type.getInternalName(Seppuku.class), "getEventManager", "()Lteam/stiff/pomelo/EventManager;", false)); + insnList.add(new VarInsnNode(ALOAD, 2)); + insnList.add(new MethodInsnNode(INVOKEINTERFACE, Type.getInternalName(EventManager.class), "dispatchEvent", "(Ljava/lang/Object;)Ljava/lang/Object;", true)); + insnList.add(new InsnNode(POP)); + + insnList.add(new VarInsnNode(ALOAD, 2)); + insnList.add(new MethodInsnNode(INVOKEVIRTUAL, Type.getInternalName(EventFoliageColor.class), "isCanceled", "()Z", false)); + final LabelNode label = new LabelNode(); + insnList.add(new JumpInsnNode(IFEQ, label)); + insnList.add(new VarInsnNode(ALOAD, 2)); + insnList.add(new MethodInsnNode(INVOKEVIRTUAL, Type.getInternalName(EventFoliageColor.class), "getColor", "()I", false)); + insnList.add(new InsnNode(IRETURN)); + insnList.add(label); + methodNode.instructions.insert(insnList); + } + + @MethodPatch( + mcpName = "getWaterColorAtPos", + notchName = "c", + mcpDesc = "(Lnet/minecraft/world/IBlockAccess;Lnet/minecraft/util/math/BlockPos;)I", + notchDesc = "(Lamy;Let;)I") + public void getWaterColorAtPos(MethodNode methodNode, PatchManager.Environment env) { + final InsnList insnList = new InsnList(); + insnList.add(new TypeInsnNode(NEW, Type.getInternalName(EventWaterColor.class))); + insnList.add(new InsnNode(DUP)); + insnList.add(new MethodInsnNode(INVOKESPECIAL, Type.getInternalName(EventWaterColor.class), "", "()V", false)); + insnList.add(new VarInsnNode(ASTORE, 2)); + + insnList.add(new FieldInsnNode(GETSTATIC, Type.getInternalName(Seppuku.class), "INSTANCE", "Lme/rigamortis/seppuku/Seppuku;")); + insnList.add(new MethodInsnNode(INVOKEVIRTUAL, Type.getInternalName(Seppuku.class), "getEventManager", "()Lteam/stiff/pomelo/EventManager;", false)); + insnList.add(new VarInsnNode(ALOAD, 2)); + insnList.add(new MethodInsnNode(INVOKEINTERFACE, Type.getInternalName(EventManager.class), "dispatchEvent", "(Ljava/lang/Object;)Ljava/lang/Object;", true)); + insnList.add(new InsnNode(POP)); + + insnList.add(new VarInsnNode(ALOAD, 2)); + insnList.add(new MethodInsnNode(INVOKEVIRTUAL, Type.getInternalName(EventWaterColor.class), "isCanceled", "()Z", false)); + final LabelNode label = new LabelNode(); + insnList.add(new JumpInsnNode(IFEQ, label)); + insnList.add(new VarInsnNode(ALOAD, 2)); + insnList.add(new MethodInsnNode(INVOKEVIRTUAL, Type.getInternalName(EventWaterColor.class), "getColor", "()I", false)); + insnList.add(new InsnNode(IRETURN)); + insnList.add(label); + methodNode.instructions.insert(insnList); + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/patch/BlockFencePatch.java b/src/main/java/me/rigamortis/seppuku/impl/patch/BlockFencePatch.java new file mode 100644 index 0000000..654d4fe --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/patch/BlockFencePatch.java @@ -0,0 +1,59 @@ +package me.rigamortis.seppuku.impl.patch; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.event.world.EventAddCollisionBox; +import me.rigamortis.seppuku.api.patch.ClassPatch; +import me.rigamortis.seppuku.api.patch.MethodPatch; +import me.rigamortis.seppuku.impl.management.PatchManager; +import net.minecraft.entity.Entity; +import net.minecraft.util.math.BlockPos; +import org.objectweb.asm.Type; +import org.objectweb.asm.tree.*; + +import static org.objectweb.asm.Opcodes.*; + +/** + * Author Seth + * 5/20/2019 @ 3:38 PM. + */ +public final class BlockFencePatch extends ClassPatch { + + public BlockFencePatch() { + super("net.minecraft.block.BlockFence", "aqo"); + } + + @MethodPatch( + mcpName = "addCollisionBoxToList", + notchName = "a", + mcpDesc = "(Lnet/minecraft/block/state/IBlockState;Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/math/AxisAlignedBB;Ljava/util/List;Lnet/minecraft/entity/Entity;Z)V", + notchDesc = "(Lawt;Lamu;Let;Lbhb;Ljava/util/List;Lvg;Z)V") + public void addCollisionBoxToList(MethodNode methodNode, PatchManager.Environment env) { + //create a list of instructions + final InsnList insnList = new InsnList(); + //add ALOAD to pass the BlockPos in + insnList.add(new VarInsnNode(ALOAD, 3)); + //add ALOAD to pass the entity in + insnList.add(new VarInsnNode(ALOAD, 6)); + //call our hook function + insnList.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "addCollisionBoxToListHook", env == PatchManager.Environment.IDE ? "(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/entity/Entity;)Z" : "(Let;Lvg;)Z", false)); + //create a label to jump to + final LabelNode jmp = new LabelNode(); + //add "if equals" and pass our label in + insnList.add(new JumpInsnNode(IFEQ, jmp)); + //add return so the rest of the function doesn't get called + insnList.add(new InsnNode(RETURN)); + //add our label + insnList.add(jmp); + //insert our instructions + methodNode.instructions.insert(insnList); + } + + public static boolean addCollisionBoxToListHook(BlockPos pos, Entity entity) { + //dispatch our event and pass the block and entity in + final EventAddCollisionBox event = new EventAddCollisionBox(pos, entity); + Seppuku.INSTANCE.getEventManager().dispatchEvent(event); + + return event.isCanceled(); + } + +} \ No newline at end of file diff --git a/src/main/java/me/rigamortis/seppuku/impl/patch/BlockFluidRendererPatch.java b/src/main/java/me/rigamortis/seppuku/impl/patch/BlockFluidRendererPatch.java new file mode 100644 index 0000000..28a7d6f --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/patch/BlockFluidRendererPatch.java @@ -0,0 +1,80 @@ +package me.rigamortis.seppuku.impl.patch; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.event.render.EventRenderBlockModel; +import me.rigamortis.seppuku.api.event.render.EventRenderFluid; +import me.rigamortis.seppuku.api.patch.ClassPatch; +import me.rigamortis.seppuku.api.patch.MethodPatch; +import me.rigamortis.seppuku.impl.management.PatchManager; +import org.objectweb.asm.Type; +import org.objectweb.asm.tree.*; +import team.stiff.pomelo.EventManager; + +import static org.objectweb.asm.Opcodes.*; +import static org.objectweb.asm.Opcodes.INVOKEVIRTUAL; +import static org.objectweb.asm.Opcodes.IRETURN; + +/** + * Author Seth + * 4/11/2019 @ 3:18 AM. + */ +public final class BlockFluidRendererPatch extends ClassPatch { + + public BlockFluidRendererPatch() { + super("net.minecraft.client.renderer.BlockFluidRenderer", "bvn"); + } + + @MethodPatch( + mcpName = "renderFluid", + notchName = "a", + mcpDesc = "(Lnet/minecraft/world/IBlockAccess;Lnet/minecraft/block/state/IBlockState;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/client/renderer/BufferBuilder;)Z", + notchDesc = "(Lamy;Lawt;Let;Lbuk;)Z") + public void renderFluid(MethodNode methodNode, PatchManager.Environment env) { + //create a list of instructions + final InsnList insnList = new InsnList(); + //create a new instance of "EventRenderBlockSide" and dupe the top value on the stack + insnList.add(new TypeInsnNode(NEW, Type.getInternalName(EventRenderFluid.class))); + insnList.add(new InsnNode(DUP)); + //add ALOAD to pass IBlockAccess into our call + insnList.add(new VarInsnNode(ALOAD, 1)); + //add ALOAD to pass IBlockState into our call + insnList.add(new VarInsnNode(ALOAD, 2)); + //add ALOAD to pass BlockPos into our call + insnList.add(new VarInsnNode(ALOAD, 3)); + //add ALOAD to pass BufferBuilder into our call + insnList.add(new VarInsnNode(ALOAD, 4)); + //call "EventRenderFluid" constructor + insnList.add(new MethodInsnNode(INVOKESPECIAL, Type.getInternalName(EventRenderFluid.class), "", env == PatchManager.Environment.IDE ? "(Lnet/minecraft/world/IBlockAccess;Lnet/minecraft/block/state/IBlockState;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/client/renderer/BufferBuilder;)V" : "(Lamy;Lawt;Let;Lbuk;)V", false)); + //store our event in the local vars + insnList.add(new VarInsnNode(ASTORE, 60)); + //Seppuku.INSTANCE + insnList.add(new FieldInsnNode(GETSTATIC, Type.getInternalName(Seppuku.class), "INSTANCE", "Lme/rigamortis/seppuku/Seppuku;")); + //getEventManager + insnList.add(new MethodInsnNode(INVOKEVIRTUAL, Type.getInternalName(Seppuku.class), "getEventManager", "()Lteam/stiff/pomelo/EventManager;", false)); + //add ALOAD to access our event + insnList.add(new VarInsnNode(ALOAD, 60)); + //call EventManager.dispatchEvent and pass our event in + insnList.add(new MethodInsnNode(INVOKEINTERFACE, Type.getInternalName(EventManager.class), "dispatchEvent", "(Ljava/lang/Object;)Ljava/lang/Object;", true)); + //remove the top value on the stack + insnList.add(new InsnNode(POP)); + //add ALOAD to access our event + insnList.add(new VarInsnNode(ALOAD, 60)); + //call EventRenderFluid.isCanceled + insnList.add(new MethodInsnNode(INVOKEVIRTUAL, Type.getInternalName(EventRenderFluid.class), "isCanceled", "()Z", false)); + //create a label to jump to + final LabelNode jmp = new LabelNode(); + //add "if equals" + insnList.add(new JumpInsnNode(IFEQ, jmp)); + //add ALOAD to access our event + insnList.add(new VarInsnNode(ALOAD, 60)); + //call EventRenderFluid.isRenderable + insnList.add(new MethodInsnNode(INVOKEVIRTUAL, Type.getInternalName(EventRenderFluid.class), "isRenderable", "()Z", false)); + //return the value of isRenderable + insnList.add(new InsnNode(IRETURN)); + //add our label + insnList.add(jmp); + //add our instructions at the top of the function + methodNode.instructions.insert(insnList); + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/patch/BlockLiquidPatch.java b/src/main/java/me/rigamortis/seppuku/impl/patch/BlockLiquidPatch.java new file mode 100644 index 0000000..f28faef --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/patch/BlockLiquidPatch.java @@ -0,0 +1,146 @@ +package me.rigamortis.seppuku.impl.patch; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.event.render.EventRenderBlockSide; +import me.rigamortis.seppuku.api.event.world.EventCanCollide; +import me.rigamortis.seppuku.api.event.world.EventLiquidCollisionBB; +import me.rigamortis.seppuku.api.patch.ClassPatch; +import me.rigamortis.seppuku.api.patch.MethodPatch; +import me.rigamortis.seppuku.impl.management.PatchManager; +import org.objectweb.asm.Type; +import org.objectweb.asm.tree.*; +import team.stiff.pomelo.EventManager; + +import static org.objectweb.asm.Opcodes.*; + +/** + * Author Seth + * 4/16/2019 @ 7:32 AM. + */ +public final class BlockLiquidPatch extends ClassPatch { + + public BlockLiquidPatch() { + super("net.minecraft.block.BlockLiquid", "aru"); + } + + /** + * This is where minecraft handles the collision boundingboxes for liquids + * @param methodNode + * @param env + */ + @MethodPatch( + mcpName = "getCollisionBoundingBox", + notchName = "a", + mcpDesc = "(Lnet/minecraft/block/state/IBlockState;Lnet/minecraft/world/IBlockAccess;Lnet/minecraft/util/math/BlockPos;)Lnet/minecraft/util/math/AxisAlignedBB;", + notchDesc = "(Lawt;Lamy;Let;)Lbhb;") + public void getCollisionBoundingBox(MethodNode methodNode, PatchManager.Environment env) { + //create a list of instructions + final InsnList insnList = new InsnList(); + //create a new instance of "EventLiquidCollisionBB" and dupe the top val on the stack + insnList.add(new TypeInsnNode(NEW, Type.getInternalName(EventLiquidCollisionBB.class))); + insnList.add(new InsnNode(DUP)); + //add ALOAD to pass the BlockPos into our call + insnList.add(new VarInsnNode(ALOAD, 3)); + //call "EventLiquidCollisionBB" constructor + insnList.add(new MethodInsnNode(INVOKESPECIAL, Type.getInternalName(EventLiquidCollisionBB.class), "", env == PatchManager.Environment.IDE ? "(Lnet/minecraft/util/math/BlockPos;)V" : "(Let;)V", false)); + //add ASTORE to store our event in the local vars + insnList.add(new VarInsnNode(ASTORE, 4)); + //Seppuku.INSTANCE.getEventManager + insnList.add(new FieldInsnNode(GETSTATIC, Type.getInternalName(Seppuku.class), "INSTANCE", "Lme/rigamortis/seppuku/Seppuku;")); + insnList.add(new MethodInsnNode(INVOKEVIRTUAL, Type.getInternalName(Seppuku.class), "getEventManager", "()Lteam/stiff/pomelo/EventManager;", false)); + //add ALOAD to access our event from the local vars + insnList.add(new VarInsnNode(ALOAD, 4)); + //call dispatchEvent and pass our event in + insnList.add(new MethodInsnNode(INVOKEINTERFACE, Type.getInternalName(EventManager.class), "dispatchEvent", "(Ljava/lang/Object;)Ljava/lang/Object;", true)); + //remove the top value on the stack + insnList.add(new InsnNode(POP)); + //add ALOAD to access our event from the local vars + insnList.add(new VarInsnNode(ALOAD, 4)); + //call EventLiquidCollisionBB.isCanceled + insnList.add(new MethodInsnNode(INVOKEVIRTUAL, Type.getInternalName(EventLiquidCollisionBB.class), "isCanceled", "()Z", false)); + //create a label to jump to + final LabelNode jmp = new LabelNode(); + //add "if equals" and pass in our label + insnList.add(new JumpInsnNode(IFEQ, jmp)); + //add ALOAD to access our event from the local vars + insnList.add(new VarInsnNode(ALOAD, 4)); + //call getBoundingBox + insnList.add(new MethodInsnNode(INVOKEVIRTUAL, Type.getInternalName(EventLiquidCollisionBB.class), "getBoundingBox", env == PatchManager.Environment.IDE ? "()Lnet/minecraft/util/math/AxisAlignedBB;" : "()Lbhb;", false)); + //add ARETURN to return our bb + insnList.add(new InsnNode(ARETURN)); + //add our label + insnList.add(jmp); + //insert the list of instructions + methodNode.instructions.insert(insnList); + } + + @MethodPatch( + mcpName = "shouldSideBeRendered", + notchName = "a", + mcpDesc = "(Lnet/minecraft/block/state/IBlockState;Lnet/minecraft/world/IBlockAccess;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/EnumFacing;)Z", + notchDesc = "(Lawt;Lamy;Let;Lfa;)Z") + public void shouldSideBeRendered(MethodNode methodNode, PatchManager.Environment env) { +//create a list of instructions + final InsnList insnList = new InsnList(); + //create a new instance of "EventRenderBlockSide" and dupe the top value on the stack + insnList.add(new TypeInsnNode(NEW, Type.getInternalName(EventRenderBlockSide.class))); + insnList.add(new InsnNode(DUP)); + //add ALOAD 0 to pass "this" into the event + insnList.add(new VarInsnNode(ALOAD, 0)); + //call "EventRenderBlockSide" constructor + insnList.add(new MethodInsnNode(INVOKESPECIAL, Type.getInternalName(EventRenderBlockSide.class), "", env == PatchManager.Environment.IDE ? "(Lnet/minecraft/block/Block;)V" : "(Laow;)V", false)); + //store our event in the local vars + insnList.add(new VarInsnNode(ASTORE, 5)); + //Seppuku.INSTANCE + insnList.add(new FieldInsnNode(GETSTATIC, Type.getInternalName(Seppuku.class), "INSTANCE", "Lme/rigamortis/seppuku/Seppuku;")); + //getEventManager + insnList.add(new MethodInsnNode(INVOKEVIRTUAL, Type.getInternalName(Seppuku.class), "getEventManager", "()Lteam/stiff/pomelo/EventManager;", false)); + //add ALOAD to access our event + insnList.add(new VarInsnNode(ALOAD, 5)); + //call EventManager.dispatchEvent and pass our event in + insnList.add(new MethodInsnNode(INVOKEINTERFACE, Type.getInternalName(EventManager.class), "dispatchEvent", "(Ljava/lang/Object;)Ljava/lang/Object;", true)); + //remove the top value on the stack + insnList.add(new InsnNode(POP)); + //add ALOAD to access our event + insnList.add(new VarInsnNode(ALOAD, 5)); + //call EventRenderBlockSide.isCanceled + insnList.add(new MethodInsnNode(INVOKEVIRTUAL, Type.getInternalName(EventRenderBlockSide.class), "isCanceled", "()Z", false)); + //create a label to jump to + final LabelNode jmp = new LabelNode(); + //add "if equals" + insnList.add(new JumpInsnNode(IFEQ, jmp)); + //add ALOAD to access our event + insnList.add(new VarInsnNode(ALOAD, 5)); + //call EventRenderBlockSide.isRenderable + insnList.add(new MethodInsnNode(INVOKEVIRTUAL, Type.getInternalName(EventRenderBlockSide.class), "isRenderable", "()Z", false)); + //return the value of isRenderable + insnList.add(new InsnNode(IRETURN)); + //add our label + insnList.add(jmp); + //add our instructions at the top of the function + methodNode.instructions.insert(insnList); + } + + @MethodPatch( + mcpName = "canCollideCheck", + notchName = "a", + mcpDesc = "(Lnet/minecraft/block/state/IBlockState;Z)Z", + notchDesc = "(Lawt;Z)Z") + public void canCollideCheck(MethodNode methodNode, PatchManager.Environment env) { + final InsnList preInsn = new InsnList(); + preInsn.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "canCollideCheckHook", "()Z", false)); + final LabelNode jmp = new LabelNode(); + preInsn.add(new JumpInsnNode(IFEQ, jmp)); + preInsn.add(new InsnNode(ICONST_1)); + preInsn.add(new InsnNode(IRETURN)); + preInsn.add(jmp); + methodNode.instructions.insert(preInsn); + } + + public static boolean canCollideCheckHook() { + final EventCanCollide event = new EventCanCollide(); + Seppuku.INSTANCE.getEventManager().dispatchEvent(event); + return event.isCanceled(); + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/patch/BlockModelRendererPatch.java b/src/main/java/me/rigamortis/seppuku/impl/patch/BlockModelRendererPatch.java new file mode 100644 index 0000000..62f69a8 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/patch/BlockModelRendererPatch.java @@ -0,0 +1,83 @@ +package me.rigamortis.seppuku.impl.patch; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.event.render.EventRenderBlockModel; +import me.rigamortis.seppuku.api.patch.ClassPatch; +import me.rigamortis.seppuku.api.patch.MethodPatch; +import me.rigamortis.seppuku.impl.management.PatchManager; +import org.objectweb.asm.Type; +import org.objectweb.asm.tree.*; +import team.stiff.pomelo.EventManager; + +import static org.objectweb.asm.Opcodes.*; + +/** + * Author Seth + * 4/10/2019 @ 4:04 AM. + */ +public final class BlockModelRendererPatch extends ClassPatch { + + public BlockModelRendererPatch() { + super("net.minecraft.client.renderer.BlockModelRenderer", "bvo"); + } + + @MethodPatch( + mcpName = "renderModel", + notchName = "a", + mcpDesc = "(Lnet/minecraft/world/IBlockAccess;Lnet/minecraft/client/renderer/block/model/IBakedModel;Lnet/minecraft/block/state/IBlockState;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/client/renderer/BufferBuilder;ZJ)Z", + notchDesc = "(Lamy;Lcfy;Lawt;Let;Lbuk;ZJ)Z") + public void renderModel(MethodNode methodNode, PatchManager.Environment env) { + //create a list of instructions + final InsnList insnList = new InsnList(); + //create a new instance of "EventRenderBlockSide" and dupe the top value on the stack + insnList.add(new TypeInsnNode(NEW, Type.getInternalName(EventRenderBlockModel.class))); + insnList.add(new InsnNode(DUP)); + //add ALOAD to pass IBlockAccess into our call + insnList.add(new VarInsnNode(ALOAD, 1)); + //add ALOAD to pass IBakedModel into our call + insnList.add(new VarInsnNode(ALOAD, 2)); + //add ALOAD to pass IBlockState into our call + insnList.add(new VarInsnNode(ALOAD, 3)); + //add ALOAD to pass BlockPos into our call + insnList.add(new VarInsnNode(ALOAD, 4)); + //add ALOAD to pass BufferBuilder into our call + insnList.add(new VarInsnNode(ALOAD, 5)); + //add ILOAD to pass checkSides into our call + insnList.add(new VarInsnNode(ILOAD, 6)); + //add LLOAD to pass rand into our call + insnList.add(new VarInsnNode(LLOAD, 7)); + //call "EventRenderBlockModel" constructor + insnList.add(new MethodInsnNode(INVOKESPECIAL, Type.getInternalName(EventRenderBlockModel.class), "", env == PatchManager.Environment.IDE ? "(Lnet/minecraft/world/IBlockAccess;Lnet/minecraft/client/renderer/block/model/IBakedModel;Lnet/minecraft/block/state/IBlockState;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/client/renderer/BufferBuilder;ZJ)V" : "(Lamy;Lcfy;Lawt;Let;Lbuk;ZJ)V", false)); + //store our event in the local vars + insnList.add(new VarInsnNode(ASTORE, 13)); + //Seppuku.INSTANCE + insnList.add(new FieldInsnNode(GETSTATIC, Type.getInternalName(Seppuku.class), "INSTANCE", "Lme/rigamortis/seppuku/Seppuku;")); + //getEventManager + insnList.add(new MethodInsnNode(INVOKEVIRTUAL, Type.getInternalName(Seppuku.class), "getEventManager", "()Lteam/stiff/pomelo/EventManager;", false)); + //add ALOAD to access our event + insnList.add(new VarInsnNode(ALOAD, 13)); + //call EventManager.dispatchEvent and pass our event in + insnList.add(new MethodInsnNode(INVOKEINTERFACE, Type.getInternalName(EventManager.class), "dispatchEvent", "(Ljava/lang/Object;)Ljava/lang/Object;", true)); + //remove the top value on the stack + insnList.add(new InsnNode(POP)); + //add ALOAD to access our event + insnList.add(new VarInsnNode(ALOAD, 13)); + //call EventRenderBlockModel.isCanceled + insnList.add(new MethodInsnNode(INVOKEVIRTUAL, Type.getInternalName(EventRenderBlockModel.class), "isCanceled", "()Z", false)); + //create a label to jump to + final LabelNode jmp = new LabelNode(); + //add "if equals" + insnList.add(new JumpInsnNode(IFEQ, jmp)); + //add ALOAD to access our event + insnList.add(new VarInsnNode(ALOAD, 13)); + //call EventRenderBlockModel.isRenderable + insnList.add(new MethodInsnNode(INVOKEVIRTUAL, Type.getInternalName(EventRenderBlockModel.class), "isRenderable", "()Z", false)); + //return the value of isRenderable + insnList.add(new InsnNode(IRETURN)); + //add our label + insnList.add(jmp); + //add our instructions at the top of the function + methodNode.instructions.insert(insnList); + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/patch/BlockPanePatch.java b/src/main/java/me/rigamortis/seppuku/impl/patch/BlockPanePatch.java new file mode 100644 index 0000000..93b843c --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/patch/BlockPanePatch.java @@ -0,0 +1,59 @@ +package me.rigamortis.seppuku.impl.patch; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.event.world.EventAddCollisionBox; +import me.rigamortis.seppuku.api.patch.ClassPatch; +import me.rigamortis.seppuku.api.patch.MethodPatch; +import me.rigamortis.seppuku.impl.management.PatchManager; +import net.minecraft.entity.Entity; +import net.minecraft.util.math.BlockPos; +import org.objectweb.asm.Type; +import org.objectweb.asm.tree.*; + +import static org.objectweb.asm.Opcodes.*; + +/** + * Author Seth + * 5/20/2019 @ 3:28 PM. + */ +public final class BlockPanePatch extends ClassPatch { + + public BlockPanePatch() { + super("net.minecraft.block.BlockPane", "auo"); + } + + @MethodPatch( + mcpName = "addCollisionBoxToList", + notchName = "a", + mcpDesc = "(Lnet/minecraft/block/state/IBlockState;Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/math/AxisAlignedBB;Ljava/util/List;Lnet/minecraft/entity/Entity;Z)V", + notchDesc = "(Lawt;Lamu;Let;Lbhb;Ljava/util/List;Lvg;Z)V") + public void addCollisionBoxToList(MethodNode methodNode, PatchManager.Environment env) { + //create a list of instructions + final InsnList insnList = new InsnList(); + //add ALOAD to pass the BlockPos in + insnList.add(new VarInsnNode(ALOAD, 3)); + //add ALOAD to pass the entity in + insnList.add(new VarInsnNode(ALOAD, 6)); + //call our hook function + insnList.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "addCollisionBoxToListHook", env == PatchManager.Environment.IDE ? "(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/entity/Entity;)Z" : "(Let;Lvg;)Z", false)); + //create a label to jump to + final LabelNode jmp = new LabelNode(); + //add "if equals" and pass our label in + insnList.add(new JumpInsnNode(IFEQ, jmp)); + //add return so the rest of the function doesn't get called + insnList.add(new InsnNode(RETURN)); + //add our label + insnList.add(jmp); + //insert our instructions + methodNode.instructions.insert(insnList); + } + + public static boolean addCollisionBoxToListHook(BlockPos pos, Entity entity) { + //dispatch our event and pass the block and entity in + final EventAddCollisionBox event = new EventAddCollisionBox(pos, entity); + Seppuku.INSTANCE.getEventManager().dispatchEvent(event); + + return event.isCanceled(); + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/patch/BlockPatch.java b/src/main/java/me/rigamortis/seppuku/impl/patch/BlockPatch.java new file mode 100644 index 0000000..7903c0b --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/patch/BlockPatch.java @@ -0,0 +1,173 @@ +package me.rigamortis.seppuku.impl.patch; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.event.world.EventAddCollisionBox; +import me.rigamortis.seppuku.api.event.world.EventGetBlockLayer; +import me.rigamortis.seppuku.api.event.render.EventRenderBlockSide; +import me.rigamortis.seppuku.api.patch.ClassPatch; +import me.rigamortis.seppuku.api.patch.MethodPatch; +import me.rigamortis.seppuku.impl.management.PatchManager; +import net.minecraft.entity.Entity; +import net.minecraft.util.math.BlockPos; +import org.objectweb.asm.Type; +import org.objectweb.asm.tree.*; +import team.stiff.pomelo.EventManager; + +import static org.objectweb.asm.Opcodes.*; + +/** + * Author Seth + * 4/9/2019 @ 12:10 PM. + */ +public final class BlockPatch extends ClassPatch { + + public BlockPatch() { + super("net.minecraft.block.Block", "aow"); + } + + /** + * This is where minecraft handles what side of a + * block should be rendered + * + * @param methodNode + * @param env + */ + @MethodPatch( + mcpName = "shouldSideBeRendered", + notchName = "a", + mcpDesc = "(Lnet/minecraft/block/state/IBlockState;Lnet/minecraft/world/IBlockAccess;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/EnumFacing;)Z", + notchDesc = "(Lawt;Lamy;Let;Lfa;)Z") + public void shouldSideBeRendered(MethodNode methodNode, PatchManager.Environment env) { + //create a list of instructions + final InsnList insnList = new InsnList(); + //create a new instance of "EventRenderBlockSide" and dupe the top value on the stack + insnList.add(new TypeInsnNode(NEW, Type.getInternalName(EventRenderBlockSide.class))); + insnList.add(new InsnNode(DUP)); + //add ALOAD 0 to pass "this" into the event + insnList.add(new VarInsnNode(ALOAD, 0)); + //call "EventRenderBlockSide" constructor + insnList.add(new MethodInsnNode(INVOKESPECIAL, Type.getInternalName(EventRenderBlockSide.class), "", env == PatchManager.Environment.IDE ? "(Lnet/minecraft/block/Block;)V" : "(Laow;)V", false)); + //store our event in the local vars + insnList.add(new VarInsnNode(ASTORE, 6)); + //Seppuku.INSTANCE + insnList.add(new FieldInsnNode(GETSTATIC, Type.getInternalName(Seppuku.class), "INSTANCE", "Lme/rigamortis/seppuku/Seppuku;")); + //getEventManager + insnList.add(new MethodInsnNode(INVOKEVIRTUAL, Type.getInternalName(Seppuku.class), "getEventManager", "()Lteam/stiff/pomelo/EventManager;", false)); + //add ALOAD to access our event + insnList.add(new VarInsnNode(ALOAD, 6)); + //call EventManager.dispatchEvent and pass our event in + insnList.add(new MethodInsnNode(INVOKEINTERFACE, Type.getInternalName(EventManager.class), "dispatchEvent", "(Ljava/lang/Object;)Ljava/lang/Object;", true)); + //remove the top value on the stack + insnList.add(new InsnNode(POP)); + //add ALOAD to access our event + insnList.add(new VarInsnNode(ALOAD, 6)); + //call EventRenderBlockSide.isCanceled + insnList.add(new MethodInsnNode(INVOKEVIRTUAL, Type.getInternalName(EventRenderBlockSide.class), "isCanceled", "()Z", false)); + //create a label to jump to + final LabelNode jmp = new LabelNode(); + //add "if equals" + insnList.add(new JumpInsnNode(IFEQ, jmp)); + //add ALOAD to access our event + insnList.add(new VarInsnNode(ALOAD, 6)); + //call EventRenderBlockSide.isRenderable + insnList.add(new MethodInsnNode(INVOKEVIRTUAL, Type.getInternalName(EventRenderBlockSide.class), "isRenderable", "()Z", false)); + //return the value of isRenderable + insnList.add(new InsnNode(IRETURN)); + //add our label + insnList.add(jmp); + //add our instructions at the top of the function + methodNode.instructions.insert(insnList); + } + + @MethodPatch( + mcpName = "getBlockLayer", + notchName = "f", + mcpDesc = "Lnet/minecraft/util/BlockRenderLayer;", + notchDesc = "Lamm;") + public void getBlockLayer(MethodNode methodNode, PatchManager.Environment env) { + //create a list of instructions + final InsnList insnList = new InsnList(); + //create a new instance of "EventGetBlockLayer" and dupe the top value on the stack + insnList.add(new TypeInsnNode(NEW, Type.getInternalName(EventGetBlockLayer.class))); + insnList.add(new InsnNode(DUP)); + //add ALOAD 0 to pass "this" into the event + insnList.add(new VarInsnNode(ALOAD, 0)); + //call "EventGetBlockLayer" constructor + insnList.add(new MethodInsnNode(INVOKESPECIAL, Type.getInternalName(EventGetBlockLayer.class), "", env == PatchManager.Environment.IDE ? "(Lnet/minecraft/block/Block;)V" : "(Laow;)V", false)); + //store our event in the local vars + insnList.add(new VarInsnNode(ASTORE, 1)); + //Seppuku.INSTANCE + insnList.add(new FieldInsnNode(GETSTATIC, Type.getInternalName(Seppuku.class), "INSTANCE", "Lme/rigamortis/seppuku/Seppuku;")); + //getEventManager + insnList.add(new MethodInsnNode(INVOKEVIRTUAL, Type.getInternalName(Seppuku.class), "getEventManager", "()Lteam/stiff/pomelo/EventManager;", false)); + //add ALOAD to access our event + insnList.add(new VarInsnNode(ALOAD, 1)); + //call EventManager.dispatchEvent and pass our event in + insnList.add(new MethodInsnNode(INVOKEINTERFACE, Type.getInternalName(EventManager.class), "dispatchEvent", "(Ljava/lang/Object;)Ljava/lang/Object;", true)); + //remove the top value on the stack + insnList.add(new InsnNode(POP)); + //add ALOAD to access our event + insnList.add(new VarInsnNode(ALOAD, 1)); + //call EventGetBlockLayer.isCanceled + insnList.add(new MethodInsnNode(INVOKEVIRTUAL, Type.getInternalName(EventGetBlockLayer.class), "isCanceled", "()Z", false)); + //create a label to jump to + final LabelNode jmp = new LabelNode(); + //add "if equals" + insnList.add(new JumpInsnNode(IFEQ, jmp)); + //add ALOAD to access our event + insnList.add(new VarInsnNode(ALOAD, 1)); + //call EventGetBlockLayer.getLayer + insnList.add(new MethodInsnNode(INVOKEVIRTUAL, Type.getInternalName(EventGetBlockLayer.class), "getLayer", env == PatchManager.Environment.IDE ? "()Lnet/minecraft/util/BlockRenderLayer;" : "()Lamm;", false)); + //return the value of getLayer + insnList.add(new InsnNode(ARETURN)); + //add our label + insnList.add(jmp); + //add our instructions at the top of the function + methodNode.instructions.insert(insnList); + } + + /** + * This is where minecraft adds aabb's for block collision + * @param methodNode + * @param env + */ + @MethodPatch( + mcpName = "addCollisionBoxToList", + notchName = "a", + mcpDesc = "(Lnet/minecraft/block/state/IBlockState;Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/math/AxisAlignedBB;Ljava/util/List;Lnet/minecraft/entity/Entity;Z)V", + notchDesc = "(Lawt;Lamu;Let;Lbhb;Ljava/util/List;Lvg;Z)V") + public void addCollisionBoxToList(MethodNode methodNode, PatchManager.Environment env) { + //create a list of instructions + final InsnList insnList = new InsnList(); + //add ALOAD to pass the BlockPos in + insnList.add(new VarInsnNode(ALOAD, 3)); + //add ALOAD to pass the entity in + insnList.add(new VarInsnNode(ALOAD, 6)); + //call our hook function + insnList.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "addCollisionBoxToListHook", env == PatchManager.Environment.IDE ? "(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/entity/Entity;)Z" : "(Let;Lvg;)Z", false)); + //create a label to jump to + final LabelNode jmp = new LabelNode(); + //add "if equals" and pass our label in + insnList.add(new JumpInsnNode(IFEQ, jmp)); + //add return so the rest of the function doesn't get called + insnList.add(new InsnNode(RETURN)); + //add our label + insnList.add(jmp); + //insert our instructions + methodNode.instructions.insert(insnList); + } + + /** + * Our addCollisionBoxToList hook used to disable block collision + * @param entity + * @return + */ + public static boolean addCollisionBoxToListHook(BlockPos pos, Entity entity) { + //dispatch our event and pass the block and entity in + final EventAddCollisionBox event = new EventAddCollisionBox(pos, entity); + Seppuku.INSTANCE.getEventManager().dispatchEvent(event); + + return event.isCanceled(); + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/patch/BlockSlimePatch.java b/src/main/java/me/rigamortis/seppuku/impl/patch/BlockSlimePatch.java new file mode 100644 index 0000000..788865d --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/patch/BlockSlimePatch.java @@ -0,0 +1,104 @@ +package me.rigamortis.seppuku.impl.patch; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.event.world.EventLandOnSlime; +import me.rigamortis.seppuku.api.event.world.EventWalkOnSlime; +import me.rigamortis.seppuku.api.patch.ClassPatch; +import me.rigamortis.seppuku.api.patch.MethodPatch; +import me.rigamortis.seppuku.impl.management.PatchManager; +import org.objectweb.asm.Type; +import org.objectweb.asm.tree.*; + +import static org.objectweb.asm.Opcodes.IFEQ; +import static org.objectweb.asm.Opcodes.INVOKESTATIC; +import static org.objectweb.asm.Opcodes.RETURN; + +/** + * Author Seth + * 4/16/2019 @ 3:37 AM. + */ +public final class BlockSlimePatch extends ClassPatch { + + public BlockSlimePatch() { + super("net.minecraft.block.BlockSlime", "atu"); + } + + /** + * This is where minecraft slows us down while walking on slime blocks + * @param methodNode + * @param env + */ + @MethodPatch( + mcpName = "onEntityWalk", + notchName = "a", + mcpDesc = "(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/entity/Entity;)V", + notchDesc = "(Lamu;Let;Lvg;)V") + public void onEntityWalk(MethodNode methodNode, PatchManager.Environment env) { + //create a list of instructions and add the needed instructions to call our hook function + final InsnList insnList = new InsnList(); + //call our hook function + insnList.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "onEntityWalkHook", "()Z", false)); + //add a label to jump to + final LabelNode jmp = new LabelNode(); + //add if equals and pass the label + insnList.add(new JumpInsnNode(IFEQ, jmp)); + //add return so the rest of the function doesn't get called + insnList.add(new InsnNode(RETURN)); + //add our label + insnList.add(jmp); + //insert the list of instructions at the top of the function + methodNode.instructions.insert(insnList); + } + + /** + * Our onEntityWalk hook + * Used to stop minecraft from slowing us down while + * walking on slime blocks + * @return + */ + public static boolean onEntityWalkHook() { + final EventWalkOnSlime event = new EventWalkOnSlime(); + Seppuku.INSTANCE.getEventManager().dispatchEvent(event); + + return event.isCanceled(); + } + + /** + * This is where minecraft makes us bounce when we land on a slime + * @param methodNode + * @param env + */ + @MethodPatch( + mcpName = "onLanded", + notchName = "a", + mcpDesc = "(Lnet/minecraft/world/World;Lnet/minecraft/entity/Entity;)V", + notchDesc = "(Lamu;Lvg;)V") + public void onLanded(MethodNode methodNode, PatchManager.Environment env) { + //create a list of instructions and add the needed instructions to call our hook function + final InsnList insnList = new InsnList(); + //call our hook function + insnList.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "onLanded", "()Z", false)); + //add a label to jump to + final LabelNode jmp = new LabelNode(); + //add if equals and pass the label + insnList.add(new JumpInsnNode(IFEQ, jmp)); + //add return so the rest of the function doesn't get called + insnList.add(new InsnNode(RETURN)); + //add our label + insnList.add(jmp); + //insert the list of instructions at the top of the function + methodNode.instructions.insert(insnList); + } + + /** + * Our onLanded hook used to remove slime bouncing + * @return + */ + public static boolean onLanded() { + final EventLandOnSlime event = new EventLandOnSlime(); + Seppuku.INSTANCE.getEventManager().dispatchEvent(event); + + return event.isCanceled(); + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/patch/BlockSoulSandPatch.java b/src/main/java/me/rigamortis/seppuku/impl/patch/BlockSoulSandPatch.java new file mode 100644 index 0000000..b81ca33 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/patch/BlockSoulSandPatch.java @@ -0,0 +1,64 @@ +package me.rigamortis.seppuku.impl.patch; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.event.world.EventCollideSoulSand; +import me.rigamortis.seppuku.api.patch.ClassPatch; +import me.rigamortis.seppuku.api.patch.MethodPatch; +import me.rigamortis.seppuku.impl.management.PatchManager; +import org.objectweb.asm.Type; +import org.objectweb.asm.tree.*; + +import static org.objectweb.asm.Opcodes.IFEQ; +import static org.objectweb.asm.Opcodes.INVOKESTATIC; +import static org.objectweb.asm.Opcodes.RETURN; + +/** + * Author Seth + * 4/10/2019 @ 2:51 AM. + */ +public final class BlockSoulSandPatch extends ClassPatch { + + public BlockSoulSandPatch() { + super("net.minecraft.block.BlockSoulSand", "atx"); + } + + /** + * This is where minecraft slows you down when moving on soul sand + * @param methodNode + * @param env + */ + @MethodPatch( + mcpName = "onEntityCollidedWithBlock", + notchName = "a", + mcpDesc = "(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/state/IBlockState;Lnet/minecraft/entity/Entity;)V", + notchDesc = "(Lamu;Let;Lawt;Lvg;)V") + public void onEntityCollidedWithBlock(MethodNode methodNode, PatchManager.Environment env) { + //create a list of instructions and add the needed instructions to call our hook function + final InsnList insnList = new InsnList(); + //call our hook function + insnList.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "onEntityCollidedWithBlockHook", "()Z", false)); + //add a label to jump to + final LabelNode jmp = new LabelNode(); + //add if equals and pass the label + insnList.add(new JumpInsnNode(IFEQ, jmp)); + //add return so the rest of the function doesn't get called + insnList.add(new InsnNode(RETURN)); + //add our label + insnList.add(jmp); + //insert the list of instructions at the top of the function + methodNode.instructions.insert(insnList); + } + + /** + * Our onEntityCollidedWithBlock hook used to disable + * the slowing of movement while on soul sand + * @return + */ + public static boolean onEntityCollidedWithBlockHook() { + final EventCollideSoulSand event = new EventCollideSoulSand(); + Seppuku.INSTANCE.getEventManager().dispatchEvent(event); + + return event.isCanceled(); + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/patch/BlockStairsPatch.java b/src/main/java/me/rigamortis/seppuku/impl/patch/BlockStairsPatch.java new file mode 100644 index 0000000..f8efeba --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/patch/BlockStairsPatch.java @@ -0,0 +1,59 @@ +package me.rigamortis.seppuku.impl.patch; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.event.world.EventAddCollisionBox; +import me.rigamortis.seppuku.api.patch.ClassPatch; +import me.rigamortis.seppuku.api.patch.MethodPatch; +import me.rigamortis.seppuku.impl.management.PatchManager; +import net.minecraft.entity.Entity; +import net.minecraft.util.math.BlockPos; +import org.objectweb.asm.Type; +import org.objectweb.asm.tree.*; + +import static org.objectweb.asm.Opcodes.*; + +/** + * Author Seth + * 5/20/2019 @ 3:16 PM. + */ +public final class BlockStairsPatch extends ClassPatch { + + public BlockStairsPatch() { + super("net.minecraft.block.BlockStairs", "aud"); + } + + @MethodPatch( + mcpName = "addCollisionBoxToList", + notchName = "a", + mcpDesc = "(Lnet/minecraft/block/state/IBlockState;Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/math/AxisAlignedBB;Ljava/util/List;Lnet/minecraft/entity/Entity;Z)V", + notchDesc = "(Lawt;Lamu;Let;Lbhb;Ljava/util/List;Lvg;Z)V") + public void addCollisionBoxToList(MethodNode methodNode, PatchManager.Environment env) { + //create a list of instructions + final InsnList insnList = new InsnList(); + //add ALOAD to pass the BlockPos in + insnList.add(new VarInsnNode(ALOAD, 3)); + //add ALOAD to pass the entity in + insnList.add(new VarInsnNode(ALOAD, 6)); + //call our hook function + insnList.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "addCollisionBoxToListHook", env == PatchManager.Environment.IDE ? "(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/entity/Entity;)Z" : "(Let;Lvg;)Z", false)); + //create a label to jump to + final LabelNode jmp = new LabelNode(); + //add "if equals" and pass our label in + insnList.add(new JumpInsnNode(IFEQ, jmp)); + //add return so the rest of the function doesn't get called + insnList.add(new InsnNode(RETURN)); + //add our label + insnList.add(jmp); + //insert our instructions + methodNode.instructions.insert(insnList); + } + + public static boolean addCollisionBoxToListHook(BlockPos pos, Entity entity) { + //dispatch our event and pass the block and entity in + final EventAddCollisionBox event = new EventAddCollisionBox(pos, entity); + Seppuku.INSTANCE.getEventManager().dispatchEvent(event); + + return event.isCanceled(); + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/patch/EntityLlamaPatch.java b/src/main/java/me/rigamortis/seppuku/impl/patch/EntityLlamaPatch.java new file mode 100644 index 0000000..4bfd804 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/patch/EntityLlamaPatch.java @@ -0,0 +1,63 @@ +package me.rigamortis.seppuku.impl.patch; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.event.entity.EventSteerEntity; +import me.rigamortis.seppuku.api.patch.ClassPatch; +import me.rigamortis.seppuku.api.patch.MethodPatch; +import me.rigamortis.seppuku.impl.management.PatchManager; +import org.objectweb.asm.Type; +import org.objectweb.asm.tree.*; + +import static org.objectweb.asm.Opcodes.*; + +/** + * Author Seth + * 4/9/2019 @ 11:38 AM. + */ +public final class EntityLlamaPatch extends ClassPatch { + + public EntityLlamaPatch() { + super("net.minecraft.entity.passive.EntityLlama", "aas"); + } + + /** + * This is where minecraft checks if you can steer llamas + * @param methodNode + * @param env + */ + @MethodPatch( + mcpName = "canBeSteered", + notchName = "cV", + mcpDesc = "()Z") + public void canBeSteered(MethodNode methodNode, PatchManager.Environment env) { + //create a list of instructions and add the needed instructions to call our hook function + final InsnList insnList = new InsnList(); + //call our hook function + insnList.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "canBeSteeredHook", "()Z", false)); + //add a label to jump to + final LabelNode jmp = new LabelNode(); + //add if equals and pass the label + insnList.add(new JumpInsnNode(IFEQ, jmp)); + //add 1 or true + insnList.add(new InsnNode(ICONST_1)); + //add return so the rest of the function doesn't get called + insnList.add(new InsnNode(IRETURN)); + //add our label + insnList.add(jmp); + //insert the list of instructions at the top of the function + methodNode.instructions.insert(insnList); + } + + /** + * Our canBeSteered hook + * Used to allow us to steer and control llamas + * @return + */ + public static boolean canBeSteeredHook() { + //dispatch our event + final EventSteerEntity event = new EventSteerEntity(); + Seppuku.INSTANCE.getEventManager().dispatchEvent(event); + + return event.isCanceled(); + } +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/patch/EntityPatch.java b/src/main/java/me/rigamortis/seppuku/impl/patch/EntityPatch.java new file mode 100644 index 0000000..90af3af --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/patch/EntityPatch.java @@ -0,0 +1,31 @@ +package me.rigamortis.seppuku.impl.patch; + +import me.rigamortis.seppuku.api.patch.ClassPatch; + +/** + * Author Seth + * 5/24/2019 @ 3:42 AM. + */ +public final class EntityPatch extends ClassPatch { + + public EntityPatch() { + super("net.minecraft.entity.Entity", "vg"); + } +// +// @MethodPatch( +// mcpName = "move", +// notchName = "a", +// mcpDesc = "(Lnet/minecraft/entity/MoverType;DDD)V", +// notchDesc = "(Lvv;DDD)V") +// public void move(MethodNode methodNode, PatchManager.Environment env) { +// final AbstractInsnNode insnNode = ASMUtil.findPatternInsn(methodNode, new int[] {Opcodes.ALOAD, Opcodes.GETFIELD, Opcodes.ICONST_0, Opcodes.FCMPL, Opcodes.IFLE}); +// if(insnNode != null) { +// methodNode.instructions.insertBefore(insnNode, new MethodInsnNode(Opcodes.INVOKESTATIC, Type.getInternalName(this.getClass()), "moveHook", "()V", false)); +// } +// } +// +// public static void moveHook() { +// Seppuku.INSTANCE.getEventManager().dispatchEvent(new EventStep()); +// } + +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/patch/EntityPigPatch.java b/src/main/java/me/rigamortis/seppuku/impl/patch/EntityPigPatch.java new file mode 100644 index 0000000..f9d7ab2 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/patch/EntityPigPatch.java @@ -0,0 +1,103 @@ +package me.rigamortis.seppuku.impl.patch; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.event.entity.EventPigTravel; +import me.rigamortis.seppuku.api.event.entity.EventSteerEntity; +import me.rigamortis.seppuku.api.patch.ClassPatch; +import me.rigamortis.seppuku.api.patch.MethodPatch; +import me.rigamortis.seppuku.api.util.ASMUtil; +import me.rigamortis.seppuku.impl.management.PatchManager; +import net.minecraft.client.Minecraft; +import net.minecraft.entity.Entity; +import net.minecraft.entity.passive.EntityPig; +import org.objectweb.asm.Type; +import org.objectweb.asm.tree.*; + +import static org.objectweb.asm.Opcodes.*; + +/** + * Author Seth + * 4/9/2019 @ 11:15 AM. + */ +public final class EntityPigPatch extends ClassPatch { + + public EntityPigPatch() { + super("net.minecraft.entity.passive.EntityPig", "aad"); + } + + /** + * This is where minecraft checks if you can steer pigs + * + * @param methodNode + * @param env + */ + @MethodPatch( + mcpName = "canBeSteered", + notchName = "cV", + mcpDesc = "()Z") + public void canBeSteered(MethodNode methodNode, PatchManager.Environment env) { + //create a list of instructions and add the needed instructions to call our hook function + final InsnList insnList = new InsnList(); + //call our hook function + insnList.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "canBeSteeredHook", "()Z", false)); + //add a label to jump to + final LabelNode jmp = new LabelNode(); + //add if equals and pass the label + insnList.add(new JumpInsnNode(IFEQ, jmp)); + //add 1 or true + insnList.add(new InsnNode(ICONST_1)); + //add return so the rest of the function doesn't get called + insnList.add(new InsnNode(IRETURN)); + //add our label + insnList.add(jmp); + //insert the list of instructions at the top of the function + methodNode.instructions.insert(insnList); + } + + @MethodPatch( + mcpName = "travel", + notchName = "a", + mcpDesc = "(FFF)V") + public void travel(MethodNode methodNode, PatchManager.Environment env) { + final AbstractInsnNode target = ASMUtil.findMethodInsn(methodNode, INVOKEVIRTUAL, env == PatchManager.Environment.IDE ? "net/minecraft/entity/passive/EntityPig" : "aad", env == PatchManager.Environment.IDE ? "setAIMoveSpeed" : "k", "(F)V"); + if (target != null) { + //create a list of instructions and add the needed instructions to call our hook function + final InsnList insnList = new InsnList(); + //call our hook function + insnList.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "travelHook", "()Z", false)); + //add a label to jump to + final LabelNode jmp = new LabelNode(); + //add if equals and pass the label + insnList.add(new JumpInsnNode(IFEQ, jmp)); + //add return so the rest of the function doesn't get called + insnList.add(new InsnNode(RETURN)); + //add our label + insnList.add(jmp); + //insert the list of instructions at the top of the function + methodNode.instructions.insert(target, insnList); + } + } + + public static boolean travelHook() { + final EventPigTravel event = new EventPigTravel(); + Seppuku.INSTANCE.getEventManager().dispatchEvent(event); + + return event.isCanceled(); + } + + /** + * Our canBeSteered hook + * Used to allow us to steer and control pigs + * without a "carrot on a stick" + * + * @return + */ + public static boolean canBeSteeredHook() { + //dispatch our event + final EventSteerEntity event = new EventSteerEntity(); + Seppuku.INSTANCE.getEventManager().dispatchEvent(event); + + return event.isCanceled(); + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/patch/EntityPlayerPatch.java b/src/main/java/me/rigamortis/seppuku/impl/patch/EntityPlayerPatch.java new file mode 100644 index 0000000..578a946 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/patch/EntityPlayerPatch.java @@ -0,0 +1,110 @@ +package me.rigamortis.seppuku.impl.patch; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.event.player.EventApplyCollision; +import me.rigamortis.seppuku.api.event.player.EventPushedByWater; +import me.rigamortis.seppuku.api.patch.ClassPatch; +import me.rigamortis.seppuku.api.patch.MethodPatch; +import me.rigamortis.seppuku.impl.management.PatchManager; +import net.minecraft.client.Minecraft; +import net.minecraft.util.math.AxisAlignedBB; +import org.objectweb.asm.Type; +import org.objectweb.asm.tree.*; + +import static org.objectweb.asm.Opcodes.*; + +/** + * Author Seth + * 4/8/2019 @ 6:47 PM. + */ +public final class EntityPlayerPatch extends ClassPatch { + + public EntityPlayerPatch() { + super("net.minecraft.entity.player.EntityPlayer", "aed"); + } + + /** + * This is where minecraft handles + * water pushing + * Normally in creative mode you dont + * get pushed by water + * @param methodNode + * @param env + */ + @MethodPatch( + mcpName = "isPushedByWater", + notchName = "bo", + mcpDesc = "()Z") + public void isPushedByWater(MethodNode methodNode, PatchManager.Environment env) { + //create a list of instructions + final InsnList insnList = new InsnList(); + //call our hook function + insnList.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "isPushedByWaterHook", "()Z", false)); + //create a label to jump to + final LabelNode jmp = new LabelNode(); + //add "if equals" + insnList.add(new JumpInsnNode(IFEQ, jmp)); + //add 0 or false + insnList.add(new InsnNode(ICONST_0)); + //return so the rest of the function doesnt get called + insnList.add(new InsnNode(IRETURN)); + //add our label + insnList.add(jmp); + //insert the list of instructs at the top of the function + methodNode.instructions.insert(insnList); + } + + /** + * Our isPushedByWater hook + * @return + */ + public static boolean isPushedByWaterHook() { + //dispatch our event + final EventPushedByWater event = new EventPushedByWater(); + Seppuku.INSTANCE.getEventManager().dispatchEvent(event); + + return event.isCanceled(); + } + + /** + * This is where minecraft handles entities + * colliding with each other + * @param methodNode + * @param env + */ + @MethodPatch( + mcpName = "applyEntityCollision", + notchName = "i", + mcpDesc = "(Lnet/minecraft/entity/Entity;)V", + notchDesc = "(Lvg;)V") + public void applyEntityCollision(MethodNode methodNode, PatchManager.Environment env) { + //create a list of instructions + final InsnList insnList = new InsnList(); + //call our hook function + insnList.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "applyEntityCollisionHook", "()Z", false)); + //create a label to jump to + final LabelNode jmp = new LabelNode(); + //add "if equals" + insnList.add(new JumpInsnNode(IFEQ, jmp)); + //return so the rest of the function doesnt get called + insnList.add(new InsnNode(RETURN)); + //add our label + insnList.add(jmp); + //insert the list of instructs at the top of the function + methodNode.instructions.insert(insnList); + } + + /** + * Our applyEntityCollision hook + * Used to cancel entity collision + * @return + */ + public static boolean applyEntityCollisionHook() { + //dispatch our event + final EventApplyCollision event = new EventApplyCollision(); + Seppuku.INSTANCE.getEventManager().dispatchEvent(event); + + return event.isCanceled(); + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/patch/EntityPlayerSPPatch.java b/src/main/java/me/rigamortis/seppuku/impl/patch/EntityPlayerSPPatch.java new file mode 100644 index 0000000..f1d27bb --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/patch/EntityPlayerSPPatch.java @@ -0,0 +1,382 @@ +package me.rigamortis.seppuku.impl.patch; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.event.EventStageable; +import me.rigamortis.seppuku.api.event.player.*; +import me.rigamortis.seppuku.api.patch.ClassPatch; +import me.rigamortis.seppuku.api.patch.MethodPatch; +import me.rigamortis.seppuku.api.util.ASMUtil; +import me.rigamortis.seppuku.impl.management.PatchManager; +import net.minecraft.util.EnumHand; +import net.minecraftforge.client.ForgeHooksClient; +import org.objectweb.asm.Type; +import org.objectweb.asm.tree.*; +import team.stiff.pomelo.EventManager; + +import static org.objectweb.asm.Opcodes.*; +import static org.objectweb.asm.Opcodes.INVOKESTATIC; + +/** + * Author Seth + * 4/8/2019 @ 2:48 AM. + */ +public final class EntityPlayerSPPatch extends ClassPatch { + + public EntityPlayerSPPatch() { + super("net.minecraft.client.entity.EntityPlayerSP", "bud"); + } + + /** + * This is where minecraft handles player updates and movement + * + * @param methodNode + * @param env + */ + @MethodPatch( + mcpName = "onUpdate", + notchName = "B_", + mcpDesc = "()V") + public void onUpdate(MethodNode methodNode, PatchManager.Environment env) { + //create a list of instructions + final InsnList preInsn = new InsnList(); + //EventStageable.EventStage.PRE + preInsn.add(new FieldInsnNode(GETSTATIC, "me/rigamortis/seppuku/api/event/EventStageable$EventStage", "PRE", "Lme/rigamortis/seppuku/api/event/EventStageable$EventStage;")); + //call our hook function + preInsn.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "onUpdateHook", "(Lme/rigamortis/seppuku/api/event/EventStageable$EventStage;)Z", false)); + //create a label to jump to + final LabelNode jmp = new LabelNode(); + //add "if equals" + preInsn.add(new JumpInsnNode(IFEQ, jmp)); + //return so the rest of the function doesnt get called + preInsn.add(new InsnNode(RETURN)); + //add our label + preInsn.add(jmp); + //insert the list of instructs at the top of the function + methodNode.instructions.insert(preInsn); + + //same as above + final InsnList postInsn = new InsnList(); + //EventStageable.EventStage.POST + postInsn.add(new FieldInsnNode(GETSTATIC, "me/rigamortis/seppuku/api/event/EventStageable$EventStage", "POST", "Lme/rigamortis/seppuku/api/event/EventStageable$EventStage;")); + //call our hook function + postInsn.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "onUpdateHook", "(Lme/rigamortis/seppuku/api/event/EventStageable$EventStage;)Z", false)); + //insert the list of instructions at the bottom of the function + methodNode.instructions.insertBefore(ASMUtil.bottom(methodNode), postInsn); + } + + /** + * Our onUpdate hook + * This is where minecraft runs movement related code and + * sends movement packets + * + * @param stage + * @return + */ + public static boolean onUpdateHook(EventStageable.EventStage stage) { + //dispatch our event and pass the stage in + final EventPlayerUpdate event = new EventPlayerUpdate(stage); + Seppuku.INSTANCE.getEventManager().dispatchEvent(event); + + return event.isCanceled(); + } + + /** + * This is where minecraft handles player updates and movement + * while not in a vehicle + * + * @param methodNode + * @param env + */ + @MethodPatch( + mcpName = "onUpdateWalkingPlayer", + notchName = "N", + mcpDesc = "()V") + public void onUpdateWalkingPlayer(MethodNode methodNode, PatchManager.Environment env) { + //create a list of instructions + final InsnList preInsn = new InsnList(); + //EventStageable.EventStage.PRE + preInsn.add(new FieldInsnNode(GETSTATIC, "me/rigamortis/seppuku/api/event/EventStageable$EventStage", "PRE", "Lme/rigamortis/seppuku/api/event/EventStageable$EventStage;")); + //call our hook function + preInsn.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "onUpdateWalkingPlayerHook", "(Lme/rigamortis/seppuku/api/event/EventStageable$EventStage;)Z", false)); + //create a label to jump to + final LabelNode jmp = new LabelNode(); + //add "if equals" + preInsn.add(new JumpInsnNode(IFEQ, jmp)); + //return so the rest of the function doesnt get called + preInsn.add(new InsnNode(RETURN)); + //add our label + preInsn.add(jmp); + //insert the list of instructs at the top of the function + methodNode.instructions.insert(preInsn); + + //same as above + final InsnList postInsn = new InsnList(); + //EventStageable.EventStage.POST + postInsn.add(new FieldInsnNode(GETSTATIC, "me/rigamortis/seppuku/api/event/EventStageable$EventStage", "POST", "Lme/rigamortis/seppuku/api/event/EventStageable$EventStage;")); + //call our hook function + postInsn.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "onUpdateWalkingPlayerHook", "(Lme/rigamortis/seppuku/api/event/EventStageable$EventStage;)Z", false)); + //insert the list of instructions at the bottom of the function + methodNode.instructions.insertBefore(ASMUtil.bottom(methodNode), postInsn); + } + + /** + * Our onUpdate hook + * This is where minecraft runs non vehicle movement related code and + * sends movement packets + * + * @param stage + * @return + */ + public static boolean onUpdateWalkingPlayerHook(EventStageable.EventStage stage) { + if (stage == EventStageable.EventStage.PRE) { + Seppuku.INSTANCE.getRotationManager().updateRotations(); + Seppuku.INSTANCE.getPositionManager().updatePosition(); + } + + //dispatch our event and pass the stage in + final EventUpdateWalkingPlayer event = new EventUpdateWalkingPlayer(stage); + Seppuku.INSTANCE.getEventManager().dispatchEvent(event); + + if (stage == EventStageable.EventStage.POST) { + Seppuku.INSTANCE.getRotationManager().restoreRotations(); + Seppuku.INSTANCE.getPositionManager().restorePosition(); + } + + return event.isCanceled(); + } + + /** + * This is where minecraft handles sending chat messages + * + * @param methodNode + * @param env + */ + @MethodPatch( + mcpName = "sendChatMessage", + notchName = "g", + mcpDesc = "(Ljava/lang/String;)V") + public void sendChatMessage(MethodNode methodNode, PatchManager.Environment env) { + //create a list of instructions + final InsnList insnList = new InsnList(); + //add ALOAD to pass the message into our hook function + insnList.add(new VarInsnNode(ALOAD, 1)); + //call our hook function + insnList.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "sendChatMessageHook", "(Ljava/lang/String;)Z", false)); + //create a label to jump to + final LabelNode jmp = new LabelNode(); + //add "if equals" + insnList.add(new JumpInsnNode(IFEQ, jmp)); + //return so the rest of the function doesnt get called + insnList.add(new InsnNode(RETURN)); + //add our label + insnList.add(jmp); + //insert the list of instructs at the top of the function + methodNode.instructions.insert(insnList); + } + + /** + * Our sendChatMessage hook + * It allows us to intercept outgoing chat messages + * + * @param message + * @return + */ + public static boolean sendChatMessageHook(String message) { + //dispatch our event and pass the message in + final EventSendChatMessage event = new EventSendChatMessage(message); + Seppuku.INSTANCE.getEventManager().dispatchEvent(event); + + return event.isCanceled(); + } + + @MethodPatch( + mcpName = "swingArm", + notchName = "a", + mcpDesc = "(Lnet/minecraft/util/EnumHand;)V", + notchDesc = "(Lub;)V") + public void swingArm(MethodNode methodNode, PatchManager.Environment env) { + //create a list of instructions + final InsnList insnList = new InsnList(); + //add ALOAD to pass the EnumHand into our hook function + insnList.add(new VarInsnNode(ALOAD, 1)); + //call our hook function + insnList.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "swingArmHook", env == PatchManager.Environment.IDE ? "(Lnet/minecraft/util/EnumHand;)Z" : "(Lub;)Z", false)); + //create a label to jump to + final LabelNode jmp = new LabelNode(); + //add "if equals" + insnList.add(new JumpInsnNode(IFEQ, jmp)); + //return so the rest of the function doesnt get called + insnList.add(new InsnNode(RETURN)); + //add our label + insnList.add(jmp); + //insert the list of instructs at the top of the function + methodNode.instructions.insert(insnList); + } + + /** + * This is our swingArm hook + * We can cancel to stop our swing animation + * It's useful for older servers that dont support + * swinging the OFF_HAND + * + * @param hand + * @return + */ + public static boolean swingArmHook(EnumHand hand) { + //dispatch our event and pass the EnumHand in + final EventSwingArm event = new EventSwingArm(hand); + Seppuku.INSTANCE.getEventManager().dispatchEvent(event); + + return event.isCanceled(); + } + + /** + * This happens when you exit an inventory + * + * @param methodNode + * @param env + */ + @MethodPatch( + mcpName = "closeScreen", + notchName = "p", + mcpDesc = "()V") + public void closeScreen(MethodNode methodNode, PatchManager.Environment env) { + //create a list of instructions + final InsnList insnList = new InsnList(); + //call our hook function + insnList.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "closeScreenHook", "()Z", false)); + //create a label to jump to + final LabelNode jmp = new LabelNode(); + //add "if equals" + insnList.add(new JumpInsnNode(IFEQ, jmp)); + //return so the rest of the function doesnt get called + insnList.add(new InsnNode(RETURN)); + //add our label + insnList.add(jmp); + //insert the list of instructs at the top of the function + methodNode.instructions.insert(insnList); + } + + /** + * Our closeScreen hook + * Useful for some mods i.e MoreInv + * + * @return + */ + public static boolean closeScreenHook() { + //dispatch our event + final EventCloseScreen event = new EventCloseScreen(); + Seppuku.INSTANCE.getEventManager().dispatchEvent(event); + + return event.isCanceled(); + } + + @MethodPatch( + mcpName = "pushOutOfBlocks", + notchName = "i", + mcpDesc = "(DDD)Z") + public void pushOutOfBlocks(MethodNode methodNode, PatchManager.Environment env) { + //create a list of instructions + final InsnList insnList = new InsnList(); + //call our hook function + insnList.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "pushOutOfBlocksHook", "()Z", false)); + //create a label to jump to + final LabelNode jmp = new LabelNode(); + //add "if equals" + insnList.add(new JumpInsnNode(IFEQ, jmp)); + //add 0 or false + insnList.add(new InsnNode(ICONST_0)); + //return so the rest of the function doesnt get called + insnList.add(new InsnNode(IRETURN)); + //add our label + insnList.add(jmp); + //insert the list of instructs at the top of the function + methodNode.instructions.insert(insnList); + } + + /** + * Our pushOutOfBlocks hook used to disable being pushed out of blocks + * + * @return + */ + public static boolean pushOutOfBlocksHook() { + //dispatch our event + final EventPushOutOfBlocks event = new EventPushOutOfBlocks(); + Seppuku.INSTANCE.getEventManager().dispatchEvent(event); + + return event.isCanceled(); + } + + /** + * This is where minecraft slows you down while your hand is active + * + * @param methodNode + * @param env + */ + @MethodPatch( + mcpName = "onLivingUpdate", + notchName = "n", + mcpDesc = "()V") + public void onLivingUpdate(MethodNode methodNode, PatchManager.Environment env) { + final AbstractInsnNode target = ASMUtil.findMethodInsn(methodNode, INVOKESTATIC, Type.getInternalName(ForgeHooksClient.class), "onInputUpdate", env == PatchManager.Environment.IDE ? "(Lnet/minecraft/entity/player/EntityPlayer;Lnet/minecraft/util/MovementInput;)V" : "(Laed;Lbub;)V"); + + if (target != null) { + methodNode.instructions.insert(target, new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "onLivingUpdateHook", "()V", false)); + } + } + + /** + * Our onLivingUpdate mid function hook + * Used to negate slowing down while hands are active + */ + public static void onLivingUpdateHook() { + //dispatch our event + final EventUpdateInput event = new EventUpdateInput(); + Seppuku.INSTANCE.getEventManager().dispatchEvent(event); + } + + @MethodPatch( + mcpName = "move", + notchName = "a", + mcpDesc = "(Lnet/minecraft/entity/MoverType;DDD)V", + notchDesc = "(Lvv;DDD)V") + public void move(MethodNode methodNode, PatchManager.Environment env) { + final InsnList insnList = new InsnList(); + insnList.add(new TypeInsnNode(NEW, Type.getInternalName(EventMove.class))); + insnList.add(new InsnNode(DUP)); + insnList.add(new VarInsnNode(ALOAD, 1)); + insnList.add(new VarInsnNode(DLOAD, 2)); + insnList.add(new VarInsnNode(DLOAD, 4)); + insnList.add(new VarInsnNode(DLOAD, 6)); + insnList.add(new MethodInsnNode(INVOKESPECIAL, Type.getInternalName(EventMove.class), "", env == PatchManager.Environment.IDE ? "(Lnet/minecraft/entity/MoverType;DDD)V" : "(Lvv;DDD)V", false)); + insnList.add(new VarInsnNode(ASTORE, 11)); + + insnList.add(new FieldInsnNode(GETSTATIC, Type.getInternalName(Seppuku.class), "INSTANCE", "Lme/rigamortis/seppuku/Seppuku;")); + insnList.add(new MethodInsnNode(INVOKEVIRTUAL, Type.getInternalName(Seppuku.class), "getEventManager", "()Lteam/stiff/pomelo/EventManager;", false)); + insnList.add(new VarInsnNode(ALOAD, 11)); + insnList.add(new MethodInsnNode(INVOKEINTERFACE, Type.getInternalName(EventManager.class), "dispatchEvent", "(Ljava/lang/Object;)Ljava/lang/Object;", true)); + insnList.add(new InsnNode(POP)); + + insnList.add(new VarInsnNode(ALOAD, 11)); + insnList.add(new MethodInsnNode(INVOKEVIRTUAL, Type.getInternalName(EventMove.class), "getX", "()D", false)); + insnList.add(new VarInsnNode(DSTORE, 2)); + + insnList.add(new VarInsnNode(ALOAD, 11)); + insnList.add(new MethodInsnNode(INVOKEVIRTUAL, Type.getInternalName(EventMove.class), "getY", "()D", false)); + insnList.add(new VarInsnNode(DSTORE, 4)); + + insnList.add(new VarInsnNode(ALOAD, 11)); + insnList.add(new MethodInsnNode(INVOKEVIRTUAL, Type.getInternalName(EventMove.class), "getZ", "()D", false)); + insnList.add(new VarInsnNode(DSTORE, 6)); + + insnList.add(new VarInsnNode(ALOAD, 11)); + insnList.add(new MethodInsnNode(INVOKEVIRTUAL, Type.getInternalName(EventMove.class), "isCanceled", "()Z", false)); + final LabelNode jmp = new LabelNode(); + insnList.add(new JumpInsnNode(IFEQ, jmp)); + insnList.add(new InsnNode(RETURN)); + insnList.add(jmp); + methodNode.instructions.insert(insnList); + } + +} + diff --git a/src/main/java/me/rigamortis/seppuku/impl/patch/EntityRendererPatch.java b/src/main/java/me/rigamortis/seppuku/impl/patch/EntityRendererPatch.java new file mode 100644 index 0000000..fca26bd --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/patch/EntityRendererPatch.java @@ -0,0 +1,174 @@ +package me.rigamortis.seppuku.impl.patch; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.event.render.EventHurtCamEffect; +import me.rigamortis.seppuku.api.event.render.EventOrientCamera; +import me.rigamortis.seppuku.api.event.render.EventRender2D; +import me.rigamortis.seppuku.api.event.render.EventRender3D; +import me.rigamortis.seppuku.api.patch.ClassPatch; +import me.rigamortis.seppuku.api.patch.MethodPatch; +import me.rigamortis.seppuku.api.util.ASMUtil; +import me.rigamortis.seppuku.impl.management.PatchManager; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.ScaledResolution; +import org.objectweb.asm.Type; +import org.objectweb.asm.tree.*; + +import static org.objectweb.asm.Opcodes.*; + +/** + * Author Seth + * 4/6/2019 @ 12:46 PM. + */ +public final class EntityRendererPatch extends ClassPatch { + + public EntityRendererPatch() { + super("net.minecraft.client.renderer.EntityRenderer", "buq"); + } + + /** + * This is where we place our 2d rendering context + * + * @param methodNode + * @param env + */ + @MethodPatch( + mcpName = "updateCameraAndRender", + notchName = "a", + mcpDesc = "(FJ)V") + public void updateCameraAndRender(MethodNode methodNode, PatchManager.Environment env) { + //find the instruction that calls renderGameOverlay + final AbstractInsnNode target = ASMUtil.findMethodInsn(methodNode, INVOKEVIRTUAL, env == PatchManager.Environment.IDE ? "net/minecraft/client/gui/GuiIngame" : "biq", env == PatchManager.Environment.IDE ? "renderGameOverlay" : "a", "(F)V"); + + if (target != null) { + //create a list of instructions + final InsnList insnList = new InsnList(); + //add FLOAD to pass partialTicks param into our hook function + insnList.add(new VarInsnNode(FLOAD, 1)); + //call our hook function + insnList.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "updateCameraAndRenderHook", "(F)V", false)); + //insert our instructions after the renderGameOverlay call + methodNode.instructions.insert(target, insnList); + } + } + + /** + * This is our 2d render context + * Anything rendered here will be in screen space + * It should be called after forge and have top priority + * + * @param partialTicks + */ + public static void updateCameraAndRenderHook(float partialTicks) { + //dispatch our event so we can render stuff on our screen + Seppuku.INSTANCE.getEventManager().dispatchEvent(new EventRender2D(partialTicks, new ScaledResolution(Minecraft.getMinecraft()))); + } + + /** + * This is where we place our 3d rendering context + * + * @param methodNode + * @param env + */ + @MethodPatch( + mcpName = "renderWorldPass", + notchName = "a", + mcpDesc = "(IFJ)V") + public void renderWorldPass(MethodNode methodNode, PatchManager.Environment env) { + //find the LDC instruction with the value "hand" + //there is only 1 in this function and its passed into the call + //mc.mcProfiler.endStartSection("hand"); + final AbstractInsnNode target = ASMUtil.findInsnLdc(methodNode, "hand"); + + if (target != null) { + //make a list of instructions + final InsnList list = new InsnList(); + //add FLOAD to pass the partialTicks param into our hook function + list.add(new VarInsnNode(FLOAD, 2)); + //call our hook function + list.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "renderWorldPassHook", "(F)V", false)); + //insert the list of instructions 1 instruction after the LDC + methodNode.instructions.insert(target.getNext(), list); + } + } + + /** + * This is our 3d render context + * Anything rendered here will be rendered in world space + * before your hand + * + * @param partialTicks + */ + public static void renderWorldPassHook(float partialTicks) { + //dispatch our event and pass partial ticks in + Seppuku.INSTANCE.getEventManager().dispatchEvent(new EventRender3D(partialTicks)); + } + + /** + * This is where minecraft rotates and shakes your screen + * while taking damage + * + * @param methodNode + * @param env + */ + @MethodPatch( + mcpName = "hurtCameraEffect", + notchName = "d", + mcpDesc = "(F)V") + public void hurtCameraEffect(MethodNode methodNode, PatchManager.Environment env) { + //create a list of instructions and add the needed instructions to call our hook function + final InsnList insnList = new InsnList(); + //call our hook function + insnList.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "hurtCameraEffectHook", "()Z", false)); + //add a label to jump to + final LabelNode jmp = new LabelNode(); + //add if equals and pass the label + insnList.add(new JumpInsnNode(IFEQ, jmp)); + //add return so the rest of the function doesn't get called + insnList.add(new InsnNode(RETURN)); + //add our label + insnList.add(jmp); + //insert the list of instructions at the top of the function + methodNode.instructions.insert(insnList); + } + + /** + * Our hurtCameraEffect hook + * Used to disable the screen shaking effect while taking damage + * + * @return + */ + public static boolean hurtCameraEffectHook() { + //dispatch our event + final EventHurtCamEffect event = new EventHurtCamEffect(); + Seppuku.INSTANCE.getEventManager().dispatchEvent(event); + + return event.isCanceled(); + } + + @MethodPatch( + mcpName = "orientCamera", + notchName = "f", + mcpDesc = "(F)V") + public void orientCamera(MethodNode methodNode, PatchManager.Environment env) { + final AbstractInsnNode target = ASMUtil.findMethodInsn(methodNode, INVOKEVIRTUAL, env == PatchManager.Environment.IDE ? "net/minecraft/client/multiplayer/WorldClient" : "bsb", env == PatchManager.Environment.IDE ? "rayTraceBlocks" : "a", env == PatchManager.Environment.IDE ? "(Lnet/minecraft/util/math/Vec3d;Lnet/minecraft/util/math/Vec3d;)Lnet/minecraft/util/math/RayTraceResult;" : "(Lbhe;Lbhe;)Lbhc;"); + + if(target != null) { + final InsnList insnList = new InsnList(); + insnList.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "orientCameraHook", "()Z", false)); + final LabelNode jmp = new LabelNode(); + insnList.add(new JumpInsnNode(IFEQ, jmp)); + insnList.add(new InsnNode(ACONST_NULL)); + insnList.add(new VarInsnNode(ASTORE, 24)); + insnList.add(jmp); + methodNode.instructions.insert(target.getNext(), insnList); + } + } + + public static boolean orientCameraHook() { + final EventOrientCamera event = new EventOrientCamera(); + Seppuku.INSTANCE.getEventManager().dispatchEvent(event); + return event.isCanceled(); + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/patch/GuiBossOverlayPatch.java b/src/main/java/me/rigamortis/seppuku/impl/patch/GuiBossOverlayPatch.java new file mode 100644 index 0000000..4bfb3b3 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/patch/GuiBossOverlayPatch.java @@ -0,0 +1,48 @@ +package me.rigamortis.seppuku.impl.patch; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.event.render.EventRenderBossHealth; +import me.rigamortis.seppuku.api.patch.ClassPatch; +import me.rigamortis.seppuku.api.patch.MethodPatch; +import me.rigamortis.seppuku.impl.management.PatchManager; +import org.objectweb.asm.Type; +import org.objectweb.asm.tree.*; + +import static org.objectweb.asm.Opcodes.*; + +/** + * created by noil on 10/4/2019 at 2:40 PM + */ +public final class GuiBossOverlayPatch extends ClassPatch { + + public GuiBossOverlayPatch() { + super("net.minecraft.client.gui.GuiBossOverlay"); + } + + @MethodPatch( + mcpName = "renderBossHealth", + mcpDesc = "()V") + public void renderBossHealth(MethodNode methodNode, PatchManager.Environment env) { + //create a list of instructions + final InsnList insnList = new InsnList(); + //call our hook function + insnList.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "renderBossHealthHook", "()Z", false)); + //create a label to jump to + final LabelNode jmp = new LabelNode(); + //add "if equals" + insnList.add(new JumpInsnNode(IFEQ, jmp)); + //return so the rest of the function doesnt get called + insnList.add(new InsnNode(RETURN)); + //add our label + insnList.add(jmp); + //insert the list of instructs at the top of the function + methodNode.instructions.insert(insnList); + } + + public static boolean renderBossHealthHook() { + final EventRenderBossHealth event = new EventRenderBossHealth(); + Seppuku.INSTANCE.getEventManager().dispatchEvent(event); + + return event.isCanceled(); + } +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/patch/GuiIngameForgePatch.java b/src/main/java/me/rigamortis/seppuku/impl/patch/GuiIngameForgePatch.java new file mode 100644 index 0000000..d2e874e --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/patch/GuiIngameForgePatch.java @@ -0,0 +1,148 @@ +package me.rigamortis.seppuku.impl.patch; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.event.gui.EventRenderHelmet; +import me.rigamortis.seppuku.api.event.gui.EventRenderPortal; +import me.rigamortis.seppuku.api.event.gui.EventRenderPotions; +import me.rigamortis.seppuku.api.patch.ClassPatch; +import me.rigamortis.seppuku.api.patch.MethodPatch; +import me.rigamortis.seppuku.impl.management.PatchManager; +import org.objectweb.asm.Type; +import org.objectweb.asm.tree.*; + +import static org.objectweb.asm.Opcodes.*; + +/** + * Author Seth + * 4/8/2019 @ 8:04 PM. + */ +public final class GuiIngameForgePatch extends ClassPatch { + + public GuiIngameForgePatch() { + super("net.minecraftforge.client.GuiIngameForge"); + } + + /** + * This is where minecraft renders a + * portal overlay effect on your screen + * + * @param methodNode + * @param env + */ + @MethodPatch( + mcpName = "renderPortal", + mcpDesc = "(Lnet/minecraft/client/gui/ScaledResolution;F)V", + notchDesc = "(Lbit;F)V") + public void renderPortal(MethodNode methodNode, PatchManager.Environment env) { + //create a list of instructions + final InsnList insnList = new InsnList(); + //call our hook function + insnList.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "renderPortalHook", "()Z", false)); + //create a label to jump to + final LabelNode jmp = new LabelNode(); + //add "if equals" + insnList.add(new JumpInsnNode(IFEQ, jmp)); + //return so the rest of the function doesnt get called + insnList.add(new InsnNode(RETURN)); + //add our label + insnList.add(jmp); + //insert the list of instructs at the top of the function + methodNode.instructions.insert(insnList); + } + + /** + * Our renderPortal hook to remove the portal overlay + * + * @return + */ + public static boolean renderPortalHook() { + //dispatch our event + final EventRenderPortal event = new EventRenderPortal(); + Seppuku.INSTANCE.getEventManager().dispatchEvent(event); + + return event.isCanceled(); + } + + /** + * This is where minecraft renders potion icons + * on the top right of your screen + * + * @param methodNode + * @param env + */ + @MethodPatch( + mcpName = "renderPotionIcons", + mcpDesc = "(Lnet/minecraft/client/gui/ScaledResolution;)V", + notchDesc = "(Lbit;)V") + public void renderPotionIcons(MethodNode methodNode, PatchManager.Environment env) { + //create a list of instructions + final InsnList insnList = new InsnList(); + //call our hook function + insnList.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "renderPotionIconsHook", "()Z", false)); + //create a label to jump to + final LabelNode jmp = new LabelNode(); + //add "if equals" + insnList.add(new JumpInsnNode(IFEQ, jmp)); + //return so the rest of the function doesnt get called + insnList.add(new InsnNode(RETURN)); + //add our label + insnList.add(jmp); + //insert the list of instructs at the top of the function + methodNode.instructions.insert(insnList); + } + + /** + * Our renderPotionIcons hook used to remove potion + * status icons + * + * @return + */ + public static boolean renderPotionIconsHook() { + //dispatch our event + final EventRenderPotions event = new EventRenderPotions(); + Seppuku.INSTANCE.getEventManager().dispatchEvent(event); + + return event.isCanceled(); + } + + /** + * This is where minecraft renders overlay effects + * like pumpkins + * + * @param methodNode + * @param env + */ + @MethodPatch( + mcpName = "renderHelmet", + mcpDesc = "(Lnet/minecraft/client/gui/ScaledResolution;F)V", + notchDesc = "(Lbit;F)V") + public void renderHelmet(MethodNode methodNode, PatchManager.Environment env) { + //create a list of instructions + final InsnList insnList = new InsnList(); + //call our hook function + insnList.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "renderHelmetHook", "()Z", false)); + //create a label to jump to + final LabelNode jmp = new LabelNode(); + //add "if equals" + insnList.add(new JumpInsnNode(IFEQ, jmp)); + //return so the rest of the function doesnt get called + insnList.add(new InsnNode(RETURN)); + //add our label + insnList.add(jmp); + //insert the list of instructs at the top of the function + methodNode.instructions.insert(insnList); + } + + /** + * Our renderHelmet hook to remove overlay effects + * + * @return + */ + public static boolean renderHelmetHook() { + //dispatch our event + final EventRenderHelmet event = new EventRenderHelmet(); + Seppuku.INSTANCE.getEventManager().dispatchEvent(event); + + return event.isCanceled(); + } +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/patch/GuiScreenBookPatch.java b/src/main/java/me/rigamortis/seppuku/impl/patch/GuiScreenBookPatch.java new file mode 100644 index 0000000..2ae149d --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/patch/GuiScreenBookPatch.java @@ -0,0 +1,102 @@ +package me.rigamortis.seppuku.impl.patch; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.event.gui.EventBookPage; +import me.rigamortis.seppuku.api.event.gui.EventBookTitle; +import me.rigamortis.seppuku.api.patch.ClassPatch; +import me.rigamortis.seppuku.api.patch.MethodPatch; +import me.rigamortis.seppuku.impl.management.PatchManager; +import org.objectweb.asm.Type; +import org.objectweb.asm.tree.*; + +import static org.objectweb.asm.Opcodes.*; + +/** + * Author Seth + * 4/8/2019 @ 7:08 PM. + */ +public final class GuiScreenBookPatch extends ClassPatch { + + public GuiScreenBookPatch() { + super("net.minecraft.client.gui.GuiScreenBook", "bmj"); + } + + /** + * This is where minecraft appends your text + * to a page in books + * @param methodNode + * @param env + */ + @MethodPatch( + mcpName = "pageInsertIntoCurrent", + notchName = "b", + mcpDesc = "(Ljava/lang/String;)V") + public void pageInsertIntoCurrent(MethodNode methodNode, PatchManager.Environment env) { + //create a list of instructions + final InsnList insnList = new InsnList(); + //add ALOAD to pass the page param to our hook function + insnList.add(new VarInsnNode(ALOAD, 1)); + //call our hook function + insnList.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "pageInsertIntoCurrentHook", "(Ljava/lang/String;)Ljava/lang/String;", false)); + //save the value to the param + insnList.add(new VarInsnNode(ASTORE, 1)); + //insert our instructions + methodNode.instructions.insert(insnList); + } + + /** + * This is our pageInsertIntoCurrent hook + * We can use it to modify book pages + * @param page + * @return + */ + public static String pageInsertIntoCurrentHook(String page) { + //dispatch our event and pass in the page + final EventBookPage event = new EventBookPage(page); + Seppuku.INSTANCE.getEventManager().dispatchEvent(event); + + return event.getPage(); + } + + /** + * This is where minecraft handles + * typing in the title of a book + * @param methodNode + * @param env + */ + @MethodPatch( + mcpName = "keyTypedInTitle", + notchName = "c", + mcpDesc = "(CI)V") + public void keyTypedInTitle(MethodNode methodNode, PatchManager.Environment env) { + //create a list of instructions + final InsnList insnList = new InsnList(); + + //add ALOAD to access class fields + insnList.add(new VarInsnNode(ALOAD, 0)); + insnList.add(new VarInsnNode(ALOAD, 0)); + //get the "bookTitle" field + insnList.add(new FieldInsnNode(GETFIELD, env == PatchManager.Environment.IDE ? "net/minecraft/client/gui/GuiScreenBook" : "bmj", env == PatchManager.Environment.IDE ? "bookTitle" : "A", "Ljava/lang/String;")); + //call our hook function and pass the "bookTitle" field + insnList.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "keyTypedInTitleHook", "(Ljava/lang/String;)Ljava/lang/String;", false)); + //store the value to the "bookTitle" field + insnList.add(new FieldInsnNode(PUTFIELD, env == PatchManager.Environment.IDE ? "net/minecraft/client/gui/GuiScreenBook" : "bmj", env == PatchManager.Environment.IDE ? "bookTitle" : "A", "Ljava/lang/String;")); + //insert our list of instructions + methodNode.instructions.insert(insnList); + } + + /** + * This is our keyTypedInTitle + * We can use it to modify the title text of a book + * @param title + * @return + */ + public static String keyTypedInTitleHook(String title) { + //dispatch our event and pass in the title which can be null + final EventBookTitle event = new EventBookTitle(title); + Seppuku.INSTANCE.getEventManager().dispatchEvent(event); + + return event.getTitle(); + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/patch/ItemRendererPatch.java b/src/main/java/me/rigamortis/seppuku/impl/patch/ItemRendererPatch.java new file mode 100644 index 0000000..b103570 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/patch/ItemRendererPatch.java @@ -0,0 +1,107 @@ +package me.rigamortis.seppuku.impl.patch; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.event.render.EventRenderOverlay; +import me.rigamortis.seppuku.api.patch.ClassPatch; +import me.rigamortis.seppuku.api.patch.MethodPatch; +import me.rigamortis.seppuku.impl.management.PatchManager; +import org.objectweb.asm.Type; +import org.objectweb.asm.tree.*; + +import static org.objectweb.asm.Opcodes.*; + +/** + * Author Seth + * 4/9/2019 @ 12:25 AM. + */ +public final class ItemRendererPatch extends ClassPatch { + + public ItemRendererPatch() { + super("net.minecraft.client.renderer.ItemRenderer", "buu"); + } + + @MethodPatch( + mcpName = "renderBlockInHand", + notchName = "a", + mcpDesc = "(Lnet/minecraft/client/renderer/texture/TextureAtlasSprite;)V", + notchDesc = "(Lcdq;)V") + public void renderBlockInHand(MethodNode methodNode, PatchManager.Environment env) { + //create a list of instructions and add the needed instructions to call our hook function + final InsnList insnList = new InsnList(); + //call our hook function + insnList.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "renderBlockInHandHook", "()Z", false)); + //add a label to jump to + final LabelNode jmp = new LabelNode(); + //add if equals and pass the label + insnList.add(new JumpInsnNode(IFEQ, jmp)); + //add return so the rest of the function doesn't get called + insnList.add(new InsnNode(RETURN)); + //add our label + insnList.add(jmp); + //insert the list of instructions at the top of the function + methodNode.instructions.insert(insnList); + } + + public static boolean renderBlockInHandHook() { + final EventRenderOverlay event = new EventRenderOverlay(EventRenderOverlay.OverlayType.BLOCK); + Seppuku.INSTANCE.getEventManager().dispatchEvent(event); + + return event.isCanceled(); + } + + @MethodPatch( + mcpName = "renderWaterOverlayTexture", + notchName = "e", + mcpDesc = "(F)V") + public void renderWaterOverlayTexture(MethodNode methodNode, PatchManager.Environment env) { + //create a list of instructions and add the needed instructions to call our hook function + final InsnList insnList = new InsnList(); + //call our hook function + insnList.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "renderWaterOverlayTextureHook", "()Z", false)); + //add a label to jump to + final LabelNode jmp = new LabelNode(); + //add if equals and pass the label + insnList.add(new JumpInsnNode(IFEQ, jmp)); + //add return so the rest of the function doesn't get called + insnList.add(new InsnNode(RETURN)); + //add our label + insnList.add(jmp); + //insert the list of instructions at the top of the function + methodNode.instructions.insert(insnList); + } + + public static boolean renderWaterOverlayTextureHook() { + final EventRenderOverlay event = new EventRenderOverlay(EventRenderOverlay.OverlayType.LIQUID); + Seppuku.INSTANCE.getEventManager().dispatchEvent(event); + + return event.isCanceled(); + } + + @MethodPatch( + mcpName = "renderFireInFirstPerson", + notchName = "d", + mcpDesc = "()V") + public void renderFireInFirstPerson(MethodNode methodNode, PatchManager.Environment env) { + //create a list of instructions and add the needed instructions to call our hook function + final InsnList insnList = new InsnList(); + //call our hook function + insnList.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "renderFireInFirstPersonHook", "()Z", false)); + //add a label to jump to + final LabelNode jmp = new LabelNode(); + //add if equals and pass the label + insnList.add(new JumpInsnNode(IFEQ, jmp)); + //add return so the rest of the function doesn't get called + insnList.add(new InsnNode(RETURN)); + //add our label + insnList.add(jmp); + //insert the list of instructions at the top of the function + methodNode.instructions.insert(insnList); + } + + public static boolean renderFireInFirstPersonHook() { + final EventRenderOverlay event = new EventRenderOverlay(EventRenderOverlay.OverlayType.FIRE); + Seppuku.INSTANCE.getEventManager().dispatchEvent(event); + + return event.isCanceled(); + } +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/patch/KeyBindingPatch.java b/src/main/java/me/rigamortis/seppuku/impl/patch/KeyBindingPatch.java new file mode 100644 index 0000000..6f37347 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/patch/KeyBindingPatch.java @@ -0,0 +1,52 @@ +package me.rigamortis.seppuku.impl.patch; + +import me.rigamortis.seppuku.api.patch.ClassPatch; +import me.rigamortis.seppuku.api.patch.MethodPatch; +import me.rigamortis.seppuku.impl.management.PatchManager; +import org.objectweb.asm.tree.*; + +import static org.objectweb.asm.Opcodes.*; + +/** + * Author Seth + * 4/10/2019 @ 3:27 AM. + */ +public final class KeyBindingPatch extends ClassPatch { + + public KeyBindingPatch() { + super("net.minecraft.client.settings.KeyBinding", "bhy"); + } + + /** + * This is where minecraft checks if a key is down + * We need to patch it because forge adds a key conflicting + * problem and doesn't allow us to keep keys pressed while + * gui's are open + * @param methodNode + * @param env + */ + @MethodPatch( + mcpName = "isKeyDown", + notchName = "e", + mcpDesc = "()Z") + public void isKeyDown(MethodNode methodNode, PatchManager.Environment env) { + AbstractInsnNode target = null; + + for (AbstractInsnNode insn : methodNode.instructions.toArray()) { + if (insn.getOpcode() == ALOAD) { + target = insn; + break; + } + } + + if(target != null) { + AbstractInsnNode next = target.getNext().getNext(); //If + while(next.getOpcode() != IRETURN) { + next = next.getNext(); + methodNode.instructions.remove(next.getPrevious()); + } + } + } + +} + diff --git a/src/main/java/me/rigamortis/seppuku/impl/patch/MinecraftPatch.java b/src/main/java/me/rigamortis/seppuku/impl/patch/MinecraftPatch.java new file mode 100644 index 0000000..f3ac61e --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/patch/MinecraftPatch.java @@ -0,0 +1,172 @@ +package me.rigamortis.seppuku.impl.patch; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.event.EventStageable; +import me.rigamortis.seppuku.api.event.minecraft.EventDisplayGui; +import me.rigamortis.seppuku.api.event.minecraft.EventKeyPress; +import me.rigamortis.seppuku.api.event.minecraft.EventRunTick; +import me.rigamortis.seppuku.api.event.minecraft.EventUpdateFramebufferSize; +import me.rigamortis.seppuku.api.patch.ClassPatch; +import me.rigamortis.seppuku.api.patch.MethodPatch; +import me.rigamortis.seppuku.api.util.ASMUtil; +import me.rigamortis.seppuku.impl.management.PatchManager; +import net.minecraft.client.gui.GuiScreen; +import org.lwjgl.input.Keyboard; +import org.objectweb.asm.Type; +import org.objectweb.asm.tree.*; + +import static org.objectweb.asm.Opcodes.*; + +/** + * Author Seth + * 4/4/2019 @ 11:27 PM. + */ +public final class MinecraftPatch extends ClassPatch { + + public MinecraftPatch() { + super("net.minecraft.client.Minecraft", "bib"); + } + + /** + * Patch the method "updateFramebufferSize" + * Mainly used for shaders + * @param methodNode + */ + @MethodPatch( + mcpName = "updateFramebufferSize", + notchName = "aC", + mcpDesc = "()V") + public void updateFramebufferSize(MethodNode methodNode, PatchManager.Environment env) { + //inset a static method call to our method "updateFramebufferSizeHook" + methodNode.instructions.insert(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "updateFramebufferSizeHook", "()V", false)); + } + + /** + * This is called when we resize our game + */ + public static void updateFramebufferSizeHook() { + //dispatch our event "EventUpdateFramebufferSize" + Seppuku.INSTANCE.getEventManager().dispatchEvent(new EventUpdateFramebufferSize()); + } + + /** + * Patch the method "runTick" + * The bytecode we are inserting here replicates this call + * MinecraftPatch.runTickHook(EventStageable.EventStage.PRE); + * @param methodNode + * @param env + */ + @MethodPatch( + mcpName = "runTick", + notchName = "t", + mcpDesc = "()V") + public void runTick(MethodNode methodNode, PatchManager.Environment env) { + //create a list of instructions and add the needed instructions to call our hook function + final InsnList preInsn = new InsnList(); + //EventStageable.EventStage.PRE + preInsn.add(new FieldInsnNode(GETSTATIC, "me/rigamortis/seppuku/api/event/EventStageable$EventStage", "PRE", "Lme/rigamortis/seppuku/api/event/EventStageable$EventStage;")); + //MinecraftPatch.runTickHook(); + preInsn.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "runTickHook", "(Lme/rigamortis/seppuku/api/event/EventStageable$EventStage;)V", false)); + //insert the list of instructions at the top of the function + methodNode.instructions.insert(preInsn); + + //do the same thing as above but insert the list at the bottom of the method + final InsnList postInsn = new InsnList(); + //EventStageable.EventStage.POST + postInsn.add(new FieldInsnNode(GETSTATIC, "me/rigamortis/seppuku/api/event/EventStageable$EventStage", "POST", "Lme/rigamortis/seppuku/api/event/EventStageable$EventStage;")); + //MinecraftPatch.runTickHook(); + postInsn.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "runTickHook", "(Lme/rigamortis/seppuku/api/event/EventStageable$EventStage;)V", false)); + //insert the list of instructions at the bottom of the function + methodNode.instructions.insertBefore(ASMUtil.bottom(methodNode), postInsn); + } + + /** + * This is twice called every tick + */ + public static void runTickHook(EventStageable.EventStage stage) { + //dispatch our event "EventRunTick" and pass in the stage(pre, post) + Seppuku.INSTANCE.getEventManager().dispatchEvent(new EventRunTick(stage)); + } + + /** + * This is where key input is handled + * @param methodNode + * @param env + */ + @MethodPatch( + mcpName = "runTickKeyboard", + notchName = "aD", + mcpDesc = "()V") + public void runTickKeyboard(MethodNode methodNode, PatchManager.Environment env) { + //find the instruction that calls dispatchKeypresses + final AbstractInsnNode target = ASMUtil.findMethodInsn(methodNode, INVOKEVIRTUAL, env == PatchManager.Environment.IDE ? "net/minecraft/client/Minecraft" : "bib", env == PatchManager.Environment.IDE ? "dispatchKeypresses" : "W", "()V"); + + if(target != null) { + //make a list of instructions + final InsnList insnList = new InsnList(); + //we use ILOAD to pass the "keycode" into our call + insnList.add(new VarInsnNode(ILOAD, 1)); + //call our hook function + insnList.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "runTickKeyboardHook", "(I)V", false)); + //inset the instructions after the call "dispatchKeypresses" + methodNode.instructions.insert(target, insnList); + } + } + + /** + * This is a hacky way to intercept key presses + */ + public static void runTickKeyboardHook(int key) { + //check if the key was just pressed + if(Keyboard.getEventKeyState()) { + //dispatch our event for key presses and pass in the keycode + Seppuku.INSTANCE.getEventManager().dispatchEvent(new EventKeyPress(key)); + } + } + + /** + * This is used to tell if we just opened a gui screen + * It can be cancelled + * @param methodNode + * @param env + */ + @MethodPatch( + mcpName = "displayGuiScreen", + notchName = "a", + mcpDesc = "(Lnet/minecraft/client/gui/GuiScreen;)V", + notchDesc = "(Lblk;)V") + public void displayGuiScreen(MethodNode methodNode, PatchManager.Environment env) { + //make a list of our instructions + final InsnList insnList = new InsnList(); + //we use ALOAD to pass the first param to our call + insnList.add(new VarInsnNode(ALOAD, 1)); + //call our hook function + //note the desc is ()Z because our hook function is a boolean + insnList.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "displayGuiScreenHook", env == PatchManager.Environment.IDE ? "(Lnet/minecraft/client/gui/GuiScreen;)Z" : "(Lblk;)Z", false)); + //create a LabelNode to jump to + final LabelNode jmp = new LabelNode(); + //add an "if equals" and pass our label + insnList.add(new JumpInsnNode(IFEQ, jmp)); + //add a return + insnList.add(new InsnNode(RETURN)); + //finally add the label + insnList.add(jmp); + //insert our instructions at the top + methodNode.instructions.insert(insnList); + } + + /** + * Our display gui hook called when we open a gui + * @param screen can be null! + * @return + */ + public static boolean displayGuiScreenHook(GuiScreen screen) { + //dispatch our event and pass the gui + final EventDisplayGui event = new EventDisplayGui(screen); + Seppuku.INSTANCE.getEventManager().dispatchEvent(event); + + //return event.isCanceled() to allow us to cancel the original function + return event.isCanceled(); + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/patch/NetworkManagerPatch.java b/src/main/java/me/rigamortis/seppuku/impl/patch/NetworkManagerPatch.java new file mode 100644 index 0000000..8902184 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/patch/NetworkManagerPatch.java @@ -0,0 +1,147 @@ +package me.rigamortis.seppuku.impl.patch; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.event.EventStageable; +import me.rigamortis.seppuku.api.event.network.EventReceivePacket; +import me.rigamortis.seppuku.api.event.network.EventSendPacket; +import me.rigamortis.seppuku.api.patch.ClassPatch; +import me.rigamortis.seppuku.api.patch.MethodPatch; +import me.rigamortis.seppuku.api.util.ASMUtil; +import me.rigamortis.seppuku.impl.management.PatchManager; +import net.minecraft.network.Packet; +import org.objectweb.asm.Type; +import org.objectweb.asm.tree.*; + +import static org.objectweb.asm.Opcodes.*; + +/** + * Author Seth + * 4/6/2019 @ 1:46 PM. + */ +public final class NetworkManagerPatch extends ClassPatch { + + public NetworkManagerPatch() { + super("net.minecraft.network.NetworkManager", "gw"); + } + + /** + * This is where minecraft sends packets before they are compressed and encrypted + * @param methodNode + * @param env + */ + @MethodPatch( + mcpName = "sendPacket", + notchName = "a", + mcpDesc = "(Lnet/minecraft/network/Packet;)V", + notchDesc = "(Lht;)V") + public void sendPacket(MethodNode methodNode, PatchManager.Environment env) { + //create a list of instructions and add the needed instructions to call our hook function + final InsnList preInsn = new InsnList(); + //add ALOAD to pass the Packet into our hook function + preInsn.add(new VarInsnNode(ALOAD, 1)); + //EventStageable.EventStage.PRE + preInsn.add(new FieldInsnNode(GETSTATIC, "me/rigamortis/seppuku/api/event/EventStageable$EventStage", "PRE", "Lme/rigamortis/seppuku/api/event/EventStageable$EventStage;")); + //call our hook function + preInsn.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "sendPacketHook", env == PatchManager.Environment.IDE ? "(Lnet/minecraft/network/Packet;Lme/rigamortis/seppuku/api/event/EventStageable$EventStage;)Z" : "(Lht;Lme/rigamortis/seppuku/api/event/EventStageable$EventStage;)Z", false)); + //add a label to jump to + final LabelNode jmp = new LabelNode(); + //add if equals and pass the label + preInsn.add(new JumpInsnNode(IFEQ, jmp)); + //add return so the rest of the function doesn't get called + preInsn.add(new InsnNode(RETURN)); + //add our label + preInsn.add(jmp); + //insert the list of instructions at the top of the function + methodNode.instructions.insert(preInsn); + + //do the same thing as above but insert the list at the bottom of the method + //we dont need to cancel post + final InsnList postInsn = new InsnList(); + //add ALOAD to pass the Packet into our hook function + postInsn.add(new VarInsnNode(ALOAD, 1)); + //EventStageable.EventStage.POST + postInsn.add(new FieldInsnNode(GETSTATIC, "me/rigamortis/seppuku/api/event/EventStageable$EventStage", "POST", "Lme/rigamortis/seppuku/api/event/EventStageable$EventStage;")); + //call our hook function + postInsn.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "sendPacketHook", env == PatchManager.Environment.IDE ? "(Lnet/minecraft/network/Packet;Lme/rigamortis/seppuku/api/event/EventStageable$EventStage;)Z" : "(Lht;Lme/rigamortis/seppuku/api/event/EventStageable$EventStage;)Z", false)); + //insert the list of instructions at the bottom of the function + methodNode.instructions.insertBefore(ASMUtil.bottom(methodNode), postInsn); + } + + /** + * This is our sendPacket hook + * It allows us to intercept outgoing unencrypted packets and modify the data + * It also allows us to cancel sending certain packets + * @param packet + * @param stage + * @return + */ + public static boolean sendPacketHook(Packet packet, EventStageable.EventStage stage) { + final EventSendPacket event = new EventSendPacket(stage, packet); + Seppuku.INSTANCE.getEventManager().dispatchEvent(event); + + return event.isCanceled(); + } + + /** + * This is where minecraft handles received packets + * @param methodNode + * @param env + */ + @MethodPatch( + mcpName = "channelRead0", + notchName = "a", + mcpDesc = "(Lio/netty/channel/ChannelHandlerContext;Lnet/minecraft/network/Packet;)V", + notchDesc = "(Lio/netty/channel/ChannelHandlerContext;Lht;)V") + public void channelRead0(MethodNode methodNode, PatchManager.Environment env) { + //create a list of instructions and add the needed instructions to call our hook function + final InsnList preInsn = new InsnList(); + //add ALOAD to pass the Packet into our hook function + preInsn.add(new VarInsnNode(ALOAD, 2)); + //EventStageable.EventStage.PRE + preInsn.add(new FieldInsnNode(GETSTATIC, "me/rigamortis/seppuku/api/event/EventStageable$EventStage", "PRE", "Lme/rigamortis/seppuku/api/event/EventStageable$EventStage;")); + //call our hook function + preInsn.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "channelRead0Hook", env == PatchManager.Environment.IDE ? "(Lnet/minecraft/network/Packet;Lme/rigamortis/seppuku/api/event/EventStageable$EventStage;)Z" : "(Lht;Lme/rigamortis/seppuku/api/event/EventStageable$EventStage;)Z", false)); + //add a label to jump to + final LabelNode jmp = new LabelNode(); + //add if equals and pass the label + preInsn.add(new JumpInsnNode(IFEQ, jmp)); + //add return so the rest of the function doesn't get called + preInsn.add(new InsnNode(RETURN)); + //add our label + preInsn.add(jmp); + //insert the list of instructions at the top of the function + methodNode.instructions.insert(preInsn); + + //do the same thing as above but insert the list at the bottom of the method + //we dont need to cancel post + final InsnList postInsn = new InsnList(); + //add ALOAD to pass the Packet into our hook function + postInsn.add(new VarInsnNode(ALOAD, 2)); + //EventStageable.EventStage.POST + postInsn.add(new FieldInsnNode(GETSTATIC, "me/rigamortis/seppuku/api/event/EventStageable$EventStage", "POST", "Lme/rigamortis/seppuku/api/event/EventStageable$EventStage;")); + //call our hook function + postInsn.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "channelRead0Hook", env == PatchManager.Environment.IDE ? "(Lnet/minecraft/network/Packet;Lme/rigamortis/seppuku/api/event/EventStageable$EventStage;)Z" : "(Lht;Lme/rigamortis/seppuku/api/event/EventStageable$EventStage;)Z", false)); + //insert the list of instructions at the bottom of the function + methodNode.instructions.insertBefore(ASMUtil.bottom(methodNode), postInsn); + } + + /** + * This is our channelRead0 hook + * It allows us to cancel processing incoming packets or modify the unencrypted data + * @param packet + * @param stage + * @return + */ + public static boolean channelRead0Hook(Packet packet, EventStageable.EventStage stage) { + if(packet != null) { + final EventReceivePacket event = new EventReceivePacket(stage, packet); + Seppuku.INSTANCE.getEventManager().dispatchEvent(event); + + return event.isCanceled(); + } + + return false; + } + + +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/patch/PlayerControllerMPPatch.java b/src/main/java/me/rigamortis/seppuku/impl/patch/PlayerControllerMPPatch.java new file mode 100644 index 0000000..ecf9b6b --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/patch/PlayerControllerMPPatch.java @@ -0,0 +1,355 @@ +package me.rigamortis.seppuku.impl.patch; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.event.player.*; +import me.rigamortis.seppuku.api.patch.ClassPatch; +import me.rigamortis.seppuku.api.patch.MethodPatch; +import me.rigamortis.seppuku.impl.management.PatchManager; +import net.minecraft.client.Minecraft; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.network.play.client.CPacketChatMessage; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; +import org.objectweb.asm.Type; +import org.objectweb.asm.tree.*; +import team.stiff.pomelo.EventManager; + +import static org.objectweb.asm.Opcodes.*; + +/** + * Author Seth + * 4/6/2019 @ 6:01 PM. + */ +public final class PlayerControllerMPPatch extends ClassPatch { + + public PlayerControllerMPPatch() { + super("net.minecraft.client.multiplayer.PlayerControllerMP", "bsa"); + } + + /** + * This is called when we finish mining a block + * @param methodNode + * @param env + */ + @MethodPatch( + mcpName = "onPlayerDestroyBlock", + notchName = "a", + mcpDesc = "(Lnet/minecraft/util/math/BlockPos;)Z", + notchDesc = "(Let;)Z") + public void onPlayerDestroyBlock(MethodNode methodNode, PatchManager.Environment env) { + //create a list of instructions and add the needed instructions to call our hook function + final InsnList insnList = new InsnList(); + //add ALOAD to pass the BlockPos into our hook function + insnList.add(new VarInsnNode(ALOAD, 1)); + //call our hook function + insnList.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "onPlayerDestroyBlockHook", env == PatchManager.Environment.IDE ? "(Lnet/minecraft/util/math/BlockPos;)Z" : "(Let;)Z", false)); + //add a label to jump to + final LabelNode jmp = new LabelNode(); + //add if equals and pass the label + insnList.add(new JumpInsnNode(IFEQ, jmp)); + //add a 0 or false + insnList.add(new InsnNode(ICONST_0)); + //add return so the rest of the function doesn't get called + insnList.add(new InsnNode(IRETURN)); + //add our label + insnList.add(jmp); + //insert the list of instructions at the top of the function + methodNode.instructions.insert(insnList); + } + + /** + * Our onPlayerDestroyBlock hook used to get block coordinates + * of what we just broke + * @param pos + * @return + */ + public static boolean onPlayerDestroyBlockHook(BlockPos pos) { + //dispatch our event and pass the BlockPos + final EventDestroyBlock event = new EventDestroyBlock(pos); + Seppuku.INSTANCE.getEventManager().dispatchEvent(event); + + return event.isCanceled(); + } + + /** + * This is where minecraft starts mining + * @param methodNode + * @param env + */ + @MethodPatch( + mcpName = "clickBlock", + notchName = "a", + mcpDesc = "(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/EnumFacing;)Z", + notchDesc = "(Let;Lfa;)Z") + public void clickBlock(MethodNode methodNode, PatchManager.Environment env) { + //create a list of instructions and add the needed instructions to call our hook function + final InsnList insnList = new InsnList(); + //add ALOAD to pass the BlockPos into our hook function + insnList.add(new VarInsnNode(ALOAD, 1)); + //add ALOAD to pass the EnumFacing into our hook function + insnList.add(new VarInsnNode(ALOAD, 2)); + //call our hook function + insnList.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "clickBlockHook", env == PatchManager.Environment.IDE ? "(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/EnumFacing;)Z" : "(Let;Lfa;)Z", false)); + //add a label to jump to + final LabelNode jmp = new LabelNode(); + //add if equals and pass the label + insnList.add(new JumpInsnNode(IFEQ, jmp)); + //add a 0 or false + insnList.add(new InsnNode(ICONST_0)); + //add return so the rest of the function doesn't get called + insnList.add(new InsnNode(IRETURN)); + //add our label + insnList.add(jmp); + //insert the list of instructions at the top of the function + methodNode.instructions.insert(insnList); + } + + /** + * Our clickBlock hook used to detect when we first + * click on a block + * @param pos + * @param face + * @return + */ + public static boolean clickBlockHook(BlockPos pos, EnumFacing face) { + //dispatch our event and pass the BlockPos and EnumFacing + final EventClickBlock event = new EventClickBlock(pos, face); + Seppuku.INSTANCE.getEventManager().dispatchEvent(event); + + return event.isCanceled(); + } + + /** + * This is where minecraft handles abort destroying blocks + * and resetting break progress + * @param methodNode + * @param env + */ + @MethodPatch( + mcpName = "resetBlockRemoving", + notchName = "c", + mcpDesc = "()V") + public void resetBlockRemoving(MethodNode methodNode, PatchManager.Environment env) { + //create a list of instructions and add the needed instructions to call our hook function + final InsnList insnList = new InsnList(); + insnList.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "resetBlockRemovingHook", "()Z", false)); + //add a label to jump to + final LabelNode jmp = new LabelNode(); + //add if equals and pass the label + insnList.add(new JumpInsnNode(IFEQ, jmp)); + //add return so the rest of the function doesn't get called + insnList.add(new InsnNode(RETURN)); + //add our label + insnList.add(jmp); + //insert the list of instructions at the top of the function + methodNode.instructions.insert(insnList); + } + + /** + * Our resetBlockRemoving used to detect when we stop mining + * It is cancellable so we can save break progress + * @return + */ + public static boolean resetBlockRemovingHook() { + //dispatch the event + final EventResetBlockRemoving event = new EventResetBlockRemoving(); + Seppuku.INSTANCE.getEventManager().dispatchEvent(event); + + return event.isCanceled(); + } + + /** + * This is where minecraft handles breaking blocks and calculates + * block hit delay/current damage + * @param methodNode + * @param env + */ + @MethodPatch( + mcpName = "onPlayerDamageBlock", + notchName = "b", + mcpDesc = "(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/EnumFacing;)Z", + notchDesc = "(Let;Lfa;)Z") + public void onPlayerDamageBlock(MethodNode methodNode, PatchManager.Environment env) { + //create a list of instructions and add the needed instructions to call our hook function + final InsnList insnList = new InsnList(); + //add ALOAD to pass the BlockPos into our hook function + insnList.add(new VarInsnNode(ALOAD, 1)); + //add ALOAD to pass the EnumFacing into our hook function + insnList.add(new VarInsnNode(ALOAD, 2)); + //call our hook function + insnList.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "onPlayerDamageBlockHook", env == PatchManager.Environment.IDE ? "(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/EnumFacing;)Z" : "(Let;Lfa;)Z", false)); + //add a label to jump to + final LabelNode jmp = new LabelNode(); + //add if equals and pass the label + insnList.add(new JumpInsnNode(IFEQ, jmp)); + //add a 0 or false + insnList.add(new InsnNode(ICONST_0)); + //add return so the rest of the function doesn't get called + insnList.add(new InsnNode(IRETURN)); + //add our label + insnList.add(jmp); + //insert the list of instructions at the top of the function + methodNode.instructions.insert(insnList); + } + + /** + * Our onPlayerDamageBlock hook used to detect if we are + * currently mining a block + * @param pos + * @param face + * @return + */ + public static boolean onPlayerDamageBlockHook(BlockPos pos, EnumFacing face) { + //dispatch the event + final EventPlayerDamageBlock event = new EventPlayerDamageBlock(pos, face); + Seppuku.INSTANCE.getEventManager().dispatchEvent(event); + + return event.isCanceled(); + } + + /** + * This is where minecraft handles right clicking + * on blocks + * @param methodNode + * @param env + */ + @MethodPatch( + mcpName = "processRightClickBlock", + notchName = "a", + mcpDesc = "(Lnet/minecraft/client/entity/EntityPlayerSP;Lnet/minecraft/client/multiplayer/WorldClient;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/EnumFacing;Lnet/minecraft/util/math/Vec3d;Lnet/minecraft/util/EnumHand;)Lnet/minecraft/util/EnumActionResult;", + notchDesc = "(Lbud;Lbsb;Let;Lfa;Lbhe;Lub;)Lud;") + public void processRightClickBlock(MethodNode methodNode, PatchManager.Environment env) { + //create a list of instructions + final InsnList insnList = new InsnList(); + + //create a new instance of "EventRightClickBlock" and dupe the top val on the stack + insnList.add(new TypeInsnNode(NEW, Type.getInternalName(EventRightClickBlock.class))); + insnList.add(new InsnNode(DUP)); + //add ALOAD to pass BlockPos into our call + insnList.add(new VarInsnNode(ALOAD, 3)); + //add ALOAD to pass EnumFacing into our call + insnList.add(new VarInsnNode(ALOAD, 4)); + //add ALOAD to pass Vec3d into our call + insnList.add(new VarInsnNode(ALOAD, 5)); + //add ALOAD to pass EnumHand into our call + insnList.add(new VarInsnNode(ALOAD, 6)); + //call EventRightClickBlock's constructor + insnList.add(new MethodInsnNode(INVOKESPECIAL, Type.getInternalName(EventRightClickBlock.class), "", env == PatchManager.Environment.IDE ? "(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/EnumFacing;Lnet/minecraft/util/math/Vec3d;Lnet/minecraft/util/EnumHand;)V" : "(Let;Lfa;Lbhe;Lub;)V", false)); + //store a reference to the instance in the local vars + insnList.add(new VarInsnNode(ASTORE, 19)); + + //get "Seppuku.INSTNANCE" + insnList.add(new FieldInsnNode(GETSTATIC, Type.getInternalName(Seppuku.class), "INSTANCE", "Lme/rigamortis/seppuku/Seppuku;")); + //call "getEventManager" + insnList.add(new MethodInsnNode(INVOKEVIRTUAL, Type.getInternalName(Seppuku.class), "getEventManager", "()Lteam/stiff/pomelo/EventManager;", false)); + + //add ALOAD to get our event we stored + insnList.add(new VarInsnNode(ALOAD, 19)); + //call "dispatchEvent" and pass the event + insnList.add(new MethodInsnNode(INVOKEINTERFACE, Type.getInternalName(EventManager.class), "dispatchEvent", "(Ljava/lang/Object;)Ljava/lang/Object;", true)); + //remove the top val on the stack because we duped it + insnList.add(new InsnNode(POP)); + + //add ALOAD to get our event + insnList.add(new VarInsnNode(ALOAD, 19)); + //call "isCanceled" + insnList.add(new MethodInsnNode(INVOKEVIRTUAL, Type.getInternalName(EventRightClickBlock.class), "isCanceled", "()Z", false)); + //add a label to jump to + final LabelNode jmp = new LabelNode(); + //add "if equals" + insnList.add(new JumpInsnNode(IFEQ, jmp)); + //return "EnumActionResult.FAIL" + insnList.add(new FieldInsnNode(GETSTATIC, env == PatchManager.Environment.IDE ? "net/minecraft/util/EnumActionResult" : "ud", env == PatchManager.Environment.IDE ? "FAIL" : "c", env == PatchManager.Environment.IDE ? "Lnet/minecraft/util/EnumActionResult;" : "Lud;")); + //add ARETURN because we are returning an object... + insnList.add(new InsnNode(ARETURN)); + //add our label + insnList.add(jmp); + + //insert the list of instructions at the top + methodNode.instructions.insert(insnList); + } + + @MethodPatch( + mcpName = "processRightClick", + notchName = "a", + mcpDesc = "(Lnet/minecraft/entity/player/EntityPlayer;Lnet/minecraft/world/World;Lnet/minecraft/util/EnumHand;)Lnet/minecraft/util/EnumActionResult;", + notchDesc = "(Laed;Lamu;Lub;)Lud;") + public void processRightClick(MethodNode methodNode, PatchManager.Environment env) { + //create a list of instructions + final InsnList insnList = new InsnList(); + + //create a new instance of "EventRightClick" and dupe the top val on the stack + insnList.add(new TypeInsnNode(NEW, Type.getInternalName(EventRightClick.class))); + insnList.add(new InsnNode(DUP)); + //add ALOAD to pass EnumHand into our call + insnList.add(new VarInsnNode(ALOAD, 3)); + //call EventRightClick's constructor + insnList.add(new MethodInsnNode(INVOKESPECIAL, Type.getInternalName(EventRightClick.class), "", env == PatchManager.Environment.IDE ? "(Lnet/minecraft/util/EnumHand;)V" : "(Lub;)V", false)); + //store a reference to the instance in the local vars + insnList.add(new VarInsnNode(ASTORE, 10)); + + //get "Seppuku.INSTNANCE" + insnList.add(new FieldInsnNode(GETSTATIC, Type.getInternalName(Seppuku.class), "INSTANCE", "Lme/rigamortis/seppuku/Seppuku;")); + //call "getEventManager" + insnList.add(new MethodInsnNode(INVOKEVIRTUAL, Type.getInternalName(Seppuku.class), "getEventManager", "()Lteam/stiff/pomelo/EventManager;", false)); + + //add ALOAD to get our event we stored + insnList.add(new VarInsnNode(ALOAD, 10)); + //call "dispatchEvent" and pass the event + insnList.add(new MethodInsnNode(INVOKEINTERFACE, Type.getInternalName(EventManager.class), "dispatchEvent", "(Ljava/lang/Object;)Ljava/lang/Object;", true)); + //remove the top val on the stack because we duped it + insnList.add(new InsnNode(POP)); + + //add ALOAD to get our event + insnList.add(new VarInsnNode(ALOAD, 10)); + //call "isCanceled" + insnList.add(new MethodInsnNode(INVOKEVIRTUAL, Type.getInternalName(EventRightClick.class), "isCanceled", "()Z", false)); + //add a label to jump to + final LabelNode jmp = new LabelNode(); + //add "if equals" + insnList.add(new JumpInsnNode(IFEQ, jmp)); + //return "EnumActionResult.FAIL" + insnList.add(new FieldInsnNode(GETSTATIC, env == PatchManager.Environment.IDE ? "net/minecraft/util/EnumActionResult" : "ud", env == PatchManager.Environment.IDE ? "FAIL" : "c", env == PatchManager.Environment.IDE ? "Lnet/minecraft/util/EnumActionResult;" : "Lud;")); + //add ARETURN because we are returning an object... + insnList.add(new InsnNode(ARETURN)); + //add our label + insnList.add(jmp); + + //insert the list of instructions at the top + methodNode.instructions.insert(insnList); + } + + @MethodPatch( + mcpName = "isHittingPosition", + notchName = "b", + mcpDesc = "(Lnet/minecraft/util/math/BlockPos;)Z", + notchDesc = "(Let;)Z") + public void isHittingPosition(MethodNode methodNode, PatchManager.Environment env) { + //create a list of instructions and add the needed instructions to call our hook function + final InsnList insnList = new InsnList(); + //add ALOAD to pass the BlockPos into our call + insnList.add(new VarInsnNode(ALOAD, 1)); + //call our hook function + insnList.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "isHittingPositionHook", env == PatchManager.Environment.IDE ? "(Lnet/minecraft/util/math/BlockPos;)Z" : "(Let;)Z", false)); + //add a label to jump to + final LabelNode jmp = new LabelNode(); + //add if equals and pass the label + insnList.add(new JumpInsnNode(IFEQ, jmp)); + //add a 0 or false + insnList.add(new InsnNode(ICONST_0)); + //add return so the rest of the function doesn't get called + insnList.add(new InsnNode(IRETURN)); + //add our label + insnList.add(jmp); + //insert the list of instructions at the top of the function + methodNode.instructions.insert(insnList); + } + + public static boolean isHittingPositionHook(BlockPos pos) { + final EventHittingPosition event = new EventHittingPosition(pos); + Seppuku.INSTANCE.getEventManager().dispatchEvent(event); + + return event.isCanceled(); + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/patch/RenderLivingBasePatch.java b/src/main/java/me/rigamortis/seppuku/impl/patch/RenderLivingBasePatch.java new file mode 100644 index 0000000..fd30946 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/patch/RenderLivingBasePatch.java @@ -0,0 +1,128 @@ +package me.rigamortis.seppuku.impl.patch; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.event.EventStageable; +import me.rigamortis.seppuku.api.event.render.EventRenderLivingEntity; +import me.rigamortis.seppuku.api.event.render.EventRenderName; +import me.rigamortis.seppuku.api.patch.ClassPatch; +import me.rigamortis.seppuku.api.patch.MethodPatch; +import me.rigamortis.seppuku.api.util.ASMUtil; +import me.rigamortis.seppuku.impl.management.PatchManager; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import org.objectweb.asm.Type; +import org.objectweb.asm.tree.*; + +import static org.objectweb.asm.Opcodes.*; + +/** + * Author Seth + * 4/9/2019 @ 10:52 AM. + */ +public final class RenderLivingBasePatch extends ClassPatch { + + public RenderLivingBasePatch() { + super("net.minecraft.client.renderer.entity.RenderLivingBase", "caa"); + } + + /** + * This is where minecraft renders name plates + * @param methodNode + * @param env + */ + @MethodPatch( + mcpName = "renderName", + notchName = "a", + mcpDesc = "(Lnet/minecraft/entity/EntityLivingBase;DDD)V", + notchDesc = "(Lvp;DDD)V") + public void renderName(MethodNode methodNode, PatchManager.Environment env) { + //create a list of instructions and add the needed instructions to call our hook function + final InsnList insnList = new InsnList(); + //add ALOAD to pass the entity into our hook function + insnList.add(new VarInsnNode(ALOAD, 1)); + //call our hook function + insnList.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "renderNameHook", env == PatchManager.Environment.IDE ? "(Lnet/minecraft/entity/EntityLivingBase;)Z" : "(Lvp;)Z", false)); + //add a label to jump to + final LabelNode jmp = new LabelNode(); + //add if equals and pass the label + insnList.add(new JumpInsnNode(IFEQ, jmp)); + //add return so the rest of the function doesn't get called + insnList.add(new InsnNode(RETURN)); + //add our label + insnList.add(jmp); + //insert the list of instructions at the top of the function + methodNode.instructions.insert(insnList); + } + + /** + * This is our renderName hook + * Used to disable rendering minecrafts default + * name tags on certain entities + * @param entity + * @return + */ + public static boolean renderNameHook(EntityLivingBase entity) { + //dispatch our event and pass the entity in + final EventRenderName event = new EventRenderName(entity); + Seppuku.INSTANCE.getEventManager().dispatchEvent(event); + + return event.isCanceled(); + } + +// /** +// * This is where minecraft renders living entity models +// * @param methodNode +// * @param env +// */ +// @MethodPatch( +// mcpName = "doRender", +// notchName = "a", +// mcpDesc = "(Lnet/minecraft/entity/EntityLivingBase;DDDFF)V", +// notchDesc = "(Lvp;DDDFF)V") +// public void doRender(MethodNode methodNode, PatchManager.Environment env) { +// //create a list of instructions and add the needed instructions to call our hook function +// final InsnList preInsn = new InsnList(); +// //add ALOAD to pass the entity into our hook function +// preInsn.add(new VarInsnNode(ALOAD, 1)); +// //EventStageable.EventStage.PRE +// preInsn.add(new FieldInsnNode(GETSTATIC, "me/rigamortis/seppuku/api/event/EventStageable$EventStage", "PRE", "Lme/rigamortis/seppuku/api/event/EventStageable$EventStage;")); +// //call our hook function +// preInsn.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "doRenderHook", env == PatchManager.Environment.IDE ? "(Lnet/minecraft/entity/EntityLivingBase;Lme/rigamortis/seppuku/api/event/EventStageable$EventStage;)Z" : "(Lvp;Lme/rigamortis/seppuku/api/event/EventStageable$EventStage;)Z", false)); +// //add a label to jump to +// final LabelNode jmp = new LabelNode(); +// //add if equals and pass the label +// preInsn.add(new JumpInsnNode(IFEQ, jmp)); +// //add return so the rest of the function doesn't get called +// preInsn.add(new InsnNode(RETURN)); +// //add our label +// preInsn.add(jmp); +// //insert the list of instructions at the top of the function +// methodNode.instructions.insert(preInsn); +// +// //create a list of instructions and add the needed instructions to call our hook function +// final InsnList postInsn = new InsnList(); +// //add ALOAD to pass the entity into our hook function +// postInsn.add(new VarInsnNode(ALOAD, 1)); +// //EventStageable.EventStage.POST +// postInsn.add(new FieldInsnNode(GETSTATIC, "me/rigamortis/seppuku/api/event/EventStageable$EventStage", "POST", "Lme/rigamortis/seppuku/api/event/EventStageable$EventStage;")); +// //call our hook function +// preInsn.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "doRenderHook", env == PatchManager.Environment.IDE ? "(Lnet/minecraft/entity/EntityLivingBase;Lme/rigamortis/seppuku/api/event/EventStageable$EventStage;)Z" : "(Lvp;Lme/rigamortis/seppuku/api/event/EventStageable$EventStage;)Z", false)); +// //insert the list of instructions at the bottom of the function +// methodNode.instructions.insertBefore(ASMUtil.bottom(methodNode), postInsn); +// } +// +// /** +// * Our doRender hook used to cancel rendering specific living +// * entities or to modify the way they render +// * @param entity +// * @param stage +// * @return +// */ +// public static boolean doRenderHook(EntityLivingBase entity, EventStageable.EventStage stage) { +// final EventRenderLivingEntity event = new EventRenderLivingEntity(stage, entity); +// Seppuku.INSTANCE.getEventManager().dispatchEvent(event); +// +// return event.isCanceled(); +// } + +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/patch/RenderManagerPatch.java b/src/main/java/me/rigamortis/seppuku/impl/patch/RenderManagerPatch.java new file mode 100644 index 0000000..de0d0f7 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/patch/RenderManagerPatch.java @@ -0,0 +1,109 @@ +package me.rigamortis.seppuku.impl.patch; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.event.EventStageable; +import me.rigamortis.seppuku.api.event.render.EventRenderEntity; +import me.rigamortis.seppuku.api.patch.ClassPatch; +import me.rigamortis.seppuku.api.patch.MethodPatch; +import me.rigamortis.seppuku.api.util.ASMUtil; +import me.rigamortis.seppuku.impl.management.PatchManager; +import net.minecraft.entity.Entity; +import org.objectweb.asm.Type; +import org.objectweb.asm.tree.*; + +import static org.objectweb.asm.Opcodes.*; + +/** + * Author Seth + * 4/9/2019 @ 9:37 AM. + */ +public final class RenderManagerPatch extends ClassPatch { + + public RenderManagerPatch() { + super("net.minecraft.client.renderer.entity.RenderManager", "bzf"); + } + + /** + * This is where minecraft handles rendering of entities + * @param methodNode + * @param env + */ + @MethodPatch( + mcpName = "renderEntity", + notchName = "a", + mcpDesc = "(Lnet/minecraft/entity/Entity;DDDFFZ)V", + notchDesc = "(Lvg;DDDFFZ)V") + public void renderEntity(MethodNode methodNode, PatchManager.Environment env) { + //create a list of instructions and add the needed instructions to call our hook function + final InsnList preInsn = new InsnList(); + //add ALOAD to pass the entity into our hook function + preInsn.add(new VarInsnNode(ALOAD, 1)); + //add DLOAD to pass the x into our hook function + preInsn.add(new VarInsnNode(DLOAD, 2)); + //add DLOAD to pass the y into our hook function + preInsn.add(new VarInsnNode(DLOAD, 4)); + //add DLOAD to pass the z into our hook function + preInsn.add(new VarInsnNode(DLOAD, 6)); + //add FLOAD to pass the yaw into our hook function + preInsn.add(new VarInsnNode(FLOAD, 8)); + //add FLOAD to pass the partialTicks into our hook function + preInsn.add(new VarInsnNode(FLOAD, 9)); + //EventStageable.EventStage.PRE + preInsn.add(new FieldInsnNode(GETSTATIC, "me/rigamortis/seppuku/api/event/EventStageable$EventStage", "PRE", "Lme/rigamortis/seppuku/api/event/EventStageable$EventStage;")); + //call our hook function + preInsn.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "renderEntityHook", env == PatchManager.Environment.IDE ? "(Lnet/minecraft/entity/Entity;DDDFFLme/rigamortis/seppuku/api/event/EventStageable$EventStage;)Z" : "(Lvg;DDDFFLme/rigamortis/seppuku/api/event/EventStageable$EventStage;)Z", false)); + //add a label to jump to + final LabelNode jmp = new LabelNode(); + //add if equals and pass the label + preInsn.add(new JumpInsnNode(IFEQ, jmp)); + //add return so the rest of the function doesn't get called + preInsn.add(new InsnNode(RETURN)); + //add our label + preInsn.add(jmp); + //insert the list of instructions at the top of the function + methodNode.instructions.insert(preInsn); + + //create a list of instructions and add the needed instructions to call our hook function + final InsnList postInsn = new InsnList(); + //add ALOAD to pass the entity into our hook function + postInsn.add(new VarInsnNode(ALOAD, 1)); + //add DLOAD to pass the x into our hook function + postInsn.add(new VarInsnNode(DLOAD, 2)); + //add DLOAD to pass the y into our hook function + postInsn.add(new VarInsnNode(DLOAD, 4)); + //add DLOAD to pass the z into our hook function + postInsn.add(new VarInsnNode(DLOAD, 6)); + //add FLOAD to pass the yaw into our hook function + postInsn.add(new VarInsnNode(FLOAD, 8)); + //add FLOAD to pass the partialTicks into our hook function + postInsn.add(new VarInsnNode(FLOAD, 9)); + //EventStageable.EventStage.POST + postInsn.add(new FieldInsnNode(GETSTATIC, "me/rigamortis/seppuku/api/event/EventStageable$EventStage", "POST", "Lme/rigamortis/seppuku/api/event/EventStageable$EventStage;")); + //call our hook function + postInsn.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "renderEntityHook", env == PatchManager.Environment.IDE ? "(Lnet/minecraft/entity/Entity;DDDFFLme/rigamortis/seppuku/api/event/EventStageable$EventStage;)Z" : "(Lvg;DDDFFLme/rigamortis/seppuku/api/event/EventStageable$EventStage;)Z", false)); + //insert the list of instructions at the bottom of the function + methodNode.instructions.insertBefore(ASMUtil.bottom(methodNode), postInsn); + } + + /** + * Our renderEntity hook + * Used to disable rendering of certain entities or modify the + * way they render + * @param entity + * @param x + * @param y + * @param z + * @param yaw + * @param partialTicks + * @param stage + * @return + */ + public static boolean renderEntityHook(Entity entity, double x, double y, double z, float yaw, float partialTicks, EventStageable.EventStage stage) { + //dispatch our event and pass the render information into it along with the event stage + final EventRenderEntity event = new EventRenderEntity(stage, entity, x, y, z, yaw, partialTicks); + Seppuku.INSTANCE.getEventManager().dispatchEvent(event); + + return event.isCanceled(); + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/patch/VisGraphPatch.java b/src/main/java/me/rigamortis/seppuku/impl/patch/VisGraphPatch.java new file mode 100644 index 0000000..0f41afb --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/patch/VisGraphPatch.java @@ -0,0 +1,62 @@ +package me.rigamortis.seppuku.impl.patch; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.event.world.EventSetOpaqueCube; +import me.rigamortis.seppuku.api.patch.ClassPatch; +import me.rigamortis.seppuku.api.patch.MethodPatch; +import me.rigamortis.seppuku.impl.management.PatchManager; +import org.objectweb.asm.Type; +import org.objectweb.asm.tree.*; + +import static org.objectweb.asm.Opcodes.*; + +/** + * Author Seth + * 4/7/2019 @ 5:02 PM. + */ +public final class VisGraphPatch extends ClassPatch { + + public VisGraphPatch() { + super("net.minecraft.client.renderer.chunk.VisGraph", "bxu"); + } + + /** + * This is where minecraft handles culling + * @param methodNode + * @param env + */ + @MethodPatch( + mcpName = "setOpaqueCube", + notchName = "a", + mcpDesc = "(Lnet/minecraft/util/math/BlockPos;)V", + notchDesc = "(Let;)V") + public void setOpaqueCube(MethodNode methodNode, PatchManager.Environment env) { + //create a list of instructions and add the needed instructions to call our hook function + final InsnList insnList = new InsnList(); + //call our hook function + insnList.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "setOpaqueCubeHook", "()Z", false)); + //add a label to jump to + final LabelNode jmp = new LabelNode(); + //add if equals and pass the label + insnList.add(new JumpInsnNode(IFEQ, jmp)); + //add return so the rest of the function doesn't get called + insnList.add(new InsnNode(RETURN)); + //add our label + insnList.add(jmp); + //insert the list of instructions at the top of the function + methodNode.instructions.insert(insnList); + } + + /** + * Our setOpaqueCube hook + * Cancel to prevent culling(this may cost a few frames) + * @return + */ + public static boolean setOpaqueCubeHook() { + final EventSetOpaqueCube event = new EventSetOpaqueCube(); + Seppuku.INSTANCE.getEventManager().dispatchEvent(event); + + return event.isCanceled(); + } + +} diff --git a/src/main/java/me/rigamortis/seppuku/impl/patch/WorldPatch.java b/src/main/java/me/rigamortis/seppuku/impl/patch/WorldPatch.java new file mode 100644 index 0000000..7218a64 --- /dev/null +++ b/src/main/java/me/rigamortis/seppuku/impl/patch/WorldPatch.java @@ -0,0 +1,61 @@ +package me.rigamortis.seppuku.impl.patch; + +import me.rigamortis.seppuku.Seppuku; +import me.rigamortis.seppuku.api.event.world.EventLightUpdate; +import me.rigamortis.seppuku.api.patch.ClassPatch; +import me.rigamortis.seppuku.api.patch.MethodPatch; +import me.rigamortis.seppuku.impl.management.PatchManager; +import org.objectweb.asm.Type; +import org.objectweb.asm.tree.*; + +import static org.objectweb.asm.Opcodes.*; + +/** + * Author Seth + * 4/6/2019 @ 1:25 PM. + */ +public final class WorldPatch extends ClassPatch { + + public WorldPatch() { + super("net.minecraft.world.World", "amu"); + } + + /** + * This function is used to update light for blocks + * It is VERY unoptimized and in some cases it's + * better off to disable + * @param methodNode + * @param env + */ + @MethodPatch( + mcpName = "checkLightFor", + notchName = "c", + mcpDesc = "(Lnet/minecraft/world/EnumSkyBlock;Lnet/minecraft/util/math/BlockPos;)Z", + notchDesc = "(Lana;Let;)Z") + public void checkLightFor(MethodNode methodNode, PatchManager.Environment env) { + //create a list of instructions + final InsnList list = new InsnList(); + //call our hook function + list.add(new MethodInsnNode(INVOKESTATIC, Type.getInternalName(this.getClass()), "checkLightForHook", "()Z", false)); + //create a label to jump to + final LabelNode jmp = new LabelNode(); + //add "if equals" and pass in the label + list.add(new JumpInsnNode(IFEQ, jmp)); + //add 0 or false + list.add(new InsnNode(ICONST_0)); + //return 0 or false + list.add(new InsnNode(IRETURN)); + //add our label + list.add(jmp); + //insert the instructions at the top of the function + methodNode.instructions.insert(list); + } + + public static boolean checkLightForHook() { + final EventLightUpdate event = new EventLightUpdate(); + Seppuku.INSTANCE.getEventManager().dispatchEvent(event); + + return event.isCanceled(); + } + +} diff --git a/src/main/java/team/stiff/pomelo/EventManager.java b/src/main/java/team/stiff/pomelo/EventManager.java new file mode 100644 index 0000000..4e8d03d --- /dev/null +++ b/src/main/java/team/stiff/pomelo/EventManager.java @@ -0,0 +1,51 @@ +package team.stiff.pomelo; + +import team.stiff.pomelo.handler.EventHandler; + +/** + * Pomelo is a simplistic event-bus that supports event filtering. + *

+ * todo; thread-safety + * todo; junit testing + * + * @author Daniel + * @since May 31, 2017 + */ +public interface EventManager { + + /** + * Notify all registered {@link EventHandler}s that are listening + * for the passed event that the event has been dispatched. + * + * @param event event instance + * @param event type + * @return passed event instance + */ + E dispatchEvent(E event); + + /** + * Checks if the given listener object is registered. + * + * @param listener listener instance + * @return true if registered; false otherwise + */ + boolean isRegisteredListener(Object listener); + + /** + * Register an object as an event listener that listens for the provided + * eventClass type to be dispatched. + * + * @param listener event listener instance + * @return true if successfully added; false otherwise + */ + boolean addEventListener(Object listener); + + /** + * Remove an event listener from the bus so it does not listen + * for event dispatches anymore. + * + * @param listener event listener instance + * @return true if successfully removed; false otherwise + */ + boolean removeEventListener(Object listener); +} diff --git a/src/main/java/team/stiff/pomelo/dispatch/EventDispatcher.java b/src/main/java/team/stiff/pomelo/dispatch/EventDispatcher.java new file mode 100644 index 0000000..fc07029 --- /dev/null +++ b/src/main/java/team/stiff/pomelo/dispatch/EventDispatcher.java @@ -0,0 +1,19 @@ +package team.stiff.pomelo.dispatch; + +/** + * The dispatcher handles invocation of all registered listeners. + * + * @author Daniel + * @since May 31, 2017 + */ +public interface EventDispatcher { + + /** + * Dispatch all listeners that are listening for the + * given event. + * + * @param event event instance + * @param event type + */ + void dispatch(E event); +} diff --git a/src/main/java/team/stiff/pomelo/filter/EventFilter.java b/src/main/java/team/stiff/pomelo/filter/EventFilter.java new file mode 100644 index 0000000..9d77f0e --- /dev/null +++ b/src/main/java/team/stiff/pomelo/filter/EventFilter.java @@ -0,0 +1,24 @@ +package team.stiff.pomelo.filter; + +import team.stiff.pomelo.handler.EventHandler; + +/** + * An event filter tests whether or not certain conditions + * are met whatever situation the filter will be used in + * before allowing the event handler to be invoked. + * + * @author Daniel + * @since May 31, 2017 + */ +public interface EventFilter { + + /** + * Tests the given predicate when the handling + * event is dispatched. + * + * @param eventHandler event handler instance + * @param event instance of event being dispatched + * @return true if listener passes all filters, false otherwise + */ + boolean test(EventHandler eventHandler, E event); +} diff --git a/src/main/java/team/stiff/pomelo/filter/EventFilterScanner.java b/src/main/java/team/stiff/pomelo/filter/EventFilterScanner.java new file mode 100644 index 0000000..3cf55e5 --- /dev/null +++ b/src/main/java/team/stiff/pomelo/filter/EventFilterScanner.java @@ -0,0 +1,20 @@ +package team.stiff.pomelo.filter; + +import java.util.Set; + +/** + * Scans a listener for any filters associated with the listener. + * + * @author Daniel + * @since Jun 13, 2017 + */ +public interface EventFilterScanner { + + /** + * Finds all associated filters with the given listener + * type. + * + * @param listener listener instance + */ + Set scan(T listener); +} diff --git a/src/main/java/team/stiff/pomelo/handler/EventHandler.java b/src/main/java/team/stiff/pomelo/handler/EventHandler.java new file mode 100644 index 0000000..47ef15d --- /dev/null +++ b/src/main/java/team/stiff/pomelo/handler/EventHandler.java @@ -0,0 +1,34 @@ +package team.stiff.pomelo.handler; + +import team.stiff.pomelo.filter.EventFilter; + +/** + * The event handler is a container that will assist in the + * process of handling the event. + * + * @author Daniel + * @since May 31, 2017 + */ +public interface EventHandler { + + /** + * Invoked when the listener needs to handle + * an event. + */ + void handle(final E event); + + /** + * The object of the event listener. + * + * @return parent of listener + */ + Object getListener(); + + /** + * All of the filters that will be tested on the + * handler when being dispatched. + * + * @return iterable filters + */ + Iterable getFilters(); +} diff --git a/src/main/java/team/stiff/pomelo/handler/scan/EventHandlerScanner.java b/src/main/java/team/stiff/pomelo/handler/scan/EventHandlerScanner.java new file mode 100644 index 0000000..1676f3d --- /dev/null +++ b/src/main/java/team/stiff/pomelo/handler/scan/EventHandlerScanner.java @@ -0,0 +1,24 @@ +package team.stiff.pomelo.handler.scan; + +import team.stiff.pomelo.handler.EventHandler; + +import java.util.Map; +import java.util.Set; + +/** + * Attempts to locate all event listeners in a given object and + * stores them in a unmodifiable list. ({@see #getImmutableListeners}) + * + * @author Daniel + * @since May 31, 2017 + */ +public interface EventHandlerScanner { + + /** + * Check the given object for any possible listeners that are + * contained inside. + * + * @return true if listeners located, false otherwise + */ + Map, Set> locate(Object listenerContainer); +} diff --git a/src/main/java/team/stiff/pomelo/impl/annotated/AnnotatedEventManager.java b/src/main/java/team/stiff/pomelo/impl/annotated/AnnotatedEventManager.java new file mode 100644 index 0000000..f92f253 --- /dev/null +++ b/src/main/java/team/stiff/pomelo/impl/annotated/AnnotatedEventManager.java @@ -0,0 +1,75 @@ +package team.stiff.pomelo.impl.annotated; + +import team.stiff.pomelo.EventManager; +import team.stiff.pomelo.dispatch.EventDispatcher; +import team.stiff.pomelo.handler.EventHandler; +import team.stiff.pomelo.handler.scan.EventHandlerScanner; +import team.stiff.pomelo.impl.annotated.dispatch.MethodEventDispatcher; +import team.stiff.pomelo.impl.annotated.handler.scan.MethodHandlerScanner; + +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +/** + * An {@link EventManager} implementation that uses methods marked + * with the {@link team.stiff.pomelo.impl.annotated.handler.annotation.Listener} + * annotation. + * + * @author Daniel + * @since May 31, 2017 + */ +public final class AnnotatedEventManager implements EventManager { + /** + * Listener scanner implementation used to find all listeners inside + * of a specific listener. + */ + private final EventHandlerScanner eventHandlerScanner; + + /** + * A map that pairs a listener container with a provided dispatcher implementation. + */ + private final Map listenerDispatchers; + + public AnnotatedEventManager() { + this.eventHandlerScanner = new MethodHandlerScanner(); + this.listenerDispatchers = new ConcurrentHashMap<>(); + } + + @Override + public E dispatchEvent(final E event) { + // Iterate the stored dispatchers and notify all listeners + for (final EventDispatcher dispatcher : listenerDispatchers.values()) + dispatcher.dispatch(event); + + return event; + } + + @Override + public boolean isRegisteredListener(final Object listener) { + return listenerDispatchers.containsKey(listener); + } + + @Override + public boolean addEventListener(final Object listenerContainer) { + // Check if we've already got this object registered + if (listenerDispatchers.containsKey(listenerContainer)) + return false; + + // locate all handlers inside of the container + final Map, Set> eventHandlers = + eventHandlerScanner.locate(listenerContainer); + if (eventHandlers.isEmpty()) + return false; + + // create a new dispatcher for this specific listener + return listenerDispatchers.put(listenerContainer, + new MethodEventDispatcher(eventHandlers)) == null; + } + + @Override + public boolean removeEventListener(final Object listenerContainer) { + // Remove the given listener container from the dispatchers map + return listenerDispatchers.remove(listenerContainer) != null; + } +} diff --git a/src/main/java/team/stiff/pomelo/impl/annotated/dispatch/MethodEventDispatcher.java b/src/main/java/team/stiff/pomelo/impl/annotated/dispatch/MethodEventDispatcher.java new file mode 100644 index 0000000..bd15e25 --- /dev/null +++ b/src/main/java/team/stiff/pomelo/impl/annotated/dispatch/MethodEventDispatcher.java @@ -0,0 +1,36 @@ +package team.stiff.pomelo.impl.annotated.dispatch; + +import team.stiff.pomelo.dispatch.EventDispatcher; +import team.stiff.pomelo.handler.EventHandler; + +import java.lang.reflect.Method; +import java.util.Collections; +import java.util.Map; +import java.util.Set; + +/** + * An implementation of the {@link EventDispatcher} designed + * to invoke the listeners via reflection as the handler is a + * {@link Method} object. + * + * @author Daniel + * @since May 31, 2017 + */ +public final class MethodEventDispatcher implements EventDispatcher { + /** + * The scanning strategy chosen by the event-bus implementation. + */ + private final Map, Set> eventHandlers; + + public MethodEventDispatcher(final Map, Set> eventHandlers) { + this.eventHandlers = eventHandlers; + } + + @Override + public void dispatch(final E event) { + // iterate all registered event handlers and pass the event onto them + for (final EventHandler eventHandler : eventHandlers.getOrDefault( + event.getClass(), Collections.emptySet())) + eventHandler.handle(event); + } +} diff --git a/src/main/java/team/stiff/pomelo/impl/annotated/filter/MethodFilterScanner.java b/src/main/java/team/stiff/pomelo/impl/annotated/filter/MethodFilterScanner.java new file mode 100644 index 0000000..3346c82 --- /dev/null +++ b/src/main/java/team/stiff/pomelo/impl/annotated/filter/MethodFilterScanner.java @@ -0,0 +1,34 @@ +package team.stiff.pomelo.impl.annotated.filter; + +import team.stiff.pomelo.filter.EventFilter; +import team.stiff.pomelo.filter.EventFilterScanner; +import team.stiff.pomelo.impl.annotated.handler.annotation.Listener; + +import java.lang.reflect.Method; +import java.util.HashSet; +import java.util.Set; + +/** + * An implementation of the filter scanner that locates specific + * filters based on annotations and reflection. + * + * @author Daniel + * @since Jun 14, 2017 + */ +public final class MethodFilterScanner implements EventFilterScanner { + + @Override + public Set scan(final Method listener) { + final Set filters = new HashSet<>(); + // iterate all filters in the annotation and instantiate them + for (final Class filter : listener + .getDeclaredAnnotation(Listener.class).filters()) + try { + filters.add(filter.newInstance()); + } catch (final Exception exception) { + exception.printStackTrace(); + } + + return filters; + } +} diff --git a/src/main/java/team/stiff/pomelo/impl/annotated/handler/MethodEventHandler.java b/src/main/java/team/stiff/pomelo/impl/annotated/handler/MethodEventHandler.java new file mode 100644 index 0000000..838437f --- /dev/null +++ b/src/main/java/team/stiff/pomelo/impl/annotated/handler/MethodEventHandler.java @@ -0,0 +1,69 @@ +package team.stiff.pomelo.impl.annotated.handler; + +import team.stiff.pomelo.filter.EventFilter; +import team.stiff.pomelo.handler.EventHandler; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Set; + +/** + * A basic implementation of the {@link EventHandler} used to + * mark a method as an event listener via handle. + * + * @author Daniel + * @since May 31, 2017 + */ +public final class MethodEventHandler implements EventHandler { + /** + * The class instance and parent of the method. + */ + private final Object listenerParent; + + /** + * The method object that has been marked as a listener. + */ + private final Method method; + + /** + * A filter predicate used to test the passed method against + * all registered filters on the handler. + */ + private final Set eventFilters; + + public MethodEventHandler(final Object listenerParent, final Method method, + final Set eventFilters) { + this.listenerParent = listenerParent; + if (!method.isAccessible()) + method.setAccessible(true); + + this.method = method; + this.eventFilters = eventFilters; + } + + @Override + @SuppressWarnings("unchecked") + public void handle(final E event) { + // iterate all event filters given to the handler + for (final EventFilter filter : eventFilters) + if (!filter.test(this, event)) + return; + + try { + // invoke the listener with the current event + method.invoke(listenerParent, event); + } catch (final IllegalAccessException | InvocationTargetException exception) { + exception.printStackTrace(); + } + } + + @Override + public Object getListener() { + return method; + } + + @Override + public Iterable getFilters() { + return eventFilters; + } +} diff --git a/src/main/java/team/stiff/pomelo/impl/annotated/handler/annotation/Listener.java b/src/main/java/team/stiff/pomelo/impl/annotated/handler/annotation/Listener.java new file mode 100644 index 0000000..2ea17de --- /dev/null +++ b/src/main/java/team/stiff/pomelo/impl/annotated/handler/annotation/Listener.java @@ -0,0 +1,29 @@ +package team.stiff.pomelo.impl.annotated.handler.annotation; + +import team.stiff.pomelo.filter.EventFilter; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Annotation to denote that the method being marked + * is a listener for event dispatching. + * + * @author Daniel + * @since May 31, 2017 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface Listener { + + /** + * An array of class filters that will be used to + * determine if an event listener should be dispatched + * or not. + * + * @return array of filters + */ + Class[] filters() default { }; +} diff --git a/src/main/java/team/stiff/pomelo/impl/annotated/handler/scan/MethodHandlerScanner.java b/src/main/java/team/stiff/pomelo/impl/annotated/handler/scan/MethodHandlerScanner.java new file mode 100644 index 0000000..d5452be --- /dev/null +++ b/src/main/java/team/stiff/pomelo/impl/annotated/handler/scan/MethodHandlerScanner.java @@ -0,0 +1,41 @@ +package team.stiff.pomelo.impl.annotated.handler.scan; + +import team.stiff.pomelo.filter.EventFilterScanner; +import team.stiff.pomelo.handler.EventHandler; +import team.stiff.pomelo.handler.scan.EventHandlerScanner; +import team.stiff.pomelo.impl.annotated.filter.MethodFilterScanner; +import team.stiff.pomelo.impl.annotated.handler.MethodEventHandler; +import team.stiff.pomelo.impl.annotated.handler.annotation.Listener; + +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.stream.Stream; + +/** + * An implementation of {@link EventHandlerScanner} that locates + * all methods of a class that are event listeners. + * + * @author Daniel + * @since May 31, 2017 + */ +public final class MethodHandlerScanner implements EventHandlerScanner { + private final EventFilterScanner filterScanner = new MethodFilterScanner(); + + @Override + public Map, Set> locate(final Object listenerContainer) { + final Map, Set> eventHandlers = new HashMap<>(); + + // todo; this could totally be faster right? + Stream.of(listenerContainer.getClass().getDeclaredMethods()) + .filter(method -> method.isAnnotationPresent(Listener.class)) + .filter(method -> method.getParameterCount() == 1) + .forEach(method -> eventHandlers + .computeIfAbsent(method.getParameterTypes()[0], obj -> new HashSet<>()) + .add(new MethodEventHandler(listenerContainer, method, + filterScanner.scan(method)))); + return eventHandlers; + } +} diff --git a/src/main/resources/mcmod.info b/src/main/resources/mcmod.info new file mode 100644 index 0000000..7f2f84a --- /dev/null +++ b/src/main/resources/mcmod.info @@ -0,0 +1,16 @@ +[ +{ + "modid": "seppukumod", + "name": "Seppuku", + "description": "Seppuku is a hacked client built on forge", + "version": "${version}", + "mcversion": "${mcversion}", + "url": "http://seppuku.pw", + "updateUrl": "http://seppuku.pw", + "authorList": ["Riga"], + "credits": "Riga, Dan, Noil, D3x, TheCyberBrick, Hal", + "logoFile": "", + "screenshots": [], + "dependencies": [] +} +] diff --git a/src/main/resources/pack.mcmeta b/src/main/resources/pack.mcmeta new file mode 100644 index 0000000..4018267 --- /dev/null +++ b/src/main/resources/pack.mcmeta @@ -0,0 +1,7 @@ +{ + "pack": { + "description": "examplemod resources", + "pack_format": 3, + "_comment": "A pack_format of 3 should be used starting with Minecraft 1.11. All resources, including language files, should be lowercase (eg: en_us.lang). A pack_format of 2 will load your mod resources with LegacyV2Adapter, which requires language files to have uppercase letters (eg: en_US.lang)." + } +} diff --git a/src/main/resources/seppuku_at.cfg b/src/main/resources/seppuku_at.cfg new file mode 100644 index 0000000..3529c58 --- /dev/null +++ b/src/main/resources/seppuku_at.cfg @@ -0,0 +1,116 @@ +public net.minecraft.network.play.client.CPacketCloseWindow field_149556_a + #windowId + public-f net.minecraft.entity.EntityLivingBase field_110157_c + #x + public net.minecraft.network.play.client.CPacketPlayer field_149479_a + #y + public net.minecraft.network.play.client.CPacketPlayer field_149477_b + #z + public net.minecraft.network.play.client.CPacketPlayer field_149478_c + #yaw + public net.minecraft.network.play.client.CPacketPlayer field_149476_e + #pitch + public net.minecraft.network.play.client.CPacketPlayer field_149473_f + #onGround + public net.minecraft.network.play.client.CPacketPlayer field_149474_g + #ip + public net.minecraft.network.handshake.client.C00Handshake field_149598_b + #port + public net.minecraft.network.handshake.client.C00Handshake field_149599_c + #flying + public net.minecraft.network.play.client.CPacketPlayerAbilities field_149498_b + #flySpeed + public net.minecraft.network.play.client.CPacketPlayerAbilities field_149497_e + #profile + public net.minecraft.network.login.client.CPacketLoginStart field_149305_a + #session + public-f net.minecraft.client.Minecraft field_71449_j + #timer + public-f net.minecraft.client.Minecraft field_71428_T + #rightClickDelayTimer + public net.minecraft.client.Minecraft field_71467_ac + #curBlockDamageMP + public net.minecraft.client.multiplayer.PlayerControllerMP field_78770_f + #blockHitDelay + public net.minecraft.client.multiplayer.PlayerControllerMP field_78781_i + #motionX + public net.minecraft.network.play.server.SPacketEntityVelocity field_149415_b + #motionY + public net.minecraft.network.play.server.SPacketEntityVelocity field_149416_c + #motionZ + public net.minecraft.network.play.server.SPacketEntityVelocity field_149414_d + #isHittingBlock + public net.minecraft.client.multiplayer.PlayerControllerMP field_78778_j + #lines + public net.minecraft.network.play.client.CPacketUpdateSign field_149590_d + #x + public net.minecraft.network.play.client.CPacketVehicleMove field_187007_a + #y + public net.minecraft.network.play.client.CPacketVehicleMove field_187008_b + #z + public net.minecraft.network.play.client.CPacketVehicleMove field_187009_c + #yaw + public net.minecraft.network.play.client.CPacketVehicleMove field_187010_d + #pitch + public net.minecraft.network.play.client.CPacketVehicleMove field_187011_e + #horseJumpPower + public net.minecraft.client.entity.EntityPlayerSP field_110321_bQ + #horseJumpPowerCounter + public net.minecraft.client.entity.EntityPlayerSP field_110320_a + #auxData + public net.minecraft.network.play.client.CPacketEntityAction field_149516_c + #yaw + public net.minecraft.network.play.server.SPacketPlayerPosLook field_148936_d + #pitch + public net.minecraft.network.play.server.SPacketPlayerPosLook field_148937_e + #pressed + public net.minecraft.client.settings.KeyBinding field_74513_e + #hand + public net.minecraft.network.play.client.CPacketPlayerTryUseItem field_187029_a + #data + public net.minecraft.network.play.client.CPacketCustomPayload field_149561_c + #entityId + public net.minecraft.network.play.client.CPacketUseEntity field_149567_a + #hand + public net.minecraft.network.play.client.CPacketUseEntity field_186995_d + #hitVec + public net.minecraft.network.play.client.CPacketUseEntity field_179713_c + #action + public net.minecraft.network.play.client.CPacketUseEntity field_149566_b + public net.minecraft.entity.Entity func_70052_a(IZ)V + #setFlag + public net.minecraft.entity.Entity func_70083_f(I)Z + #getFlag + public net.minecraft.network.play.client.CPacketClientSettings field_149528_b + #view + public net.minecraft.util.Timer field_194149_e + #tickLength + public net.minecraft.network.play.server.SPacketExplosion field_149152_f #motionX + public net.minecraft.network.play.server.SPacketExplosion field_149153_g #motionY + public net.minecraft.network.play.server.SPacketExplosion field_149159_h #motionZ + public net.minecraft.entity.Entity field_71087_bX #inPortal + public net.minecraft.client.renderer.EntityRenderer func_78479_a(FI)V # setupCameraTransform + public net.minecraft.network.play.client.CPacketKeepAlive field_149461_a # key + public net.minecraft.network.play.client.CPacketTabComplete field_149420_a # message + public net.minecraft.entity.Entity field_70134_J # isInWeb + public net.minecraft.network.play.client.CPacketChatMessage field_149440_a # message + public net.minecraft.network.play.client.CPacketPlayerTryUseItemOnBlock field_179725_b # position + public net.minecraft.network.play.client.CPacketPlayerTryUseItemOnBlock field_149579_d # placedBlockDirection + public net.minecraft.network.play.client.CPacketPlayerTryUseItemOnBlock field_187027_c # hand + public net.minecraft.network.play.client.CPacketPlayerTryUseItemOnBlock field_149577_f # facingX + public net.minecraft.network.play.client.CPacketPlayerTryUseItemOnBlock field_149578_g # facingY + public net.minecraft.network.play.client.CPacketPlayerTryUseItemOnBlock field_149584_h # facingZ + public net.minecraft.client.renderer.entity.RenderManager field_78725_b # renderPosX + public net.minecraft.client.renderer.entity.RenderManager field_78726_c # renderPosY + public net.minecraft.client.renderer.entity.RenderManager field_78723_d # renderPosZ + public net.minecraft.client.renderer.EntityRenderer func_78467_g(F)V # orientCamera + public net.minecraft.network.play.client.CPacketPlayerDigging field_179717_a # position + public net.minecraft.network.play.client.CPacketPlayerDigging field_179716_b # facing + public net.minecraft.network.play.client.CPacketPlayerDigging field_149508_e # action + public net.minecraft.network.play.server.SPacketChat field_148919_a # chatComponent + public net.minecraft.client.gui.inventory.GuiEditSign field_146848_f # tileSign + public-f net.minecraft.tileentity.TileEntitySign field_145915_a # signText + public net.minecraft.client.entity.AbstractClientPlayer func_175155_b()Lnet/minecraft/client/network/NetworkPlayerInfo; # getPlayerInfo + public-f net.minecraft.util.text.TextComponentString field_150267_b # text + #smallshield stuff + public net.minecraft.client.renderer.ItemRenderer field_187471_h # equippedProgressOffHand \ No newline at end of file