mirror of https://github.com/kami-blue/client
Merge remote-tracking branch 'upstream/master' into enhancement/Utils
This commit is contained in:
commit
73aa624402
|
@ -1 +1 @@
|
|||
Subproject commit 1daa452960100da342d09903f46c1ffc02d72963
|
||||
Subproject commit d7d5e820e08ba859188c3bb33671544883afa513
|
|
@ -1 +1 @@
|
|||
Subproject commit 0ad2b06b687679a658995f20e0d79bf8c12c7af1
|
||||
Subproject commit 9ed896374539caff7a09e1eb403ffc3f8abc7ec5
|
|
@ -1 +1 @@
|
|||
Subproject commit 46b7f83e9efd03e526db36ffd44b4e5e3c5baa69
|
||||
Subproject commit 6c1f2700355308942c8851e9103d8122e08be5da
|
|
@ -22,6 +22,6 @@ public class MixinStateImplementation {
|
|||
|
||||
@Inject(method = "addCollisionBoxToList", at = @At("HEAD"), cancellable = true)
|
||||
public void addCollisionBoxToList(World worldIn, BlockPos pos, AxisAlignedBB entityBox, List<AxisAlignedBB> collidingBoxes, Entity entityIn, boolean isActualState, CallbackInfo ci) {
|
||||
Jesus.handleAddCollisionBoxToList(pos, block, entityIn, entityBox, collidingBoxes);
|
||||
Jesus.handleAddCollisionBoxToList(pos, block, entityIn, collidingBoxes);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
package org.kamiblue.client.mixin.client.render;
|
||||
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import org.kamiblue.client.util.graphics.GlStateUtils;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(GlStateManager.class)
|
||||
public class MixinGlStateManager {
|
||||
|
||||
@Inject(method = "color(FFF)V", at = @At("HEAD"), cancellable = true)
|
||||
private static void color3f(float colorRed, float colorGreen, float colorBlue, CallbackInfo ci) {
|
||||
if (GlStateUtils.getColorLock()) ci.cancel();
|
||||
}
|
||||
|
||||
@Inject(method = "color(FFFF)V", at = @At("HEAD"), cancellable = true)
|
||||
private static void color4f(float colorRed, float colorGreen, float colorBlue, float colorAlpha, CallbackInfo ci) {
|
||||
if (GlStateUtils.getColorLock()) ci.cancel();
|
||||
}
|
||||
|
||||
@Inject(method = "loadIdentity", at = @At("HEAD"))
|
||||
private static void loadIdentity(CallbackInfo ci) {
|
||||
GlStateUtils.colorLock(false);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,56 +1,20 @@
|
|||
package org.kamiblue.client.mixin.client.render;
|
||||
|
||||
import net.minecraft.client.renderer.GLAllocation;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.client.renderer.entity.layers.LayerArmorBase;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.inventory.EntityEquipmentSlot;
|
||||
import org.kamiblue.client.module.modules.render.ArmorHide;
|
||||
import org.kamiblue.client.util.graphics.GlStateUtils;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.nio.FloatBuffer;
|
||||
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
|
||||
@Mixin(LayerArmorBase.class)
|
||||
public abstract class MixinLayerArmorBase {
|
||||
|
||||
private static final FloatBuffer color = GLAllocation.createDirectFloatBuffer(16);
|
||||
private static boolean texture2d = false;
|
||||
private static boolean colorLock = false;
|
||||
|
||||
@Inject(method = "renderArmorLayer", at = @At("HEAD"), cancellable = true)
|
||||
public void renderArmorLayerPre(EntityLivingBase entityLivingBaseIn, float limbSwing, float limbSwingAmount, float partialTicks, float ageInTicks, float netHeadYaw, float headPitch, float scale, EntityEquipmentSlot slotIn, CallbackInfo ci) {
|
||||
if (ArmorHide.INSTANCE.isEnabled() && ArmorHide.shouldHide(slotIn, entityLivingBaseIn)) {
|
||||
ci.cancel();
|
||||
}
|
||||
|
||||
if (!ci.isCancelled()) {
|
||||
colorLock = GlStateUtils.getColorLock();
|
||||
texture2d = glGetBoolean(GL_TEXTURE_2D);
|
||||
if (colorLock) {
|
||||
glGetFloat(GL_CURRENT_COLOR, color);
|
||||
GlStateUtils.colorLock(false);
|
||||
}
|
||||
if (!texture2d) {
|
||||
GlStateManager.enableTexture2D();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "renderArmorLayer", at = @At("RETURN"))
|
||||
public void renderArmorLayerPost(EntityLivingBase entityLivingBaseIn, float limbSwing, float limbSwingAmount, float partialTicks, float ageInTicks, float netHeadYaw, float headPitch, float scale, EntityEquipmentSlot slotIn, CallbackInfo ci) {
|
||||
if (colorLock) {
|
||||
GlStateManager.color(color.get(0), color.get(1), color.get(2), color.get(3));
|
||||
GlStateUtils.colorLock(true);
|
||||
}
|
||||
if (!texture2d) {
|
||||
GlStateManager.disableTexture2D();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
package org.kamiblue.client.mixin.client.render;
|
||||
|
||||
import net.minecraft.client.renderer.GLAllocation;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.client.renderer.block.model.ItemCameraTransforms;
|
||||
import net.minecraft.client.renderer.entity.layers.LayerHeldItem;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.EnumHandSide;
|
||||
import org.kamiblue.client.util.graphics.GlStateUtils;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.nio.FloatBuffer;
|
||||
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
|
||||
@Mixin(LayerHeldItem.class)
|
||||
public abstract class MixinLayerHeldItem {
|
||||
|
||||
private static final FloatBuffer color = GLAllocation.createDirectFloatBuffer(16);
|
||||
private static boolean texture2d = false;
|
||||
private static boolean colorLock = false;
|
||||
|
||||
@Inject(method = "renderHeldItem", at = @At("HEAD"))
|
||||
public void renderHeldItemPre(EntityLivingBase entity, ItemStack itemStack, ItemCameraTransforms.TransformType transformType, EnumHandSide handSide, CallbackInfo ci) {
|
||||
colorLock = GlStateUtils.getColorLock();
|
||||
texture2d = glGetBoolean(GL_TEXTURE_2D);
|
||||
if (colorLock) {
|
||||
glGetFloat(GL_CURRENT_COLOR, color);
|
||||
GlStateUtils.colorLock(false);
|
||||
}
|
||||
if (!texture2d) {
|
||||
GlStateManager.enableTexture2D();
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "renderHeldItem", at = @At("RETURN"))
|
||||
public void renderHeldItemPost(EntityLivingBase entity, ItemStack itemStack, ItemCameraTransforms.TransformType transformType, EnumHandSide handSide, CallbackInfo ci) {
|
||||
if (colorLock) {
|
||||
GlStateManager.color(color.get(0), color.get(1), color.get(2), color.get(3));
|
||||
GlStateUtils.colorLock(true);
|
||||
}
|
||||
if (!texture2d) {
|
||||
GlStateManager.disableTexture2D();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,66 +1,19 @@
|
|||
package org.kamiblue.client.mixin.client.render;
|
||||
|
||||
import net.minecraft.client.renderer.GLAllocation;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.client.renderer.entity.Render;
|
||||
import net.minecraft.entity.Entity;
|
||||
import org.kamiblue.client.module.modules.render.ESP;
|
||||
import org.kamiblue.client.module.modules.render.Nametags;
|
||||
import org.kamiblue.client.util.Wrapper;
|
||||
import org.kamiblue.client.util.graphics.GlStateUtils;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.nio.FloatBuffer;
|
||||
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
|
||||
@Mixin(Render.class)
|
||||
abstract class MixinRender<T extends Entity> {
|
||||
|
||||
private static final FloatBuffer color = GLAllocation.createDirectFloatBuffer(16);
|
||||
private static boolean texture2d = false;
|
||||
private static boolean colorLock = false;
|
||||
|
||||
@Inject(method = "renderLivingLabel", at = @At("HEAD"), cancellable = true)
|
||||
protected void renderNamePre(T entityIn, String str, double x, double y, double z, int maxDistance, CallbackInfo ci) {
|
||||
if (Nametags.INSTANCE.isEnabled() && Nametags.INSTANCE.checkEntityType(entityIn)) {
|
||||
ci.cancel();
|
||||
} else if (ESP.INSTANCE.isEnabled() && ESP.INSTANCE.getDrawingOutline()) {
|
||||
if (ESP.INSTANCE.getDrawNametag()) {
|
||||
Wrapper.getMinecraft().getFramebuffer().bindFramebuffer(false);
|
||||
} else {
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
if (!ci.isCancelled()) {
|
||||
colorLock = GlStateUtils.getColorLock();
|
||||
texture2d = glGetBoolean(GL_TEXTURE_2D);
|
||||
if (colorLock) {
|
||||
glGetFloat(GL_CURRENT_COLOR, color);
|
||||
GlStateUtils.colorLock(false);
|
||||
}
|
||||
if (!texture2d) {
|
||||
GlStateManager.enableTexture2D();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "renderLivingLabel", at = @At("RETURN"))
|
||||
protected void renderNamePost(T entityIn, String str, double x, double y, double z, int maxDistance, CallbackInfo ci) {
|
||||
if (ESP.INSTANCE.isEnabled() && ESP.INSTANCE.getDrawingOutline() && ESP.INSTANCE.getFrameBuffer() != null) {
|
||||
ESP.INSTANCE.getFrameBuffer().bindFramebuffer(false);
|
||||
}
|
||||
|
||||
if (colorLock) {
|
||||
GlStateManager.color(color.get(0), color.get(1), color.get(2), color.get(3));
|
||||
GlStateUtils.colorLock(true);
|
||||
}
|
||||
if (!texture2d) {
|
||||
GlStateManager.disableTexture2D();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,36 +1,24 @@
|
|||
package org.kamiblue.client.mixin.client.render;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.entity.EntityPlayerSP;
|
||||
import net.minecraft.client.renderer.RenderGlobal;
|
||||
import net.minecraft.client.renderer.ViewFrustum;
|
||||
import net.minecraft.client.renderer.chunk.RenderChunk;
|
||||
import net.minecraft.client.renderer.culling.ICamera;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.RayTraceResult;
|
||||
import org.kamiblue.client.event.KamiEventBus;
|
||||
import org.kamiblue.client.event.events.BlockBreakEvent;
|
||||
import org.kamiblue.client.mixin.client.accessor.render.AccessorViewFrustum;
|
||||
import org.kamiblue.client.event.events.RenderEntityEvent;
|
||||
import org.kamiblue.client.module.modules.player.Freecam;
|
||||
import org.kamiblue.client.module.modules.render.SelectionHighlight;
|
||||
import org.kamiblue.client.util.Wrapper;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
import org.spongepowered.asm.mixin.injection.ModifyVariable;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(RenderGlobal.class)
|
||||
public abstract class MixinRenderGlobal {
|
||||
|
||||
@Shadow private int renderDistanceChunks;
|
||||
@Shadow private ViewFrustum viewFrustum;
|
||||
|
||||
private final Minecraft mc = Minecraft.getMinecraft();
|
||||
|
||||
@Inject(method = "drawSelectionBox", at = @At("HEAD"), cancellable = true)
|
||||
public void drawSelectionBox(EntityPlayer player, RayTraceResult movingObjectPositionIn, int execute, float partialTicks, CallbackInfo ci) {
|
||||
if (SelectionHighlight.INSTANCE.isEnabled() && SelectionHighlight.INSTANCE.getBlock().getValue()) {
|
||||
|
@ -44,38 +32,22 @@ public abstract class MixinRenderGlobal {
|
|||
KamiEventBus.INSTANCE.post(event);
|
||||
}
|
||||
|
||||
// Can't use @ModifyVariable here because it crashes outside of a dev env with Optifine
|
||||
@Redirect(method = "setupTerrain", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/RenderGlobal;getRenderChunkOffset(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/client/renderer/chunk/RenderChunk;Lnet/minecraft/util/EnumFacing;)Lnet/minecraft/client/renderer/chunk/RenderChunk;"))
|
||||
public RenderChunk renderChunkOffset(RenderGlobal renderGlobal, BlockPos playerPos, RenderChunk renderChunkBase, EnumFacing facing) {
|
||||
@Inject(method = "renderEntities", at = @At("HEAD"))
|
||||
public void renderEntitiesHead(Entity renderViewEntity, ICamera camera, float partialTicks, CallbackInfo ci) {
|
||||
RenderEntityEvent.setRenderingEntities(true);
|
||||
}
|
||||
|
||||
@Inject(method = "renderEntities", at = @At("RETURN"))
|
||||
public void renderEntitiesReturn(Entity renderViewEntity, ICamera camera, float partialTicks, CallbackInfo ci) {
|
||||
RenderEntityEvent.setRenderingEntities(false);
|
||||
}
|
||||
|
||||
@ModifyVariable(method = "setupTerrain", at = @At(value = "STORE", ordinal = 0), ordinal = 1)
|
||||
public BlockPos setupTerrainStoreFlooredChunkPosition(BlockPos playerPos) {
|
||||
if (Freecam.INSTANCE.isEnabled()) {
|
||||
playerPos = Freecam.getRenderChunkOffset(playerPos);
|
||||
}
|
||||
|
||||
// Can't use a @Shadow of getRenderChunkOffset because it crashes outside of a dev env with Optifine
|
||||
BlockPos blockpos = renderChunkBase.getBlockPosOffset16(facing);
|
||||
|
||||
if (MathHelper.abs(playerPos.getX() - blockpos.getX()) > this.renderDistanceChunks * 16) {
|
||||
return null;
|
||||
} else if (blockpos.getY() >= 0 && blockpos.getY() < 256) {
|
||||
return MathHelper.abs(playerPos.getZ() - blockpos.getZ()) > this.renderDistanceChunks * 16 ? null : ((AccessorViewFrustum) this.viewFrustum).invokeGetRenderChunk(blockpos);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* updateChunkPositions loadRenderers as well, but as long as you don't change your renderDistance in Freecam loadRenderers won't be called
|
||||
* One could add the same redirect for loadRenderers if needed
|
||||
*/
|
||||
@Redirect(method = "setupTerrain", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/ViewFrustum;updateChunkPositions(DD)V"))
|
||||
public void updateSetupTerrain(ViewFrustum viewFrustum, double viewEntityX, double viewEntityZ) {
|
||||
EntityPlayerSP player = Wrapper.getPlayer();
|
||||
|
||||
if (Freecam.INSTANCE.isEnabled() && player != null) {
|
||||
viewEntityX = player.posX;
|
||||
viewEntityZ = player.posZ;
|
||||
}
|
||||
|
||||
viewFrustum.updateChunkPositions(viewEntityX, viewEntityZ);
|
||||
return playerPos;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
package org.kamiblue.client.mixin.client.render;
|
||||
|
||||
import net.minecraft.client.renderer.entity.RenderLivingBase;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import org.kamiblue.client.event.KamiEventBus;
|
||||
import org.kamiblue.client.event.Phase;
|
||||
import org.kamiblue.client.event.events.RenderEntityEvent;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(value = RenderLivingBase.class, priority = 114514)
|
||||
public class MixinRenderLivingBase<T extends EntityLivingBase> {
|
||||
@Inject(method = "renderModel", at = @At("HEAD"), cancellable = true)
|
||||
public void renderModelHead(T entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scaleFactor, CallbackInfo ci) {
|
||||
if (entity == null || !RenderEntityEvent.getRenderingEntities()) return;
|
||||
|
||||
RenderEntityEvent eventModel = new RenderEntityEvent.Model(entity, Phase.PRE);
|
||||
KamiEventBus.INSTANCE.post(eventModel);
|
||||
}
|
||||
|
||||
@Inject(method = "renderModel", at = @At("RETURN"), cancellable = true)
|
||||
public void renderEntityReturn(T entity, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scaleFactor, CallbackInfo ci) {
|
||||
if (entity == null || !RenderEntityEvent.getRenderingEntities()) return;
|
||||
|
||||
RenderEntityEvent eventModel = new RenderEntityEvent.Model(entity, Phase.POST);
|
||||
KamiEventBus.INSTANCE.post(eventModel);
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@ package org.kamiblue.client.mixin.client.render;
|
|||
|
||||
import net.minecraft.client.renderer.entity.RenderManager;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import org.kamiblue.client.event.KamiEventBus;
|
||||
import org.kamiblue.client.event.Phase;
|
||||
import org.kamiblue.client.event.events.RenderEntityEvent;
|
||||
|
@ -14,27 +15,36 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|||
public class MixinRenderManager {
|
||||
@Inject(method = "renderEntity", at = @At("HEAD"), cancellable = true)
|
||||
public void renderEntityPre(Entity entity, double x, double y, double z, float yaw, float partialTicks, boolean debug, CallbackInfo ci) {
|
||||
if (entity == null) return;
|
||||
if (entity == null || !RenderEntityEvent.getRenderingEntities()) return;
|
||||
|
||||
RenderEntityEvent event = new RenderEntityEvent(entity, x, y, z, yaw, partialTicks, Phase.PRE);
|
||||
KamiEventBus.INSTANCE.post(event);
|
||||
RenderEntityEvent eventAll = new RenderEntityEvent.All(entity, Phase.PRE);
|
||||
KamiEventBus.INSTANCE.post(eventAll);
|
||||
if (eventAll.getCancelled()) ci.cancel();
|
||||
|
||||
if (event.getCancelled()) ci.cancel();
|
||||
if (!(entity instanceof EntityLivingBase)) {
|
||||
RenderEntityEvent eventModel = new RenderEntityEvent.Model(entity, Phase.PRE);
|
||||
KamiEventBus.INSTANCE.post(eventModel);
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "renderEntity", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/entity/Render;doRender(Lnet/minecraft/entity/Entity;DDDFF)V", shift = At.Shift.AFTER))
|
||||
public void renderEntityPeri(Entity entity, double x, double y, double z, float yaw, float partialTicks, boolean debug, CallbackInfo ci) {
|
||||
if (entity == null) return;
|
||||
if (entity == null || !RenderEntityEvent.getRenderingEntities()) return;
|
||||
|
||||
RenderEntityEvent event = new RenderEntityEvent(entity, x, y, z, yaw, partialTicks, Phase.PERI);
|
||||
RenderEntityEvent event = new RenderEntityEvent.All(entity, Phase.PERI);
|
||||
KamiEventBus.INSTANCE.post(event);
|
||||
|
||||
if (!(entity instanceof EntityLivingBase)) {
|
||||
RenderEntityEvent eventModel = new RenderEntityEvent.Model(entity, Phase.POST);
|
||||
KamiEventBus.INSTANCE.post(eventModel);
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "renderEntity", at = @At("RETURN"))
|
||||
public void renderEntityPost(Entity entity, double x, double y, double z, float yaw, float partialTicks, boolean debug, CallbackInfo ci) {
|
||||
if (entity == null) return;
|
||||
if (entity == null || !RenderEntityEvent.getRenderingEntities()) return;
|
||||
|
||||
RenderEntityEvent event = new RenderEntityEvent(entity, x, y, z, yaw, partialTicks, Phase.POST);
|
||||
RenderEntityEvent event = new RenderEntityEvent.All(entity, Phase.POST);
|
||||
KamiEventBus.INSTANCE.post(event);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,25 +1,29 @@
|
|||
package org.kamiblue.client.mixin.client.render;
|
||||
|
||||
import net.minecraft.client.entity.AbstractClientPlayer;
|
||||
import net.minecraft.client.model.ModelBase;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.client.renderer.entity.RenderLivingBase;
|
||||
import net.minecraft.client.renderer.entity.RenderManager;
|
||||
import net.minecraft.client.renderer.entity.RenderPlayer;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import org.kamiblue.client.module.modules.movement.ElytraFlight;
|
||||
import org.kamiblue.client.module.modules.player.Freecam;
|
||||
import org.kamiblue.client.util.Wrapper;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
/**
|
||||
* Created by 086 on 19/12/2017.
|
||||
*/
|
||||
@Mixin(RenderPlayer.class)
|
||||
public class MixinRenderPlayer {
|
||||
public abstract class MixinRenderPlayer extends RenderLivingBase<AbstractClientPlayer> {
|
||||
|
||||
public MixinRenderPlayer(RenderManager renderManagerIn, ModelBase modelBaseIn, float shadowSizeIn) {
|
||||
super(renderManagerIn, modelBaseIn, shadowSizeIn);
|
||||
}
|
||||
|
||||
@Shadow protected abstract void setModelVisibilities(AbstractClientPlayer clientPlayer);
|
||||
|
||||
@Inject(method = "applyRotations", at = @At("RETURN"))
|
||||
protected void applyRotations(AbstractClientPlayer entityLiving, float ageInTicks, float rotationYaw, float partialTicks, CallbackInfo ci) {
|
||||
|
@ -36,9 +40,20 @@ public class MixinRenderPlayer {
|
|||
}
|
||||
}
|
||||
|
||||
// Redirect it to the original player so the original player can be renderer correctly
|
||||
@Redirect(method = "doRender", at = @At(value = "FIELD", target = "Lnet/minecraft/client/renderer/entity/RenderManager;renderViewEntity:Lnet/minecraft/entity/Entity;", opcode = Opcodes.GETFIELD))
|
||||
public Entity getRenderViewEntity(RenderManager renderManager) {
|
||||
return Wrapper.getPlayer();
|
||||
// Force it to render the original player in Freecam
|
||||
@Inject(method = "doRender", at = @At(value = "FIELD", target = "Lnet/minecraft/client/renderer/entity/RenderManager;renderViewEntity:Lnet/minecraft/entity/Entity;"))
|
||||
public void doRenderGetRenderViewEntity(AbstractClientPlayer entity, double x, double y, double z, float entityYaw, float partialTicks, CallbackInfo ci) {
|
||||
if (Freecam.INSTANCE.isEnabled() && Wrapper.getMinecraft().getRenderViewEntity() != entity) {
|
||||
double renderY = y;
|
||||
|
||||
if (entity.isSneaking()) {
|
||||
renderY = y - 0.125D;
|
||||
}
|
||||
|
||||
this.setModelVisibilities(entity);
|
||||
GlStateManager.enableBlendProfile(GlStateManager.Profile.PLAYER_SKIN);
|
||||
super.doRender(entity, x, renderY, z, entityYaw, partialTicks);
|
||||
GlStateManager.disableBlendProfile(GlStateManager.Profile.PLAYER_SKIN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
package org.kamiblue.client.mixin.client.render;
|
||||
|
||||
import net.minecraft.client.entity.EntityPlayerSP;
|
||||
import net.minecraft.client.renderer.ViewFrustum;
|
||||
import net.minecraft.client.renderer.chunk.RenderChunk;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import org.kamiblue.client.module.modules.player.Freecam;
|
||||
import org.kamiblue.client.util.Wrapper;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
// TODO: Find a working fix of this for optifine
|
||||
@Mixin(ViewFrustum.class)
|
||||
public abstract class MixinViewFrustum {
|
||||
@Shadow public RenderChunk[] renderChunks;
|
||||
@Shadow protected int countChunksX;
|
||||
@Shadow protected int countChunksY;
|
||||
@Shadow protected int countChunksZ;
|
||||
|
||||
@Shadow protected abstract int getBaseCoordinate(int p_178157_1_, int p_178157_2_, int p_178157_3_);
|
||||
|
||||
@Inject(method = "updateChunkPositions", at = @At("HEAD"), cancellable = true)
|
||||
public void updateChunkPositionsHead(double viewEntityX, double viewEntityZ, CallbackInfo ci) {
|
||||
if (Freecam.INSTANCE.isDisabled()) return;
|
||||
|
||||
EntityPlayerSP player = Wrapper.getPlayer();
|
||||
if (player == null) return;
|
||||
|
||||
int centerX = MathHelper.floor(player.posX) - 8;
|
||||
int centerZ = MathHelper.floor(player.posZ) - 8;
|
||||
|
||||
int multipliedCountX = this.countChunksX * 16;
|
||||
|
||||
for (int x = 0; x < this.countChunksX; ++x) {
|
||||
int posX = this.getBaseCoordinate(centerX, multipliedCountX, x);
|
||||
|
||||
for (int z = 0; z < this.countChunksZ; ++z) {
|
||||
int poxZ = this.getBaseCoordinate(centerZ, multipliedCountX, z);
|
||||
|
||||
for (int y = 0; y < this.countChunksY; ++y) {
|
||||
int poxY = y * 16;
|
||||
RenderChunk renderchunk = this.renderChunks[(z * this.countChunksY + y) * this.countChunksX + x];
|
||||
renderchunk.setPosition(posX, poxY, poxZ);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
|
@ -44,6 +44,7 @@ class KamiMod {
|
|||
var ready: Boolean = false; private set
|
||||
}
|
||||
|
||||
@Suppress("UNUSED_PARAMETER")
|
||||
@Mod.EventHandler
|
||||
fun preInit(event: FMLPreInitializationEvent) {
|
||||
val directory = File(DIRECTORY)
|
||||
|
@ -53,6 +54,7 @@ class KamiMod {
|
|||
LoaderWrapper.preLoadAll()
|
||||
}
|
||||
|
||||
@Suppress("UNUSED_PARAMETER")
|
||||
@Mod.EventHandler
|
||||
fun init(event: FMLInitializationEvent) {
|
||||
LOG.info("Initializing $NAME $VERSION")
|
||||
|
@ -69,6 +71,7 @@ class KamiMod {
|
|||
LOG.info("$NAME initialized!")
|
||||
}
|
||||
|
||||
@Suppress("UNUSED_PARAMETER")
|
||||
@Mod.EventHandler
|
||||
fun postInit(event: FMLPostInitializationEvent) {
|
||||
ready = true
|
||||
|
|
|
@ -28,7 +28,7 @@ abstract class ClientCommand(
|
|||
val prefixName get() = "$prefix$name"
|
||||
|
||||
@CommandBuilder
|
||||
protected fun AbstractArg<*>.module(
|
||||
protected inline fun AbstractArg<*>.module(
|
||||
name: String,
|
||||
block: BuilderBlock<AbstractModule>
|
||||
) {
|
||||
|
@ -36,7 +36,7 @@ abstract class ClientCommand(
|
|||
}
|
||||
|
||||
@CommandBuilder
|
||||
protected fun AbstractArg<*>.hudElement(
|
||||
protected inline fun AbstractArg<*>.hudElement(
|
||||
name: String,
|
||||
block: BuilderBlock<HudElement>
|
||||
) {
|
||||
|
@ -44,7 +44,7 @@ abstract class ClientCommand(
|
|||
}
|
||||
|
||||
@CommandBuilder
|
||||
protected fun AbstractArg<*>.block(
|
||||
protected inline fun AbstractArg<*>.block(
|
||||
name: String,
|
||||
block: BuilderBlock<Block>
|
||||
) {
|
||||
|
@ -52,7 +52,7 @@ abstract class ClientCommand(
|
|||
}
|
||||
|
||||
@CommandBuilder
|
||||
protected fun AbstractArg<*>.item(
|
||||
protected inline fun AbstractArg<*>.item(
|
||||
name: String,
|
||||
block: BuilderBlock<Item>
|
||||
) {
|
||||
|
@ -60,7 +60,7 @@ abstract class ClientCommand(
|
|||
}
|
||||
|
||||
@CommandBuilder
|
||||
protected fun AbstractArg<*>.player(
|
||||
protected inline fun AbstractArg<*>.player(
|
||||
name: String,
|
||||
block: BuilderBlock<PlayerProfile>
|
||||
) {
|
||||
|
@ -68,7 +68,7 @@ abstract class ClientCommand(
|
|||
}
|
||||
|
||||
@CommandBuilder
|
||||
protected fun AbstractArg<*>.blockPos(
|
||||
protected inline fun AbstractArg<*>.blockPos(
|
||||
name: String,
|
||||
block: BuilderBlock<BlockPos>
|
||||
) {
|
||||
|
@ -76,7 +76,7 @@ abstract class ClientCommand(
|
|||
}
|
||||
|
||||
@CommandBuilder
|
||||
protected fun AbstractArg<*>.baritoneBlock(
|
||||
protected inline fun AbstractArg<*>.baritoneBlock(
|
||||
name: String,
|
||||
block: BuilderBlock<Block>
|
||||
) {
|
||||
|
@ -84,7 +84,7 @@ abstract class ClientCommand(
|
|||
}
|
||||
|
||||
@CommandBuilder
|
||||
protected fun AbstractArg<*>.schematic(
|
||||
protected inline fun AbstractArg<*>.schematic(
|
||||
name: String,
|
||||
file: BuilderBlock<File>
|
||||
) {
|
||||
|
|
|
@ -76,7 +76,9 @@ object CommandManager : AbstractCommandManager<ClientExecuteEvent>(), AsyncLoade
|
|||
?: throw SubCommandNotFoundException(event.args, command)
|
||||
|
||||
onMainThread {
|
||||
finalArg.invoke(event)
|
||||
runBlocking {
|
||||
finalArg.invoke(event)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,13 +3,8 @@ package org.kamiblue.client.event.events
|
|||
import net.minecraft.entity.Entity
|
||||
import org.kamiblue.client.event.*
|
||||
|
||||
class RenderEntityEvent(
|
||||
sealed class RenderEntityEvent(
|
||||
val entity: Entity,
|
||||
val x: Double,
|
||||
val y: Double,
|
||||
val z: Double,
|
||||
val yaw: Float,
|
||||
val partialTicks: Float,
|
||||
override val phase: Phase
|
||||
) : Event, ICancellable by Cancellable(), IMultiPhase<RenderEntityEvent>, ProfilerEvent {
|
||||
|
||||
|
@ -18,4 +13,13 @@ class RenderEntityEvent(
|
|||
override fun nextPhase(): RenderEntityEvent {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
class All(entity: Entity, phase: Phase) : RenderEntityEvent(entity, phase)
|
||||
|
||||
class Model(entity: Entity, phase: Phase) : RenderEntityEvent(entity, phase)
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
var renderingEntities = false
|
||||
}
|
||||
}
|
|
@ -85,7 +85,7 @@ object PlayerPacketManager : Manager {
|
|||
prevServerSideRotation = serverSideRotation
|
||||
}
|
||||
|
||||
listener<RenderEntityEvent> {
|
||||
listener<RenderEntityEvent.All> {
|
||||
if (it.entity != Wrapper.player || it.entity.isRiding) return@listener
|
||||
|
||||
if (it.phase == Phase.PRE) {
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
package org.kamiblue.client.module.modules.chat
|
||||
|
||||
import net.minecraft.init.Items
|
||||
import net.minecraft.network.play.server.SPacketUpdateHealth
|
||||
import net.minecraft.util.EnumHand
|
||||
import org.kamiblue.client.KamiMod
|
||||
import org.kamiblue.client.event.SafeClientEvent
|
||||
import org.kamiblue.client.event.events.PacketEvent
|
||||
import org.kamiblue.client.module.Category
|
||||
import org.kamiblue.client.module.Module
|
||||
|
@ -66,7 +69,7 @@ internal object AutoExcuse : Module(
|
|||
init {
|
||||
safeListener<PacketEvent.Receive> {
|
||||
if (loadedExcuses.isEmpty() || it.packet !is SPacketUpdateHealth) return@safeListener
|
||||
if (it.packet.health <= 0f && timer.tick(3L)) {
|
||||
if (it.packet.health <= 0.0f && !isHoldingTotem && timer.tick(3L)) {
|
||||
sendServerMessage(getExcuse())
|
||||
}
|
||||
}
|
||||
|
@ -94,5 +97,8 @@ internal object AutoExcuse : Module(
|
|||
}
|
||||
}
|
||||
|
||||
private val SafeClientEvent.isHoldingTotem: Boolean
|
||||
get() = EnumHand.values().any { player.getHeldItem(it).item == Items.TOTEM_OF_UNDYING }
|
||||
|
||||
private fun getExcuse() = loadedExcuses.random().replace(CLIENT_NAME, clients.random())
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ internal object KamiMoji : Module(
|
|||
if (index == -1) continue
|
||||
|
||||
val x = mc.fontRenderer.getStringWidth(text.substring(0, index)) + fontHeight / 4
|
||||
drawEmoji(texture, (posX + x).toDouble(), posY.toDouble(), fontHeight.toFloat(), alpha)
|
||||
drawEmoji(texture, (posX + x).toDouble(), posY.toDouble(), fontHeight.toFloat())
|
||||
}
|
||||
|
||||
text = text.replaceFirst(emojiText, getReplacement(fontHeight))
|
||||
|
@ -70,7 +70,7 @@ internal object KamiMoji : Module(
|
|||
}
|
||||
|
||||
/* This is created because vanilla one doesn't take double position input */
|
||||
private fun drawEmoji(texture: MipmapTexture, x: Double, y: Double, size: Float, alpha: Float) {
|
||||
private fun drawEmoji(texture: MipmapTexture, x: Double, y: Double, size: Float) {
|
||||
val tessellator = Tessellator.getInstance()
|
||||
val bufBuilder = tessellator.buffer
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ package org.kamiblue.client.module.modules.combat
|
|||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraftforge.client.event.ClientChatReceivedEvent
|
||||
import net.minecraftforge.fml.common.gameevent.TickEvent
|
||||
import org.kamiblue.client.event.SafeClientEvent
|
||||
import org.kamiblue.client.event.events.ConnectionEvent
|
||||
import org.kamiblue.client.module.Category
|
||||
import org.kamiblue.client.module.Module
|
||||
|
@ -10,6 +11,7 @@ import org.kamiblue.client.util.TickTimer
|
|||
import org.kamiblue.client.util.TimeUnit
|
||||
import org.kamiblue.client.util.text.MessageSendHelper
|
||||
import org.kamiblue.client.util.text.MessageSendHelper.sendServerMessage
|
||||
import org.kamiblue.client.util.text.formatValue
|
||||
import org.kamiblue.client.util.threads.safeListener
|
||||
import org.kamiblue.commons.extension.synchronized
|
||||
import org.kamiblue.event.listener.listener
|
||||
|
@ -21,24 +23,29 @@ internal object AutoEZ : Module(
|
|||
category = Category.COMBAT,
|
||||
description = "Sends an insult in chat after killing someone"
|
||||
) {
|
||||
private val detectMode = setting("Detect Mode", DetectMode.HEALTH)
|
||||
private val messageMode = setting("Message Mode", MessageMode.ONTOP)
|
||||
private val customText = setting("Custom Text", "unchanged")
|
||||
private const val UNCHANGED = "Unchanged"
|
||||
private const val NAME = "\$NAME"
|
||||
private const val HYPIXEL_MESSAGE = "\$HYPIXEL_MESSAGE"
|
||||
|
||||
private val detectMode by setting("Detect Mode", DetectMode.HEALTH)
|
||||
private val messageMode by setting("Message Mode", MessageMode.ONTOP)
|
||||
private val customText by setting("Custom Text", UNCHANGED, { messageMode == MessageMode.CUSTOM })
|
||||
|
||||
private enum class DetectMode {
|
||||
BROADCAST, HEALTH
|
||||
}
|
||||
|
||||
@Suppress("UNUSED")
|
||||
enum class MessageMode(val text: String) {
|
||||
GG("gg, \$NAME"),
|
||||
ONTOP("KAMI BLUE on top! ez \$NAME"),
|
||||
EZD("You just got ez'd \$NAME"),
|
||||
EZ_HYPIXEL("\$HYPIXEL_MESSAGE \$NAME"),
|
||||
NAENAE("You just got naenae'd by kami blue plus, \$NAME"),
|
||||
private enum class MessageMode(val text: String) {
|
||||
GG("gg, $NAME"),
|
||||
ONTOP("KAMI BLUE on top! ez $NAME"),
|
||||
EZD("You just got ez'd $NAME"),
|
||||
EZ_HYPIXEL("$HYPIXEL_MESSAGE $NAME"),
|
||||
NAENAE("You just got naenae'd by kami blue plus, $NAME"),
|
||||
CUSTOM("");
|
||||
}
|
||||
|
||||
// Got these from the forums, kinda based -humboldt123
|
||||
private val hypixelCensorMessages = arrayOf(
|
||||
"Hey Helper, how play game?",
|
||||
"Hello everyone! I am an innocent player who loves everything Hypixel.",
|
||||
|
@ -85,73 +92,97 @@ internal object AutoEZ : Module(
|
|||
"I need help, teach me how to play!",
|
||||
"What happens if I add chocolate milk to macaroni and cheese?",
|
||||
"Can you paint with all the colors of the wind"
|
||||
) // Got these from the forums, kinda based -humboldt123
|
||||
)
|
||||
|
||||
private val timer = TickTimer(TimeUnit.SECONDS)
|
||||
private val attackedPlayers = LinkedHashMap<EntityPlayer, Int>().synchronized() // <Player, Last Attack Time>
|
||||
private val confirmedKills = Collections.newSetFromMap(WeakHashMap<EntityPlayer, Boolean>()).synchronized()
|
||||
|
||||
init {
|
||||
safeListener<ClientChatReceivedEvent> {
|
||||
if (detectMode.value != DetectMode.BROADCAST || player.isDead || player.health <= 0.0f) return@safeListener
|
||||
onDisable {
|
||||
reset()
|
||||
}
|
||||
|
||||
val message = it.message.unformattedText
|
||||
if (!message.contains(player.name, true)) return@safeListener
|
||||
// Clear the map on disconnect
|
||||
listener<ConnectionEvent.Disconnect> {
|
||||
reset()
|
||||
}
|
||||
|
||||
for (player in attackedPlayers.keys) {
|
||||
if (!message.contains(player.name, true)) continue
|
||||
sendEzMessage(player)
|
||||
break // Break right after removing so we don't get exception
|
||||
safeListener<ClientChatReceivedEvent> { event ->
|
||||
if (detectMode != DetectMode.BROADCAST || !player.isEntityAlive) return@safeListener
|
||||
|
||||
val message = event.message.unformattedText
|
||||
if (!message.contains(player.name)) return@safeListener
|
||||
|
||||
attackedPlayers.keys.find {
|
||||
message.contains(it.name)
|
||||
}?.let {
|
||||
confirmedKills.add(it)
|
||||
}
|
||||
}
|
||||
|
||||
safeListener<TickEvent.ClientTickEvent> { event ->
|
||||
if (event.phase != TickEvent.Phase.END) return@safeListener
|
||||
|
||||
if (player.isDead || player.health <= 0.0f) {
|
||||
attackedPlayers.clear()
|
||||
if (!player.isEntityAlive) {
|
||||
reset()
|
||||
return@safeListener
|
||||
}
|
||||
|
||||
// Update attacked Entity
|
||||
val attacked = player.lastAttackedEntity
|
||||
if (attacked is EntityPlayer && !attacked.isDead && attacked.health > 0.0f) {
|
||||
attackedPlayers[attacked] = player.lastAttackedEntityTime
|
||||
}
|
||||
|
||||
// Remove players if they are out of world or we haven't attack them again in 100 ticks (5 seconds)
|
||||
attackedPlayers.entries.removeIf { !it.key.isAddedToWorld || player.ticksExisted - it.value > 100 }
|
||||
|
||||
// Check death
|
||||
if (detectMode.value == DetectMode.HEALTH) {
|
||||
for (player in attackedPlayers.keys) {
|
||||
if (!player.isDead && player.health > 0.0f) continue
|
||||
sendEzMessage(player)
|
||||
break // Break right after removing so we don't get exception
|
||||
}
|
||||
}
|
||||
|
||||
// Send custom message type help message
|
||||
updateAttackedPlayer()
|
||||
removeInvalidPlayers()
|
||||
sendEzMessage()
|
||||
sendHelpMessage()
|
||||
}
|
||||
}
|
||||
|
||||
// Clear the map on disconnect
|
||||
listener<ConnectionEvent.Disconnect> {
|
||||
attackedPlayers.clear()
|
||||
private fun SafeClientEvent.updateAttackedPlayer() {
|
||||
val attacked = player.lastAttackedEntity
|
||||
if (attacked is EntityPlayer && attacked.isEntityAlive) {
|
||||
attackedPlayers[attacked] = player.lastAttackedEntityTime
|
||||
}
|
||||
}
|
||||
|
||||
private fun SafeClientEvent.removeInvalidPlayers() {
|
||||
val removeTime = player.ticksExisted - 100L
|
||||
|
||||
// Remove players if they are offline or we haven't attack them again in 100 ticks (5 seconds)
|
||||
attackedPlayers.entries.removeIf {
|
||||
@Suppress("SENSELESS_COMPARISON")
|
||||
it.value < removeTime || connection.getPlayerInfo(it.key.uniqueID) == null
|
||||
}
|
||||
}
|
||||
|
||||
private fun sendEzMessage() {
|
||||
// Check death and confirmation
|
||||
attackedPlayers.keys.find {
|
||||
!it.isEntityAlive && (detectMode == DetectMode.HEALTH || confirmedKills.contains(it))
|
||||
}?.let {
|
||||
attackedPlayers.remove(it)
|
||||
confirmedKills.remove(it)
|
||||
|
||||
val originalText = if (messageMode == MessageMode.CUSTOM) customText else messageMode.text
|
||||
var replaced = originalText.replace(NAME, it.name)
|
||||
if (messageMode == MessageMode.EZ_HYPIXEL) {
|
||||
replaced = replaced.replace(HYPIXEL_MESSAGE, hypixelCensorMessages.random())
|
||||
}
|
||||
|
||||
sendServerMessage(replaced)
|
||||
}
|
||||
}
|
||||
|
||||
private fun sendHelpMessage() {
|
||||
if (messageMode.value == MessageMode.CUSTOM && customText.value == "unchanged" && timer.tick(5L)) { // 5 seconds delay
|
||||
MessageSendHelper.sendChatMessage("$chatName In order to use the custom $name, " +
|
||||
"please change the CustomText setting in ClickGUI, " +
|
||||
"with '&7\$NAME&f' being the username of the killed player")
|
||||
if (messageMode == MessageMode.CUSTOM && customText == UNCHANGED && timer.tick(5L)) { // 5 seconds delay
|
||||
MessageSendHelper.sendChatMessage(
|
||||
"$chatName In order to use the custom $name, " +
|
||||
"please change the CustomText setting in ClickGUI, " +
|
||||
"with ${formatValue(NAME)} being the username of the killed player"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun sendEzMessage(player: EntityPlayer) {
|
||||
val text = (if (messageMode.value == MessageMode.CUSTOM) customText.value else messageMode.value.text)
|
||||
.replace("\$NAME", player.name).replace("\$HYPIXEL_MESSAGE", hypixelCensorMessages.random())
|
||||
sendServerMessage(text)
|
||||
attackedPlayers.remove(player)
|
||||
private fun reset() {
|
||||
attackedPlayers.clear()
|
||||
confirmedKills.clear()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,25 +1,36 @@
|
|||
package org.kamiblue.client.module.modules.combat
|
||||
|
||||
import net.minecraft.network.play.server.SPacketPlayerPosLook
|
||||
import net.minecraft.util.MovementInputFromOptions
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.util.math.Vec3d
|
||||
import net.minecraftforge.client.event.InputUpdateEvent
|
||||
import org.kamiblue.client.event.SafeClientEvent
|
||||
import org.kamiblue.client.event.events.PacketEvent
|
||||
import org.kamiblue.client.event.events.PlayerMoveEvent
|
||||
import org.kamiblue.client.event.events.PlayerTravelEvent
|
||||
import org.kamiblue.client.event.events.RenderWorldEvent
|
||||
import org.kamiblue.client.module.Category
|
||||
import org.kamiblue.client.module.Module
|
||||
import org.kamiblue.client.module.modules.movement.Strafe
|
||||
import org.kamiblue.client.util.EntityUtils
|
||||
import org.kamiblue.client.util.EntityUtils.flooredPosition
|
||||
import org.kamiblue.client.util.MovementUtils.isCentered
|
||||
import org.kamiblue.client.util.MovementUtils.resetMove
|
||||
import org.kamiblue.client.util.MovementUtils.speed
|
||||
import org.kamiblue.client.util.combat.SurroundUtils
|
||||
import org.kamiblue.client.util.combat.SurroundUtils.checkHole
|
||||
import org.kamiblue.client.util.graphics.KamiTessellator
|
||||
import org.kamiblue.client.util.math.RotationUtils
|
||||
import org.kamiblue.client.util.math.VectorUtils
|
||||
import org.kamiblue.client.util.math.VectorUtils.distanceTo
|
||||
import org.kamiblue.client.util.math.VectorUtils.toBlockPos
|
||||
import org.kamiblue.client.util.math.VectorUtils.toVec3d
|
||||
import org.kamiblue.client.util.threads.safeAsyncListener
|
||||
import org.kamiblue.client.util.threads.safeListener
|
||||
import org.kamiblue.commons.extension.ceilToInt
|
||||
import org.kamiblue.commons.extension.toRadian
|
||||
import org.kamiblue.event.listener.listener
|
||||
import org.lwjgl.opengl.GL11.*
|
||||
import kotlin.math.*
|
||||
|
||||
internal object HoleSnap : Module(
|
||||
|
@ -27,40 +38,92 @@ internal object HoleSnap : Module(
|
|||
description = "Move you into the hole nearby",
|
||||
category = Category.COMBAT
|
||||
) {
|
||||
private val airStrafe by setting("Air Strafe", true)
|
||||
private val disableStrafe by setting("Disable Strafe", true)
|
||||
private val range by setting("Range", 2.5f, 0.5f..4.0f, 0.25f)
|
||||
|
||||
private var holePos: BlockPos? = null
|
||||
private var stuckTicks = 0
|
||||
|
||||
init {
|
||||
onDisable {
|
||||
holePos = null
|
||||
stuckTicks = 0
|
||||
}
|
||||
|
||||
safeListener<RenderWorldEvent>(1) {
|
||||
holePos?.let {
|
||||
if (player.flooredPosition == it) return@safeListener
|
||||
|
||||
val posFrom = EntityUtils.getInterpolatedPos(player, KamiTessellator.pTicks())
|
||||
val posTo = it.toVec3d(0.5, 0.0, 0.5)
|
||||
val buffer = KamiTessellator.buffer
|
||||
|
||||
glLineWidth(3.0f)
|
||||
glDisable(GL_DEPTH_TEST)
|
||||
KamiTessellator.begin(GL_LINES)
|
||||
|
||||
buffer.pos(posFrom.x, posFrom.y, posFrom.z).color(32, 255, 32, 255).endVertex()
|
||||
buffer.pos(posTo.x, posTo.y, posTo.z).color(32, 255, 32, 255).endVertex()
|
||||
|
||||
KamiTessellator.render()
|
||||
glLineWidth(1.0f)
|
||||
glEnable(GL_DEPTH_TEST)
|
||||
}
|
||||
}
|
||||
|
||||
listener<PacketEvent.Receive> {
|
||||
if (it.packet is SPacketPlayerPosLook) disable()
|
||||
}
|
||||
|
||||
listener<InputUpdateEvent>(-69) {
|
||||
if (it.movementInput is MovementInputFromOptions && holePos != null) {
|
||||
it.movementInput.resetMove()
|
||||
}
|
||||
}
|
||||
|
||||
safeAsyncListener<PlayerMoveEvent> {
|
||||
if (checkHole(player) != SurroundUtils.HoleType.NONE) {
|
||||
if (!player.isEntityAlive) return@safeAsyncListener
|
||||
|
||||
val currentSpeed = player.speed
|
||||
|
||||
if (shouldDisable(currentSpeed)) {
|
||||
disable()
|
||||
return@safeAsyncListener
|
||||
}
|
||||
|
||||
findHole()?.let {
|
||||
getHole()?.let {
|
||||
if (disableStrafe) Strafe.disable()
|
||||
if (player.onGround && !isAboveHole(it)) {
|
||||
if ((airStrafe || player.onGround) && !player.isCentered(it)) {
|
||||
val playerPos = player.positionVector
|
||||
val targetPos = Vec3d(it.x + 0.5, player.posY, it.z + 0.5)
|
||||
|
||||
val yawRad = RotationUtils.getRotationTo(playerPos, targetPos).x.toRadian()
|
||||
val dist = playerPos.distanceTo(targetPos)
|
||||
val speed = min(0.2805, dist / 2.0)
|
||||
val speed = if (player.onGround) min(0.2805, dist / 2.0) else currentSpeed + 0.02
|
||||
|
||||
player.motionX = -sin(yawRad) * speed
|
||||
player.motionZ = cos(yawRad) * speed
|
||||
|
||||
if (player.collidedHorizontally) stuckTicks++
|
||||
else stuckTicks = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun SafeClientEvent.shouldDisable(currentSpeed: Double) =
|
||||
holePos?.let { player.posY < it.y } ?: false
|
||||
|| stuckTicks > 5 && currentSpeed < 0.1
|
||||
|| currentSpeed < 0.01 && checkHole(player) != SurroundUtils.HoleType.NONE
|
||||
|
||||
private fun SafeClientEvent.getHole() =
|
||||
if (player.ticksExisted % 10 == 0 && player.flooredPosition != holePos) findHole()
|
||||
else holePos ?: findHole()
|
||||
|
||||
private fun SafeClientEvent.findHole(): BlockPos? {
|
||||
var closestHole = Pair(69.69, BlockPos.ORIGIN)
|
||||
val playerPos = player.positionVector.toBlockPos()
|
||||
val playerPos = player.flooredPosition
|
||||
val ceilRange = range.ceilToInt()
|
||||
val posList = VectorUtils.getBlockPositionsInArea(playerPos.add(ceilRange, -1, ceilRange), playerPos.add(-ceilRange, -1, -ceilRange))
|
||||
|
||||
|
@ -76,11 +139,7 @@ internal object HoleSnap : Module(
|
|||
}
|
||||
}
|
||||
|
||||
return if (closestHole.second != BlockPos.ORIGIN) closestHole.second else null
|
||||
}
|
||||
|
||||
private fun SafeClientEvent.isAboveHole(holePos: BlockPos): Boolean {
|
||||
return player.posX in holePos.x + 0.31..holePos.x + 0.69
|
||||
&& player.posZ in holePos.z + 0.31..holePos.z + 0.69
|
||||
return if (closestHole.second != BlockPos.ORIGIN) closestHole.second.also { holePos = it }
|
||||
else null
|
||||
}
|
||||
}
|
|
@ -12,6 +12,7 @@ import org.kamiblue.client.module.Category
|
|||
import org.kamiblue.client.module.Module
|
||||
import org.kamiblue.client.module.modules.movement.Strafe
|
||||
import org.kamiblue.client.util.*
|
||||
import org.kamiblue.client.util.MovementUtils.centerPlayer
|
||||
import org.kamiblue.client.util.MovementUtils.speed
|
||||
import org.kamiblue.client.util.WorldUtils.buildStructure
|
||||
import org.kamiblue.client.util.WorldUtils.getPlaceInfo
|
||||
|
@ -33,24 +34,21 @@ internal object Surround : Module(
|
|||
description = "Surrounds you with obsidian to take less damage",
|
||||
modulePriority = 200
|
||||
) {
|
||||
private val autoCenter = setting("Auto Center", AutoCenterMode.MOTION)
|
||||
private val placeSpeed = setting("Places Per Tick", 4f, 0.25f..5f, 0.25f)
|
||||
private val autoDisable = setting("Auto Disable", AutoDisableMode.OUT_OF_HOLE)
|
||||
private val outOfHoleTimeout = setting("Out Of Hole Timeout", 10, 1..50, 5, { autoDisable.value == AutoDisableMode.OUT_OF_HOLE }, description = "Delay before disabling Surround when you are out of hole, in ticks")
|
||||
private val placeSpeed by setting("Places Per Tick", 4f, 0.25f..5f, 0.25f)
|
||||
private val disableStrafe by setting("Disable Strafe", true)
|
||||
private val autoDisable by setting("Auto Disable", AutoDisableMode.OUT_OF_HOLE)
|
||||
private val outOfHoleTimeout by setting("Out Of Hole Timeout", 10, 1..50, 5, { autoDisable == AutoDisableMode.OUT_OF_HOLE }, description = "Delay before disabling Surround when you are out of hole, in ticks")
|
||||
private val enableInHole = setting("Enable In Hole", false)
|
||||
private val inHoleTimeout = setting("In Hole Timeout", 50, 1..100, 5, { enableInHole.value }, description = "Delay before enabling Surround when you are in hole, in ticks")
|
||||
private val disableStrafe = setting("Disable Strafe", true)
|
||||
private val inHoleTimeout by setting("In Hole Timeout", 50, 1..100, 5, { enableInHole.value }, description = "Delay before enabling Surround when you are in hole, in ticks")
|
||||
private val toggleMessage by setting("Toggle Message", true)
|
||||
|
||||
enum class AutoCenterMode {
|
||||
OFF, TP, MOTION
|
||||
}
|
||||
|
||||
enum class AutoDisableMode {
|
||||
private enum class AutoDisableMode {
|
||||
ONE_TIME, OUT_OF_HOLE
|
||||
}
|
||||
|
||||
private val toggleTimer = StopTimer(TimeUnit.TICKS)
|
||||
|
||||
private var holePos: BlockPos? = null
|
||||
private var toggleTimer = StopTimer(TimeUnit.TICKS)
|
||||
private var job: Job? = null
|
||||
|
||||
override fun isActive(): Boolean {
|
||||
|
@ -58,26 +56,24 @@ internal object Surround : Module(
|
|||
}
|
||||
|
||||
init {
|
||||
onEnable {
|
||||
toggleTimer.reset()
|
||||
}
|
||||
|
||||
onDisable {
|
||||
PlayerPacketManager.resetHotbar()
|
||||
toggleTimer.reset()
|
||||
holePos = null
|
||||
}
|
||||
|
||||
onToggle {
|
||||
toggleTimer.reset()
|
||||
}
|
||||
|
||||
safeListener<TickEvent.ClientTickEvent> {
|
||||
if (getObby() == null) return@safeListener
|
||||
|
||||
if (isDisabled) {
|
||||
enableInHoleCheck()
|
||||
return@safeListener
|
||||
}
|
||||
|
||||
// Following codes will not run if disabled
|
||||
|
||||
// Update hole pos
|
||||
if (holePos == null || inHoleCheck()) {
|
||||
holePos = player.positionVector.toBlockPos()
|
||||
|
@ -91,12 +87,19 @@ internal object Surround : Module(
|
|||
toggleTimer.reset()
|
||||
}
|
||||
|
||||
// Placeable & Centered check
|
||||
if (!canRun() || !centerPlayer()) {
|
||||
if (autoDisable.value == AutoDisableMode.ONE_TIME) disable()
|
||||
// Placeable
|
||||
if (!canRun()) {
|
||||
if (autoDisable == AutoDisableMode.ONE_TIME) disable()
|
||||
return@safeListener
|
||||
}
|
||||
|
||||
// Centered check
|
||||
if (!player.centerPlayer()) return@safeListener
|
||||
|
||||
if (disableStrafe) {
|
||||
Strafe.disable()
|
||||
}
|
||||
|
||||
// The actual job
|
||||
if (!job.isActiveOrFalse) {
|
||||
job = runSurround()
|
||||
|
@ -111,8 +114,8 @@ internal object Surround : Module(
|
|||
|
||||
private fun SafeClientEvent.enableInHoleCheck() {
|
||||
if (enableInHole.value && inHoleCheck()) {
|
||||
if (toggleTimer.stop() > inHoleTimeout.value) {
|
||||
MessageSendHelper.sendChatMessage("$chatName You are in hole for longer than ${inHoleTimeout.value} ticks, enabling")
|
||||
if (toggleTimer.stop() > inHoleTimeout) {
|
||||
if (toggleMessage) MessageSendHelper.sendChatMessage("$chatName You are in hole for longer than $inHoleTimeout ticks, enabling")
|
||||
enable()
|
||||
}
|
||||
} else {
|
||||
|
@ -123,9 +126,9 @@ internal object Surround : Module(
|
|||
private fun SafeClientEvent.inHoleCheck() = player.onGround && player.speed < 0.15 && checkHole(player) == SurroundUtils.HoleType.OBBY
|
||||
|
||||
private fun outOfHoleCheck() {
|
||||
if (autoDisable.value == AutoDisableMode.OUT_OF_HOLE) {
|
||||
if (toggleTimer.stop() > outOfHoleTimeout.value) {
|
||||
MessageSendHelper.sendChatMessage("$chatName You are out of hole for longer than ${outOfHoleTimeout.value} ticks, disabling")
|
||||
if (autoDisable == AutoDisableMode.OUT_OF_HOLE) {
|
||||
if (toggleTimer.stop() > outOfHoleTimeout) {
|
||||
if (toggleMessage) MessageSendHelper.sendChatMessage("$chatName You are out of hole for longer than $outOfHoleTimeout ticks, disabling")
|
||||
disable()
|
||||
}
|
||||
}
|
||||
|
@ -140,7 +143,7 @@ internal object Surround : Module(
|
|||
|
||||
if (slots == null) { // Obsidian check
|
||||
if (isEnabled) {
|
||||
MessageSendHelper.sendChatMessage("$chatName No obsidian in hotbar, disabling!")
|
||||
if (toggleMessage) MessageSendHelper.sendChatMessage("$chatName No obsidian in hotbar, disabling!")
|
||||
disable()
|
||||
}
|
||||
return null
|
||||
|
@ -151,26 +154,15 @@ internal object Surround : Module(
|
|||
|
||||
private fun SafeClientEvent.canRun(): Boolean {
|
||||
val playerPos = player.positionVector.toBlockPos()
|
||||
for (offset in SurroundUtils.surroundOffset) {
|
||||
val pos = playerPos.add(offset)
|
||||
if (isPlaceable(pos, true)) return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private fun centerPlayer(): Boolean {
|
||||
return if (autoCenter.value == AutoCenterMode.OFF) {
|
||||
true
|
||||
} else {
|
||||
if (disableStrafe.value) Strafe.disable()
|
||||
SurroundUtils.centerPlayer(autoCenter.value == AutoCenterMode.TP)
|
||||
return SurroundUtils.surroundOffset.any {
|
||||
isPlaceable(playerPos.add(it), true)
|
||||
}
|
||||
}
|
||||
|
||||
private fun SafeClientEvent.runSurround() = defaultScope.launch {
|
||||
spoofHotbar()
|
||||
|
||||
buildStructure(placeSpeed.value) {
|
||||
buildStructure(placeSpeed) {
|
||||
if (isEnabled && CombatManager.isOnTopPriority(this@Surround)) {
|
||||
getPlaceInfo(player.positionVector.toBlockPos(), SurroundUtils.surroundOffset, it, 2)
|
||||
} else {
|
||||
|
|
|
@ -13,107 +13,112 @@ import org.kamiblue.client.module.Module
|
|||
import org.kamiblue.client.util.color.EnumTextColor
|
||||
import org.kamiblue.client.util.text.MessageSendHelper
|
||||
import org.kamiblue.client.util.text.MessageSendHelper.sendServerMessage
|
||||
import org.kamiblue.client.util.text.format
|
||||
import org.kamiblue.client.util.threads.safeListener
|
||||
import org.kamiblue.commons.extension.synchronized
|
||||
import org.kamiblue.event.listener.listener
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
import kotlin.collections.LinkedHashMap
|
||||
|
||||
internal object TotemPopCounter : Module(
|
||||
name = "TotemPopCounter",
|
||||
description = "Counts how many times players pop",
|
||||
category = Category.COMBAT
|
||||
) {
|
||||
private val countFriends = setting("Count Friends", true)
|
||||
private val countSelf = setting("Count Self", false)
|
||||
private val resetOnDeath = setting("Reset On Death", true)
|
||||
private val announceSetting = setting("Announce", Announce.CLIENT)
|
||||
private val thanksTo = setting("Thanks To", false)
|
||||
private val colorName = setting("Color Name", EnumTextColor.DARK_PURPLE)
|
||||
private val colorNumber = setting("Color Number", EnumTextColor.LIGHT_PURPLE)
|
||||
private val countFriends by setting("Count Friends", true)
|
||||
private val countSelf by setting("Count Self", true)
|
||||
private val announceSetting by setting("Announce", Announce.CLIENT)
|
||||
private val thanksTo by setting("Thanks To", false)
|
||||
private val colorName by setting("Color Name", EnumTextColor.DARK_PURPLE)
|
||||
private val colorNumber by setting("Color Number", EnumTextColor.LIGHT_PURPLE)
|
||||
|
||||
private enum class Announce {
|
||||
CLIENT, EVERYONE
|
||||
}
|
||||
|
||||
private val playerList = HashMap<EntityPlayer, Int>().synchronized()
|
||||
private var wasDead = false
|
||||
private val popCountMap = WeakHashMap<EntityPlayer, Int>().synchronized()
|
||||
private var wasSent = false
|
||||
|
||||
init {
|
||||
onDisable {
|
||||
playerList.clear()
|
||||
popCountMap.clear()
|
||||
wasSent = true
|
||||
}
|
||||
|
||||
safeListener<PacketEvent.Receive> {
|
||||
if (it.packet !is SPacketEntityStatus || it.packet.opCode.toInt() != 35 || player.isDead) return@safeListener
|
||||
if (it.packet !is SPacketEntityStatus || it.packet.opCode.toInt() != 35 || !player.isEntityAlive) return@safeListener
|
||||
val player = (it.packet.getEntity(world) as? EntityPlayer) ?: return@safeListener
|
||||
|
||||
if (friendCheck(player) || selfCheck(player)) {
|
||||
val count = playerList.getOrDefault(player, 0) + 1
|
||||
playerList[player] = count
|
||||
sendMessage("${formatName(player)} popped ${formatNumber(count)} ${plural(count)}${ending()}")
|
||||
if (friendCheck(player) && selfCheck(player)) {
|
||||
val count = popCountMap.getOrDefault(player, 0) + 1
|
||||
popCountMap[player] = count
|
||||
|
||||
val isSelf = player == this.player
|
||||
val message = "${formatName(player)} popped ${formatNumber(count)} ${plural(count)}${ending(isSelf)}"
|
||||
sendMessage(message, !isSelf && isPublic)
|
||||
}
|
||||
}
|
||||
|
||||
listener<ConnectionEvent.Disconnect> {
|
||||
playerList.clear()
|
||||
popCountMap.clear()
|
||||
}
|
||||
|
||||
safeListener<TickEvent.ClientTickEvent> {
|
||||
if (it.phase != TickEvent.Phase.END) return@safeListener
|
||||
|
||||
if (wasDead && !player.isDead && resetOnDeath.value) {
|
||||
sendMessage("${formatName(player)} died and ${grammar(player)} pop list was reset!")
|
||||
playerList.clear()
|
||||
wasDead = false
|
||||
if (!player.isEntityAlive) {
|
||||
if (!wasSent) {
|
||||
popCountMap.clear()
|
||||
wasSent = true
|
||||
}
|
||||
return@safeListener
|
||||
}
|
||||
|
||||
val toRemove = ArrayList<EntityPlayer>()
|
||||
for ((poppedPlayer, count) in playerList) {
|
||||
if (!poppedPlayer.isDead) continue
|
||||
if (poppedPlayer == player) continue
|
||||
sendMessage("${formatName(poppedPlayer)} died after popping ${formatNumber(count)} ${plural(count)}${ending()}")
|
||||
toRemove.add(poppedPlayer)
|
||||
wasSent = false
|
||||
|
||||
popCountMap.entries.removeIf { (player, count) ->
|
||||
if (player == this.player || player.isEntityAlive) {
|
||||
false
|
||||
} else {
|
||||
val message = "${formatName(player)} died after popping ${formatNumber(count)} ${plural(count)}${ending(false)}"
|
||||
sendMessage(message, isPublic)
|
||||
true
|
||||
}
|
||||
}
|
||||
playerList.keys.removeAll(toRemove)
|
||||
|
||||
wasDead = player.isDead
|
||||
}
|
||||
}
|
||||
|
||||
private fun friendCheck(player: EntityPlayer) = FriendManager.isFriend(player.name) && countFriends.value
|
||||
private fun friendCheck(player: EntityPlayer) = countFriends || !FriendManager.isFriend(player.name)
|
||||
|
||||
private fun selfCheck(player: EntityPlayer) = player == mc.player && countSelf.value
|
||||
private fun selfCheck(player: EntityPlayer) = countSelf || player != mc.player
|
||||
|
||||
private fun formatName(player: EntityPlayer): String {
|
||||
val name = when {
|
||||
player == mc.player -> "I"
|
||||
FriendManager.isFriend(player.name) -> if (isPublic) "My friend, " else "Your friend, "
|
||||
else -> player.name
|
||||
private fun formatName(player: EntityPlayer) =
|
||||
colorName.textFormatting format when {
|
||||
player == mc.player -> {
|
||||
"I"
|
||||
}
|
||||
FriendManager.isFriend(player.name) -> {
|
||||
if (isPublic) "My friend ${player.name}, " else "Your friend ${player.name}, "
|
||||
}
|
||||
else -> {
|
||||
player.name
|
||||
}
|
||||
}
|
||||
return colorName.value.textFormatting.toString() + name + TextFormatting.RESET
|
||||
}
|
||||
|
||||
private val isPublic: Boolean
|
||||
get() = announceSetting.value == Announce.EVERYONE
|
||||
get() = announceSetting == Announce.EVERYONE
|
||||
|
||||
private fun formatNumber(message: Int) = colorNumber.textFormatting format message
|
||||
|
||||
private fun plural(count: Int) = if (count == 1) "totem" else "totems"
|
||||
|
||||
private fun grammar(player: EntityPlayer) = if (player == mc.player) "my" else "their"
|
||||
private fun ending(self: Boolean): String = if (!self && thanksTo) " thanks to ${KamiMod.NAME} !" else "!"
|
||||
|
||||
private fun ending(): String = if (thanksTo.value) " thanks to ${KamiMod.NAME} !" else "!"
|
||||
|
||||
private fun formatNumber(message: Int) = colorNumber.value.textFormatting.toString() + message + TextFormatting.RESET
|
||||
|
||||
private fun sendMessage(message: String) {
|
||||
when (announceSetting.value) {
|
||||
Announce.CLIENT -> {
|
||||
MessageSendHelper.sendChatMessage("$chatName $message")
|
||||
}
|
||||
Announce.EVERYONE -> {
|
||||
sendServerMessage(TextFormatting.getTextWithoutFormattingCodes(message))
|
||||
}
|
||||
private fun sendMessage(message: String, public: Boolean) {
|
||||
if (public) {
|
||||
sendServerMessage(TextFormatting.getTextWithoutFormattingCodes(message))
|
||||
} else {
|
||||
MessageSendHelper.sendChatMessage("$chatName $message")
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
package org.kamiblue.client.module.modules.movement
|
||||
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import org.kamiblue.client.event.SafeClientEvent
|
||||
import org.kamiblue.client.event.events.PlayerMoveEvent
|
||||
import org.kamiblue.client.module.Category
|
||||
import org.kamiblue.client.module.Module
|
||||
import org.kamiblue.client.util.EntityUtils.flooredPosition
|
||||
import org.kamiblue.client.util.MovementUtils.centerPlayer
|
||||
import org.kamiblue.client.util.MovementUtils.isCentered
|
||||
import org.kamiblue.client.util.combat.SurroundUtils
|
||||
import org.kamiblue.client.util.combat.SurroundUtils.checkHole
|
||||
import org.kamiblue.client.util.threads.safeListener
|
||||
|
||||
internal object Anchor : Module(
|
||||
name = "Anchor",
|
||||
description = "Stops your motion when you are above hole",
|
||||
category = Category.MOVEMENT
|
||||
) {
|
||||
private val mode by setting("Mode", Mode.BOTH)
|
||||
private val autoCenter by setting("Auto Center", true)
|
||||
private val stopYMotion by setting("Stop Y Motion", false)
|
||||
private val disableInHole by setting("Disable In Hole", false)
|
||||
private val pitchTrigger by setting("Pitch Trigger", true)
|
||||
private val pitch by setting("Pitch", 75, 0..80, 1, { pitchTrigger })
|
||||
private val verticalRange by setting("Vertical Range", 3, 1..5, 1)
|
||||
|
||||
private enum class Mode {
|
||||
BOTH, BEDROCK
|
||||
}
|
||||
|
||||
private var wasInHole = false
|
||||
|
||||
init {
|
||||
onDisable {
|
||||
wasInHole = false
|
||||
}
|
||||
|
||||
safeListener<PlayerMoveEvent> {
|
||||
val isInHole = player.onGround && isHole(player.flooredPosition)
|
||||
val validPitch = !pitchTrigger || player.rotationPitch > pitch
|
||||
|
||||
// Disable after in hole for 2 ticks
|
||||
if (wasInHole && isInHole && disableInHole) {
|
||||
disable()
|
||||
return@safeListener
|
||||
}
|
||||
|
||||
if (validPitch) {
|
||||
// Stops XZ motion
|
||||
if (isInHole || isAboveHole()) {
|
||||
if (player.isCentered(player.flooredPosition)) {
|
||||
player.motionX = 0.0
|
||||
player.motionZ = 0.0
|
||||
} else if (autoCenter) {
|
||||
player.centerPlayer()
|
||||
}
|
||||
}
|
||||
|
||||
// Stops Y motion
|
||||
if (stopYMotion && isInHole) {
|
||||
player.motionY = -0.08 // Minecraft needs this for on ground check
|
||||
}
|
||||
}
|
||||
|
||||
wasInHole = isInHole
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the player is above hole
|
||||
*/
|
||||
private fun SafeClientEvent.isAboveHole(): Boolean {
|
||||
val flooredPos = player.flooredPosition
|
||||
|
||||
for (yOffset in 1..verticalRange) {
|
||||
val pos = flooredPos.down(yOffset)
|
||||
if (!world.isAirBlock(pos)) return false
|
||||
if (isHole(pos)) return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the specified block position is a valid type of hole
|
||||
*/
|
||||
private fun SafeClientEvent.isHole(pos: BlockPos): Boolean {
|
||||
val type = checkHole(pos)
|
||||
return mode == Mode.BOTH && type != SurroundUtils.HoleType.NONE
|
||||
|| mode == Mode.BEDROCK && type == SurroundUtils.HoleType.BEDROCK
|
||||
}
|
||||
|
||||
}
|
|
@ -64,7 +64,7 @@ internal object Jesus : Module(
|
|||
}
|
||||
|
||||
@JvmStatic
|
||||
fun handleAddCollisionBoxToList(pos: BlockPos, block: Block, entity: Entity?, entityBox: AxisAlignedBB, collidingBoxes: MutableList<AxisAlignedBB>) {
|
||||
fun handleAddCollisionBoxToList(pos: BlockPos, block: Block, entity: Entity?, collidingBoxes: MutableList<AxisAlignedBB>) {
|
||||
if (isDisabled || mode == Mode.DOLPHIN) return
|
||||
if (mc.gameSettings.keyBindSneak.isKeyDown) return
|
||||
if (block !is BlockLiquid) return
|
||||
|
|
|
@ -56,7 +56,6 @@ internal object Strafe : Module(
|
|||
private var jumpTicks = 0
|
||||
private val strafeTimer = TickTimer(TimeUnit.TICKS)
|
||||
|
||||
/* If you skid this you omega gay */
|
||||
init {
|
||||
onDisable {
|
||||
reset()
|
||||
|
|
|
@ -25,9 +25,10 @@ import org.kamiblue.client.module.Category
|
|||
import org.kamiblue.client.module.Module
|
||||
import org.kamiblue.client.util.*
|
||||
import org.kamiblue.client.util.MovementUtils.calcMoveYaw
|
||||
import org.kamiblue.client.util.MovementUtils.resetJumpSneak
|
||||
import org.kamiblue.client.util.MovementUtils.resetMove
|
||||
import org.kamiblue.client.util.math.RotationUtils
|
||||
import org.kamiblue.client.util.math.RotationUtils.getRotationTo
|
||||
import org.kamiblue.client.util.math.VectorUtils.toBlockPos
|
||||
import org.kamiblue.client.util.threads.onMainThreadSafe
|
||||
import org.kamiblue.client.util.threads.runSafeR
|
||||
import org.kamiblue.client.util.threads.safeListener
|
||||
|
@ -45,13 +46,14 @@ internal object Freecam : Module(
|
|||
category = Category.PLAYER,
|
||||
description = "Leave your body and transcend into the realm of the gods"
|
||||
) {
|
||||
private val directionMode = setting("Flight Mode", FlightMode.CREATIVE)
|
||||
private val horizontalSpeed = setting("Horizontal Speed", 20f, 1f..50f, 1f)
|
||||
private val verticalSpeed = setting("Vertical Speed", 20f, 1f..50f, 1f)
|
||||
private val autoRotate = setting("Auto Rotate", true)
|
||||
private val arrowKeyMove = setting("Arrow Key Move", true)
|
||||
private val disableOnDisconnect = setting("Disconnect Disable", true)
|
||||
private val leftClickCome = setting("Left Click Come", true)
|
||||
private val directionMode by setting("Flight Mode", FlightMode.CREATIVE)
|
||||
private val horizontalSpeed by setting("Horizontal Speed", 20.0f, 1.0f..50.0f, 1f)
|
||||
private val verticalSpeed by setting("Vertical Speed", 20.0f, 1.0f..50.0f, 1f, { directionMode == FlightMode.CREATIVE })
|
||||
private val autoRotate by setting("Auto Rotate", true)
|
||||
private val arrowKeyMove by setting("Arrow Key Move", true)
|
||||
private val disableOnDisconnect by setting("Disconnect Disable", true)
|
||||
private val leftClickCome by setting("Left Click Come", false)
|
||||
private val relative by setting("Relative", false)
|
||||
|
||||
private enum class FlightMode(override val displayName: String) : DisplayEnum {
|
||||
CREATIVE("Creative"),
|
||||
|
@ -112,7 +114,7 @@ internal object Freecam : Module(
|
|||
|
||||
listener<ConnectionEvent.Disconnect> {
|
||||
prevThirdPersonViewSetting = -1
|
||||
if (disableOnDisconnect.value) disable()
|
||||
if (disableOnDisconnect) disable()
|
||||
else cameraGuy = null
|
||||
}
|
||||
|
||||
|
@ -149,35 +151,26 @@ internal object Freecam : Module(
|
|||
|
||||
if (BaritoneUtils.isActive) return@safeListener
|
||||
|
||||
if (autoRotate.value) updatePlayerRotation()
|
||||
if (arrowKeyMove.value) updatePlayerMovement()
|
||||
if (autoRotate) updatePlayerRotation()
|
||||
if (arrowKeyMove) updatePlayerMovement()
|
||||
}
|
||||
|
||||
listener<InputEvent.MouseInputEvent> {
|
||||
if (leftClickCome.value && Mouse.getEventButton() == 0 && clickTimer.tick(1L)) {
|
||||
if (leftClickCome && Mouse.getEventButton() == 0 && clickTimer.tick(1L)) {
|
||||
val result = mc.objectMouseOver ?: return@listener
|
||||
|
||||
if (result.typeOfHit != RayTraceResult.Type.BLOCK) {
|
||||
return@listener
|
||||
if (result.typeOfHit == RayTraceResult.Type.BLOCK) {
|
||||
BaritoneUtils.cancelEverything()
|
||||
BaritoneUtils.primary?.customGoalProcess?.setGoalAndPath(GoalTwoBlocks(result.blockPos))
|
||||
}
|
||||
|
||||
BaritoneUtils.cancelEverything()
|
||||
BaritoneUtils.primary?.customGoalProcess?.setGoalAndPath(GoalTwoBlocks(result.hitVec.toBlockPos()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun resetMovementInput(movementInput: MovementInput?) {
|
||||
if (movementInput !is MovementInputFromOptions) return
|
||||
movementInput.apply {
|
||||
moveForward = 0f
|
||||
moveStrafe = 0f
|
||||
forwardKeyDown = false
|
||||
backKeyDown = false
|
||||
leftKeyDown = false
|
||||
rightKeyDown = false
|
||||
jump = false
|
||||
sneak = false
|
||||
if (movementInput is MovementInputFromOptions) {
|
||||
movementInput.resetMove()
|
||||
movementInput.resetJumpSneak()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -219,16 +212,16 @@ internal object Freecam : Module(
|
|||
|
||||
val yawDiff = player.rotationYaw - it.rotationYaw
|
||||
val yawRad = calcMoveYaw(yawDiff, movementInput.first, movementInput.second).toFloat()
|
||||
val inputTotal = min(abs(movementInput.first) + abs(movementInput.second), 1f)
|
||||
val inputTotal = min(abs(movementInput.first) + abs(movementInput.second), 1.0f)
|
||||
|
||||
player.movementInput?.apply {
|
||||
moveForward = cos(yawRad) * inputTotal
|
||||
moveStrafe = sin(yawRad) * inputTotal
|
||||
|
||||
forwardKeyDown = moveForward > 0f
|
||||
backKeyDown = moveForward < 0f
|
||||
leftKeyDown = moveStrafe < 0f
|
||||
rightKeyDown = moveStrafe > 0f
|
||||
forwardKeyDown = moveForward > 0.0f
|
||||
backKeyDown = moveForward < 0.0f
|
||||
leftKeyDown = moveStrafe < 0.0f
|
||||
rightKeyDown = moveStrafe > 0.0f
|
||||
|
||||
jump = Keyboard.isKeyDown(Keyboard.KEY_RCONTROL)
|
||||
}
|
||||
|
@ -273,17 +266,18 @@ internal object Freecam : Module(
|
|||
// Update sprinting
|
||||
isSprinting = mc.gameSettings.keyBindSprint.isKeyDown
|
||||
|
||||
val yawRad = (rotationYaw - RotationUtils.getRotationFromVec(Vec3d(moveStrafing.toDouble(), 0.0, moveForward.toDouble())).x).toDouble().toRadian()
|
||||
val speed = (horizontalSpeed.value / 20f) * min(abs(moveForward) + abs(moveStrafing), 1f)
|
||||
val absYaw = RotationUtils.getRotationFromVec(Vec3d(moveStrafing.toDouble(), 0.0, moveForward.toDouble())).x
|
||||
val yawRad = (rotationYaw - absYaw).toDouble().toRadian()
|
||||
val speed = (horizontalSpeed / 20.0f) * min(abs(moveForward) + abs(moveStrafing), 1.0f)
|
||||
|
||||
if (directionMode.value == FlightMode.THREE_DEE) {
|
||||
val pitchRad = Math.toRadians(rotationPitch.toDouble()) * moveForward
|
||||
if (directionMode == FlightMode.THREE_DEE) {
|
||||
val pitchRad = rotationPitch.toDouble().toRadian() * moveForward
|
||||
motionX = -sin(yawRad) * cos(pitchRad) * speed
|
||||
motionY = -sin(pitchRad) * speed
|
||||
motionZ = cos(yawRad) * cos(pitchRad) * speed
|
||||
} else {
|
||||
motionX = -sin(yawRad) * speed
|
||||
motionY = moveVertical.toDouble() * (verticalSpeed.value / 20f)
|
||||
motionY = moveVertical.toDouble() * (verticalSpeed / 20.0f)
|
||||
motionZ = cos(yawRad) * speed
|
||||
}
|
||||
|
||||
|
@ -293,13 +287,19 @@ internal object Freecam : Module(
|
|||
motionZ *= 1.5
|
||||
}
|
||||
|
||||
noClip = true
|
||||
if (relative) {
|
||||
motionX += player.posX - player.prevPosX
|
||||
motionY += player.posY - player.prevPosY
|
||||
motionZ += player.posZ - player.prevPosZ
|
||||
}
|
||||
|
||||
move(MoverType.SELF, motionX, motionY, motionZ)
|
||||
}
|
||||
|
||||
override fun getEyeHeight() = 1.65f
|
||||
|
||||
override fun isSpectator() = true
|
||||
|
||||
override fun isInvisible() = true
|
||||
|
||||
override fun isInvisibleToPlayer(player: EntityPlayer) = true
|
||||
|
@ -315,23 +315,23 @@ internal object Freecam : Module(
|
|||
private fun calcMovementInput(forward: Pair<Boolean, Boolean>, strafe: Pair<Boolean, Boolean>, vertical: Pair<Boolean, Boolean>): Triple<Float, Float, Float> {
|
||||
// Forward movement input
|
||||
val moveForward = if (forward.first xor forward.second) {
|
||||
if (forward.first) 1f else -1f
|
||||
if (forward.first) 1.0f else -1.0f
|
||||
} else {
|
||||
0f
|
||||
0.0f
|
||||
}
|
||||
|
||||
// Strafe movement input
|
||||
val moveStrafing = if (strafe.first xor strafe.second) {
|
||||
if (strafe.second) 1f else -1f
|
||||
if (strafe.second) 1.0f else -1.0f
|
||||
} else {
|
||||
0f
|
||||
0.0f
|
||||
}
|
||||
|
||||
// Vertical movement input
|
||||
val moveVertical = if (vertical.first xor vertical.second) {
|
||||
if (vertical.first) 1f else -1f
|
||||
if (vertical.first) 1.0f else -1.0f
|
||||
} else {
|
||||
0f
|
||||
0.0f
|
||||
}
|
||||
|
||||
return Triple(moveForward, moveStrafing, moveVertical)
|
||||
|
|
|
@ -18,6 +18,7 @@ import org.kamiblue.client.util.text.MessageSendHelper
|
|||
import org.kamiblue.client.util.threads.defaultScope
|
||||
import org.kamiblue.client.util.threads.safeListener
|
||||
import org.kamiblue.commons.interfaces.DisplayEnum
|
||||
import org.kamiblue.event.listener.listener
|
||||
import java.io.*
|
||||
import java.time.LocalTime
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
@ -39,10 +40,10 @@ internal object PacketLogger : Module(
|
|||
private val ignoreCancelled by setting("Ignore Cancelled", true, description = "Ignore cancelled packets.")
|
||||
|
||||
private val fileTimeFormatter = DateTimeFormatter.ofPattern("HH-mm-ss_SSS")
|
||||
private val logTimeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss.SSS")
|
||||
|
||||
private var start = 0L
|
||||
private var last = 0L
|
||||
private var lastTick = 0L
|
||||
private val timer = TickTimer(TimeUnit.SECONDS)
|
||||
|
||||
private const val directory = "${KamiMod.DIRECTORY}packetLogs"
|
||||
|
@ -73,8 +74,10 @@ internal object PacketLogger : Module(
|
|||
if (it.phase != TickEvent.Phase.START) return@safeListener
|
||||
|
||||
if (showClientTicks) {
|
||||
synchronized(this) {
|
||||
lines.add("Tick Pulse - Realtime: ${logTimeFormatter.format(LocalTime.now())} - Runtime: ${System.currentTimeMillis() - start}ms\n")
|
||||
synchronized(this@PacketLogger) {
|
||||
val current = System.currentTimeMillis()
|
||||
lines.add("Tick Pulse,,${current - start},${current - lastTick}\n")
|
||||
lastTick = current
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,215 +91,305 @@ internal object PacketLogger : Module(
|
|||
disable()
|
||||
}
|
||||
|
||||
safeListener<PacketEvent.Receive>(Int.MIN_VALUE) {
|
||||
if (ignoreCancelled && it.cancelled) return@safeListener
|
||||
listener<PacketEvent.PostReceive>(Int.MIN_VALUE) {
|
||||
if (ignoreCancelled && it.cancelled) return@listener
|
||||
|
||||
if (packetSide == PacketSide.SERVER || packetSide == PacketSide.BOTH) {
|
||||
when (it.packet) {
|
||||
is SPacketEntityTeleport -> {
|
||||
add(PacketSide.SERVER, it.packet,
|
||||
"x: ${it.packet.x} " +
|
||||
"y: ${it.packet.y} " +
|
||||
"z: ${it.packet.z} " +
|
||||
"pitch: ${it.packet.pitch} " +
|
||||
"yaw: ${it.packet.yaw} " +
|
||||
"entityID: ${it.packet.entityId}")
|
||||
}
|
||||
is SPacketEntityMetadata -> {
|
||||
val dataEntry = StringBuilder().run {
|
||||
append("dataEntries: ")
|
||||
for (entry in it.packet.dataManagerEntries) {
|
||||
append("> isDirty: ${entry.isDirty} key: ${entry.key} value: ${entry.value} ")
|
||||
}
|
||||
toString()
|
||||
}
|
||||
|
||||
add(PacketSide.SERVER, it.packet, dataEntry)
|
||||
}
|
||||
is SPacketUnloadChunk -> {
|
||||
if (!ignoreChunkLoading) {
|
||||
add(PacketSide.SERVER, it.packet,
|
||||
"x: ${it.packet.x} " +
|
||||
"z: ${it.packet.z}")
|
||||
}
|
||||
}
|
||||
is SPacketDestroyEntities -> {
|
||||
val entities = StringBuilder().run {
|
||||
append("entityIDs: ")
|
||||
for (entry in it.packet.entityIDs) {
|
||||
append("> $entry ")
|
||||
}
|
||||
toString()
|
||||
}
|
||||
|
||||
add(PacketSide.SERVER, it.packet, entities)
|
||||
}
|
||||
is SPacketPlayerPosLook -> {
|
||||
val flags = StringBuilder().run {
|
||||
append("flags: ")
|
||||
for (entry in it.packet.flags) {
|
||||
append("> ${entry.name} ")
|
||||
}
|
||||
toString()
|
||||
}
|
||||
|
||||
add(PacketSide.SERVER, it.packet,
|
||||
"x: ${it.packet.x} " +
|
||||
"y: ${it.packet.y} " +
|
||||
"z: ${it.packet.z} " +
|
||||
"pitch: ${it.packet.pitch} " +
|
||||
"yaw: ${it.packet.yaw} " +
|
||||
"teleportID: ${it.packet.teleportId}" +
|
||||
flags)
|
||||
|
||||
}
|
||||
is SPacketBlockChange -> {
|
||||
add(PacketSide.SERVER, it.packet,
|
||||
"x: ${it.packet.blockPosition.x} " +
|
||||
"y: ${it.packet.blockPosition.y} " +
|
||||
"z: ${it.packet.blockPosition.z}")
|
||||
}
|
||||
is SPacketMultiBlockChange -> {
|
||||
val changedBlock = StringBuilder().run {
|
||||
append("changedBlocks: ")
|
||||
for (changedBlock in it.packet.changedBlocks) {
|
||||
append("> x: ${changedBlock.pos.x} y: ${changedBlock.pos.y} z: ${changedBlock.pos.z} ")
|
||||
}
|
||||
toString()
|
||||
log(it) {
|
||||
"x" to it.packet.blockPosition.x
|
||||
"y" to it.packet.blockPosition.y
|
||||
"z" to it.packet.blockPosition.z
|
||||
}
|
||||
|
||||
add(PacketSide.SERVER, it.packet, changedBlock)
|
||||
}
|
||||
is SPacketTimeUpdate -> {
|
||||
add(PacketSide.SERVER, it.packet,
|
||||
"totalWorldTime: ${it.packet.totalWorldTime} " +
|
||||
"worldTime: ${it.packet.worldTime}")
|
||||
}
|
||||
is SPacketChat -> {
|
||||
if (!ignoreChat) {
|
||||
add(PacketSide.SERVER, it.packet,
|
||||
"unformattedText: ${it.packet.chatComponent.unformattedText} " +
|
||||
"type: ${it.packet.type} " +
|
||||
"isSystem: ${it.packet.isSystem}")
|
||||
log(it) {
|
||||
"unformattedText" to it.packet.chatComponent.unformattedText
|
||||
"type" to it.packet.type
|
||||
"itSystem" to it.packet.isSystem
|
||||
}
|
||||
}
|
||||
}
|
||||
is SPacketTeams -> {
|
||||
add(PacketSide.SERVER, it.packet,
|
||||
"action: ${it.packet.action} " +
|
||||
"displayName: ${it.packet.displayName} " +
|
||||
"color: ${it.packet.color}")
|
||||
}
|
||||
is SPacketChunkData -> {
|
||||
add(PacketSide.SERVER, it.packet,
|
||||
"chunkX: ${it.packet.chunkX} " +
|
||||
"chunkZ: ${it.packet.chunkZ} " +
|
||||
"extractedSize: ${it.packet.extractedSize}")
|
||||
log(it) {
|
||||
"chunkX" to it.packet.chunkX
|
||||
"chunkZ" to it.packet.chunkZ
|
||||
"extractedSize" to it.packet.extractedSize
|
||||
}
|
||||
}
|
||||
is SPacketConfirmTransaction -> {
|
||||
log(it) {
|
||||
"windowId" to it.packet.windowId
|
||||
"transactionID" to it.packet.actionNumber
|
||||
"accepted" to it.packet.wasAccepted()
|
||||
}
|
||||
}
|
||||
is SPacketDestroyEntities -> {
|
||||
log(it) {
|
||||
"entityIDs" to buildString {
|
||||
for (entry in it.packet.entityIDs) {
|
||||
append("> ")
|
||||
append(entry)
|
||||
append(' ')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
is SPacketEntityMetadata -> {
|
||||
log(it) {
|
||||
"dataEntries" to buildString {
|
||||
for (entry in it.packet.dataManagerEntries) {
|
||||
append("> isDirty: ")
|
||||
append(entry.isDirty)
|
||||
|
||||
append(" key: ")
|
||||
append(entry.key)
|
||||
|
||||
append(" value: ")
|
||||
append(entry.value)
|
||||
|
||||
append(' ')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
is SPacketEntityProperties -> {
|
||||
add(PacketSide.SERVER, it.packet,
|
||||
"entityID: ${it.packet.entityId}")
|
||||
log(it) {
|
||||
"entityID" to it.packet.entityId
|
||||
}
|
||||
}
|
||||
is SPacketUpdateTileEntity -> {
|
||||
add(PacketSide.SERVER, it.packet,
|
||||
"posX: ${it.packet.pos.x} " +
|
||||
"posY: ${it.packet.pos.y} " +
|
||||
"posZ: ${it.packet.pos.z}")
|
||||
}
|
||||
is SPacketSpawnObject -> {
|
||||
add(PacketSide.SERVER, it.packet,
|
||||
"entityID: ${it.packet.entityID} " +
|
||||
"data: ${it.packet.data}")
|
||||
is SPacketEntityTeleport -> {
|
||||
log(it) {
|
||||
"x" to it.packet.x
|
||||
"y" to it.packet.y
|
||||
"z" to it.packet.z
|
||||
"yaw" to it.packet.yaw
|
||||
"pitch" to it.packet.pitch
|
||||
"entityID" to it.packet.entityId
|
||||
}
|
||||
}
|
||||
is SPacketKeepAlive -> {
|
||||
if (!ignoreKeepAlive) {
|
||||
add(PacketSide.SERVER, it.packet,
|
||||
"id: ${it.packet.id}")
|
||||
log(it) {
|
||||
"id" to it.packet.id
|
||||
}
|
||||
}
|
||||
}
|
||||
is SPacketMultiBlockChange -> {
|
||||
log(it) {
|
||||
"changedBlocks" to buildString {
|
||||
for (changedBlock in it.packet.changedBlocks) {
|
||||
append("> x: ")
|
||||
append(changedBlock.pos.x)
|
||||
|
||||
append("y: ")
|
||||
append(changedBlock.pos.y)
|
||||
|
||||
append("z: ")
|
||||
append(changedBlock.pos.z)
|
||||
|
||||
append(' ')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
is SPacketPlayerPosLook -> {
|
||||
log(it) {
|
||||
"x" to it.packet.x
|
||||
"y" to it.packet.y
|
||||
"z" to it.packet.z
|
||||
"yaw" to it.packet.yaw
|
||||
"pitch" to it.packet.pitch
|
||||
"teleportID" to it.packet.teleportId
|
||||
"flags" to buildString {
|
||||
for (entry in it.packet.flags) {
|
||||
append("> ")
|
||||
append(entry.name)
|
||||
append(' ')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
is SPacketSoundEffect -> {
|
||||
log(it) {
|
||||
"sound" to it.packet.sound.soundName
|
||||
"category" to it.packet.category
|
||||
"posX" to it.packet.x
|
||||
"posY" to it.packet.y
|
||||
"posZ" to it.packet.z
|
||||
"volume" to it.packet.volume
|
||||
"pitch" to it.packet.pitch
|
||||
}
|
||||
}
|
||||
is SPacketSpawnObject -> {
|
||||
log(it) {
|
||||
"entityID" to it.packet.entityID
|
||||
"data" to it.packet.data
|
||||
}
|
||||
}
|
||||
is SPacketTeams -> {
|
||||
log(it) {
|
||||
"action" to it.packet.action
|
||||
"type" to it.packet.displayName
|
||||
"itSystem" to it.packet.color
|
||||
}
|
||||
}
|
||||
is SPacketTimeUpdate -> {
|
||||
log(it) {
|
||||
"totalWorldTime" to it.packet.totalWorldTime
|
||||
"worldTime" to it.packet.worldTime
|
||||
}
|
||||
}
|
||||
is SPacketUnloadChunk -> {
|
||||
if (!ignoreChunkLoading) {
|
||||
log(it) {
|
||||
"x" to it.packet.x
|
||||
"z" to it.packet.z
|
||||
}
|
||||
}
|
||||
}
|
||||
is SPacketUpdateTileEntity -> {
|
||||
log(it) {
|
||||
"x" to it.packet.pos.x
|
||||
"y" to it.packet.pos.y
|
||||
"z" to it.packet.pos.z
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
if (!ignoreUnknown) {
|
||||
add(PacketSide.SERVER, it.packet, "Not Registered in PacketLogger.kt")
|
||||
log(it) {
|
||||
+ "Not Registered in PacketLogger"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
safeListener<PacketEvent.Send>(Int.MIN_VALUE) {
|
||||
if (ignoreCancelled && it.cancelled) return@safeListener
|
||||
listener<PacketEvent.PostSend>(Int.MIN_VALUE) {
|
||||
if (ignoreCancelled && it.cancelled) return@listener
|
||||
|
||||
if (packetSide == PacketSide.CLIENT || packetSide == PacketSide.BOTH) {
|
||||
when (it.packet) {
|
||||
is CPacketAnimation -> {
|
||||
add(PacketSide.CLIENT, it.packet,
|
||||
"hand: ${it.packet.hand}")
|
||||
}
|
||||
is CPacketPlayer.Rotation -> {
|
||||
add(PacketSide.CLIENT, it.packet,
|
||||
"pitch: ${it.packet.pitch} " +
|
||||
"yaw: ${it.packet.yaw} " +
|
||||
"onGround: ${it.packet.isOnGround}")
|
||||
}
|
||||
is CPacketPlayer.Position -> {
|
||||
add(PacketSide.CLIENT, it.packet,
|
||||
"x: ${it.packet.x} " +
|
||||
"y: ${it.packet.y} " +
|
||||
"z: ${it.packet.z} " +
|
||||
"onGround: ${it.packet.isOnGround}")
|
||||
}
|
||||
is CPacketPlayer.PositionRotation -> {
|
||||
add(PacketSide.CLIENT, it.packet,
|
||||
"x: ${it.packet.x} " +
|
||||
"y: ${it.packet.y} " +
|
||||
"z: ${it.packet.z} " +
|
||||
"pitch: ${it.packet.pitch} " +
|
||||
"yaw: ${it.packet.yaw} " +
|
||||
"onGround: ${it.packet.isOnGround}")
|
||||
}
|
||||
is CPacketPlayerDigging -> {
|
||||
add(PacketSide.CLIENT, it.packet,
|
||||
"positionX: ${it.packet.position.x} " +
|
||||
"positionY: ${it.packet.position.y} " +
|
||||
"positionZ: ${it.packet.position.z} " +
|
||||
"facing: ${it.packet.facing} " +
|
||||
"action: ${it.packet.action} ")
|
||||
}
|
||||
is CPacketEntityAction -> {
|
||||
add(PacketSide.CLIENT, it.packet,
|
||||
"action: ${it.packet.action} " +
|
||||
"auxData: ${it.packet.auxData}")
|
||||
}
|
||||
is CPacketUseEntity -> {
|
||||
add(PacketSide.CLIENT, it.packet,
|
||||
"action: ${it.packet.action} " +
|
||||
"hand: ${it.packet.hand} " +
|
||||
"hitVecX: ${it.packet.hitVec.x} " +
|
||||
"hitVecY: ${it.packet.hitVec.y} " +
|
||||
"hitVecZ: ${it.packet.hitVec.z}")
|
||||
}
|
||||
is CPacketPlayerTryUseItem -> {
|
||||
add(PacketSide.CLIENT, it.packet,
|
||||
"hand: ${it.packet.hand}")
|
||||
}
|
||||
is CPacketConfirmTeleport -> {
|
||||
add(PacketSide.CLIENT, it.packet,
|
||||
"teleportID: ${it.packet.teleportId}")
|
||||
log(it) {
|
||||
"hand" to it.packet.hand
|
||||
}
|
||||
}
|
||||
is CPacketChatMessage -> {
|
||||
if (!ignoreChat) {
|
||||
add(PacketSide.SERVER, it.packet,
|
||||
"message: ${it.packet.message}")
|
||||
log(it) {
|
||||
"message" to it.packet.message
|
||||
}
|
||||
}
|
||||
}
|
||||
is CPacketClickWindow -> {
|
||||
if (!ignoreChat) {
|
||||
log(it) {
|
||||
"windowId" to it.packet.windowId
|
||||
"slotID" to it.packet.slotId
|
||||
"mouseButton" to it.packet.usedButton
|
||||
"clickType" to it.packet.clickType
|
||||
"transactionID" to it.packet.actionNumber
|
||||
"clickedItem" to it.packet.clickedItem
|
||||
}
|
||||
}
|
||||
}
|
||||
is CPacketConfirmTeleport -> {
|
||||
log(it) {
|
||||
"teleportID" to it.packet.teleportId
|
||||
}
|
||||
}
|
||||
is CPacketEntityAction -> {
|
||||
log(it) {
|
||||
"action" to it.packet.action.name
|
||||
"auxData" to it.packet.auxData
|
||||
}
|
||||
}
|
||||
is CPacketHeldItemChange -> {
|
||||
log(it) {
|
||||
"slotID" to it.packet.slotId
|
||||
}
|
||||
}
|
||||
is CPacketKeepAlive -> {
|
||||
if (!ignoreKeepAlive) {
|
||||
add(PacketSide.CLIENT, it.packet,
|
||||
"key: ${it.packet.key}")
|
||||
log(it) {
|
||||
"ket" to it.packet.key
|
||||
}
|
||||
}
|
||||
}
|
||||
is CPacketPlayer.Rotation -> {
|
||||
log(it) {
|
||||
"yaw" to it.packet.yaw
|
||||
"pitch" to it.packet.pitch
|
||||
"onGround" to it.packet.isOnGround
|
||||
}
|
||||
}
|
||||
is CPacketPlayer.Position -> {
|
||||
log(it) {
|
||||
"x" to it.packet.x
|
||||
"y" to it.packet.y
|
||||
"z" to it.packet.z
|
||||
"onGround" to it.packet.isOnGround
|
||||
}
|
||||
}
|
||||
is CPacketPlayer.PositionRotation -> {
|
||||
log(it) {
|
||||
"x" to it.packet.x
|
||||
"y" to it.packet.y
|
||||
"z" to it.packet.z
|
||||
"yaw" to it.packet.yaw
|
||||
"pitch" to it.packet.pitch
|
||||
"onGround" to it.packet.isOnGround
|
||||
}
|
||||
}
|
||||
is CPacketPlayer -> {
|
||||
log(it) {
|
||||
"onGround" to it.packet.isOnGround
|
||||
}
|
||||
}
|
||||
is CPacketPlayerDigging -> {
|
||||
log(it) {
|
||||
"x" to it.packet.position.x
|
||||
"y" to it.packet.position.y
|
||||
"z" to it.packet.position.z
|
||||
"facing" to it.packet.facing
|
||||
"action" to it.packet.action
|
||||
}
|
||||
}
|
||||
is CPacketPlayerTryUseItem -> {
|
||||
log(it) {
|
||||
"hand" to it.packet.hand
|
||||
}
|
||||
}
|
||||
is CPacketPlayerTryUseItemOnBlock -> {
|
||||
log(it) {
|
||||
"x" to it.packet.pos.x
|
||||
"y" to it.packet.pos.y
|
||||
"z" to it.packet.pos.z
|
||||
"side" to it.packet.direction
|
||||
"hitVecX" to it.packet.facingX
|
||||
"hitVecY" to it.packet.facingY
|
||||
"hitVecZ" to it.packet.facingZ
|
||||
}
|
||||
}
|
||||
is CPacketUseEntity -> {
|
||||
@Suppress("UNNECESSARY_SAFE_CALL")
|
||||
log(it) {
|
||||
"action" to it.packet.action
|
||||
"action" to it.packet.hand
|
||||
"hitVecX" to it.packet.hitVec?.x
|
||||
"hitVecX" to it.packet.hitVec?.y
|
||||
"hitVecX" to it.packet.hitVec?.z
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
if (!ignoreUnknown) {
|
||||
add(PacketSide.CLIENT, it.packet, "Not Registered in PacketLogger.kt")
|
||||
log(it) {
|
||||
+ "Not Registered in PacketLogger"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -326,24 +419,72 @@ internal object PacketLogger : Module(
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a line to the csv following the format:
|
||||
* from (client or server), packet name, time since start, time since last packet, packet data
|
||||
*
|
||||
* @param side The [PacketSide] where this packet is from
|
||||
* @param packet Packet to add
|
||||
* @param data Data of the [packet] in [String]
|
||||
*/
|
||||
private fun add(side: PacketSide, packet: Packet<*>, data: String) {
|
||||
val string = "${side.displayName},${packet.javaClass.simpleName},${System.currentTimeMillis() - start},${System.currentTimeMillis() - last},${data}\n"
|
||||
private inline fun log(event: PacketEvent.PostSend, block: PacketLogBuilder.() -> Unit) {
|
||||
PacketLogBuilder(PacketSide.CLIENT, event.packet).apply(block).build()
|
||||
}
|
||||
|
||||
synchronized(this) {
|
||||
lines.add(string)
|
||||
last = System.currentTimeMillis()
|
||||
private inline fun log(event: PacketEvent.PostReceive, block: PacketLogBuilder.() -> Unit) {
|
||||
PacketLogBuilder(PacketSide.SERVER, event.packet).apply(block).build()
|
||||
}
|
||||
|
||||
private class PacketLogBuilder(val side: PacketSide, val packet: Packet<*>) {
|
||||
private val stringBuilder = StringBuilder()
|
||||
|
||||
init {
|
||||
stringBuilder.apply {
|
||||
append(side.displayName)
|
||||
append(',')
|
||||
|
||||
append(packet.javaClass.simpleName)
|
||||
append(',')
|
||||
|
||||
append(System.currentTimeMillis() - start)
|
||||
append(',')
|
||||
|
||||
append(System.currentTimeMillis() - last)
|
||||
append(',')
|
||||
}
|
||||
}
|
||||
|
||||
if (logInChat) {
|
||||
MessageSendHelper.sendChatMessage(string)
|
||||
operator fun String.unaryPlus() {
|
||||
stringBuilder.append(this)
|
||||
}
|
||||
|
||||
infix fun String.to(value: Any?) {
|
||||
if (value != null) {
|
||||
add(this, value.toString())
|
||||
}
|
||||
}
|
||||
|
||||
infix fun String.to(value: String?) {
|
||||
if (value != null) {
|
||||
add(this, value)
|
||||
}
|
||||
}
|
||||
|
||||
fun add(key: String, value: String) {
|
||||
stringBuilder.apply {
|
||||
append(key)
|
||||
append(": ")
|
||||
append(value)
|
||||
append(' ')
|
||||
}
|
||||
}
|
||||
|
||||
fun build() {
|
||||
val string = stringBuilder.run {
|
||||
append('\n')
|
||||
toString()
|
||||
}
|
||||
|
||||
synchronized(PacketLogger) {
|
||||
lines.add(string)
|
||||
last = System.currentTimeMillis()
|
||||
}
|
||||
|
||||
if (logInChat) {
|
||||
MessageSendHelper.sendChatMessage(string)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,34 +26,34 @@ internal object Chams : Module(
|
|||
category = Category.RENDER,
|
||||
description = "Modify entity rendering"
|
||||
) {
|
||||
private val page = setting("Page", Page.ENTITY_TYPE)
|
||||
private val page by setting("Page", Page.ENTITY_TYPE)
|
||||
|
||||
/* Entity type settings */
|
||||
private val self = setting("Self", false, { page.value == Page.ENTITY_TYPE })
|
||||
private val all = setting("All Entities", false, { page.value == Page.ENTITY_TYPE })
|
||||
private val experience = setting("Experience", false, { page.value == Page.ENTITY_TYPE && !all.value })
|
||||
private val arrows = setting("Arrows", false, { page.value == Page.ENTITY_TYPE && !all.value })
|
||||
private val throwable = setting("Throwable", false, { page.value == Page.ENTITY_TYPE && !all.value })
|
||||
private val items = setting("Items", false, { page.value == Page.ENTITY_TYPE && !all.value })
|
||||
private val crystals = setting("Crystals", false, { page.value == Page.ENTITY_TYPE && !all.value })
|
||||
private val players = setting("Players", true, { page.value == Page.ENTITY_TYPE && !all.value })
|
||||
private val friends = setting("Friends", false, { page.value == Page.ENTITY_TYPE && !all.value && players.value })
|
||||
private val sleeping = setting("Sleeping", false, { page.value == Page.ENTITY_TYPE && !all.value && players.value })
|
||||
private val mobs = setting("Mobs", true, { page.value == Page.ENTITY_TYPE && !all.value })
|
||||
private val passive = setting("Passive Mobs", false, { page.value == Page.ENTITY_TYPE && !all.value && mobs.value })
|
||||
private val neutral = setting("Neutral Mobs", true, { page.value == Page.ENTITY_TYPE && !all.value && mobs.value })
|
||||
private val hostile = setting("Hostile Mobs", true, { page.value == Page.ENTITY_TYPE && !all.value && mobs.value })
|
||||
private val self by setting("Self", false, { page == Page.ENTITY_TYPE })
|
||||
private val all by setting("All Entities", false, { page == Page.ENTITY_TYPE })
|
||||
private val experience by setting("Experience", false, { page == Page.ENTITY_TYPE && !all })
|
||||
private val arrows by setting("Arrows", false, { page == Page.ENTITY_TYPE && !all })
|
||||
private val throwable by setting("Throwable", false, { page == Page.ENTITY_TYPE && !all })
|
||||
private val items by setting("Items", false, { page == Page.ENTITY_TYPE && !all })
|
||||
private val crystals by setting("Crystals", false, { page == Page.ENTITY_TYPE && !all })
|
||||
private val players by setting("Players", true, { page == Page.ENTITY_TYPE && !all })
|
||||
private val friends by setting("Friends", false, { page == Page.ENTITY_TYPE && !all && players })
|
||||
private val sleeping by setting("Sleeping", false, { page == Page.ENTITY_TYPE && !all && players })
|
||||
private val mobs by setting("Mobs", true, { page == Page.ENTITY_TYPE && !all })
|
||||
private val passive by setting("Passive Mobs", false, { page == Page.ENTITY_TYPE && !all && mobs })
|
||||
private val neutral by setting("Neutral Mobs", true, { page == Page.ENTITY_TYPE && !all && mobs })
|
||||
private val hostile by setting("Hostile Mobs", true, { page == Page.ENTITY_TYPE && !all && mobs })
|
||||
|
||||
/* Rendering settings */
|
||||
private val throughWall = setting("Through Wall", true, { page.value == Page.RENDERING })
|
||||
private val texture = setting("Texture", false, { page.value == Page.RENDERING })
|
||||
private val lightning = setting("Lightning", false, { page.value == Page.RENDERING })
|
||||
private val customColor = setting("Custom Color", false, { page.value == Page.RENDERING })
|
||||
private val rainbow = setting("Rainbow", false, { page.value == Page.RENDERING && customColor.value })
|
||||
private val r = setting("Red", 255, 0..255, 1, { page.value == Page.RENDERING && customColor.value && !rainbow.value })
|
||||
private val g = setting("Green", 255, 0..255, 1, { page.value == Page.RENDERING && customColor.value && !rainbow.value })
|
||||
private val b = setting("Blue", 255, 0..255, 1, { page.value == Page.RENDERING && customColor.value && !rainbow.value })
|
||||
private val a = setting("Alpha", 255, 0..255, 1, { page.value == Page.RENDERING && customColor.value })
|
||||
private val throughWall by setting("Through Wall", true, { page == Page.RENDERING })
|
||||
private val texture by setting("Texture", false, { page == Page.RENDERING })
|
||||
private val lightning by setting("Lightning", false, { page == Page.RENDERING })
|
||||
private val customColor by setting("Custom Color", false, { page == Page.RENDERING })
|
||||
private val rainbow by setting("Rainbow", false, { page == Page.RENDERING && customColor })
|
||||
private val r by setting("Red", 255, 0..255, 1, { page == Page.RENDERING && customColor && !rainbow })
|
||||
private val g by setting("Green", 255, 0..255, 1, { page == Page.RENDERING && customColor && !rainbow })
|
||||
private val b by setting("Blue", 255, 0..255, 1, { page == Page.RENDERING && customColor && !rainbow })
|
||||
private val a by setting("Alpha", 160, 0..255, 1, { page == Page.RENDERING && customColor })
|
||||
|
||||
private enum class Page {
|
||||
ENTITY_TYPE, RENDERING
|
||||
|
@ -62,34 +62,47 @@ internal object Chams : Module(
|
|||
private var cycler = HueCycler(600)
|
||||
|
||||
init {
|
||||
listener<RenderEntityEvent>(2000) {
|
||||
listener<RenderEntityEvent.All>(2000) {
|
||||
if (!checkEntityType(it.entity)) return@listener
|
||||
|
||||
if (it.phase == Phase.PRE) {
|
||||
if (!texture.value) glDisable(GL_TEXTURE_2D)
|
||||
if (!lightning.value) glDisable(GL_LIGHTING)
|
||||
if (customColor.value) {
|
||||
if (rainbow.value) cycler.currentRgba(a.value).setGLColor()
|
||||
else glColor4f(r.value / 255.0f, g.value / 255.0f, b.value / 255.0f, a.value / 255.0f)
|
||||
GlStateUtils.colorLock(true)
|
||||
GlStateUtils.blend(true)
|
||||
GlStateManager.tryBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO)
|
||||
when (it.phase) {
|
||||
Phase.PRE -> {
|
||||
if (throughWall) glDepthRange(0.0, 0.01)
|
||||
}
|
||||
if (throughWall.value) {
|
||||
glDepthRange(0.0, 0.01)
|
||||
Phase.PERI -> {
|
||||
if (throughWall) glDepthRange(0.0, 1.0)
|
||||
}
|
||||
else -> {
|
||||
// Doesn't need to do anything on post phase
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (it.phase == Phase.PERI) {
|
||||
if (!texture.value) glEnable(GL_TEXTURE_2D)
|
||||
if (!lightning.value) glEnable(GL_LIGHTING)
|
||||
if (customColor.value) {
|
||||
GlStateUtils.blend(false)
|
||||
GlStateUtils.colorLock(false)
|
||||
glColor4f(1f, 1f, 1f, 1f)
|
||||
listener<RenderEntityEvent.Model> {
|
||||
if (!checkEntityType(it.entity)) return@listener
|
||||
|
||||
when (it.phase) {
|
||||
Phase.PRE -> {
|
||||
if (!texture) glDisable(GL_TEXTURE_2D)
|
||||
if (!lightning) glDisable(GL_LIGHTING)
|
||||
if (customColor) {
|
||||
if (rainbow) cycler.currentRgba(a).setGLColor()
|
||||
else glColor4f(r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f)
|
||||
|
||||
GlStateUtils.blend(true)
|
||||
GlStateManager.tryBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO)
|
||||
}
|
||||
}
|
||||
if (throughWall.value) {
|
||||
glDepthRange(0.0, 1.0)
|
||||
Phase.POST -> {
|
||||
if (!texture) glEnable(GL_TEXTURE_2D)
|
||||
if (!lightning) glEnable(GL_LIGHTING)
|
||||
if (customColor) {
|
||||
GlStateUtils.blend(false)
|
||||
glColor4f(1f, 1f, 1f, 1f)
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
// RenderEntityEvent.Model doesn't have peri phase
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -99,14 +112,15 @@ internal object Chams : Module(
|
|||
}
|
||||
}
|
||||
|
||||
private fun checkEntityType(entity: Entity): Boolean {
|
||||
return (self.value || entity != mc.player) && (all.value
|
||||
|| experience.value && entity is EntityXPOrb
|
||||
|| arrows.value && entity is EntityArrow
|
||||
|| throwable.value && entity is EntityThrowable
|
||||
|| items.value && entity is EntityItem
|
||||
|| crystals.value && entity is EntityEnderCrystal
|
||||
|| players.value && entity is EntityPlayer && EntityUtils.playerTypeCheck(entity, friends.value, sleeping.value)
|
||||
|| mobTypeSettings(entity, mobs.value, passive.value, neutral.value, hostile.value))
|
||||
}
|
||||
private fun checkEntityType(entity: Entity) =
|
||||
(self || entity != mc.player) && (
|
||||
all
|
||||
|| experience && entity is EntityXPOrb
|
||||
|| arrows && entity is EntityArrow
|
||||
|| throwable && entity is EntityThrowable
|
||||
|| items && entity is EntityItem
|
||||
|| crystals && entity is EntityEnderCrystal
|
||||
|| players && entity is EntityPlayer && EntityUtils.playerTypeCheck(entity, friends, sleeping)
|
||||
|| mobTypeSettings(entity, mobs, passive, neutral, hostile)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -14,21 +14,21 @@ import org.kamiblue.client.event.Phase
|
|||
import org.kamiblue.client.event.SafeClientEvent
|
||||
import org.kamiblue.client.event.events.RenderEntityEvent
|
||||
import org.kamiblue.client.event.events.RenderWorldEvent
|
||||
import org.kamiblue.client.mixin.extension.entityOutlineShader
|
||||
import org.kamiblue.client.mixin.extension.listFrameBuffers
|
||||
import org.kamiblue.client.mixin.extension.listShaders
|
||||
import org.kamiblue.client.mixin.extension.renderOutlines
|
||||
import org.kamiblue.client.mixin.extension.*
|
||||
import org.kamiblue.client.module.Category
|
||||
import org.kamiblue.client.module.Module
|
||||
import org.kamiblue.client.util.EntityUtils
|
||||
import org.kamiblue.client.util.EntityUtils.getTargetList
|
||||
import org.kamiblue.client.util.color.ColorHolder
|
||||
import org.kamiblue.client.util.graphics.ESPRenderer
|
||||
import org.kamiblue.client.util.graphics.GlStateUtils
|
||||
import org.kamiblue.client.util.graphics.KamiTessellator
|
||||
import org.kamiblue.client.util.graphics.ShaderHelper
|
||||
import org.kamiblue.client.util.threads.runSafe
|
||||
import org.kamiblue.client.util.threads.safeListener
|
||||
import org.kamiblue.event.listener.listener
|
||||
import org.lwjgl.opengl.GL11.*
|
||||
import org.lwjgl.opengl.GL11.GL_MODELVIEW
|
||||
import org.lwjgl.opengl.GL11.GL_PROJECTION
|
||||
|
||||
internal object ESP : Module(
|
||||
name = "ESP",
|
||||
|
@ -74,87 +74,29 @@ internal object ESP : Module(
|
|||
BOX, GLOW, SHADER
|
||||
}
|
||||
|
||||
private val entityList = HashSet<Entity>()
|
||||
private val entityList = LinkedHashSet<Entity>()
|
||||
|
||||
var drawingOutline = false; private set
|
||||
var drawNametag = false; private set
|
||||
private val shaderHelper = ShaderHelper(ResourceLocation("shaders/post/esp_outline.json"), "final")
|
||||
val frameBuffer = shaderHelper.getFrameBuffer("final")
|
||||
private val frameBuffer = shaderHelper.getFrameBuffer("final")
|
||||
|
||||
init {
|
||||
listener<RenderEntityEvent> {
|
||||
if (mode.value != ESPMode.SHADER || mc.renderManager.renderOutlines || !entityList.contains(it.entity)) return@listener
|
||||
|
||||
if (it.phase == Phase.PRE && hideOriginal) {
|
||||
// Steal it from Minecraft rendering kek
|
||||
prepareFrameBuffer()
|
||||
drawNametag = true
|
||||
}
|
||||
|
||||
if (it.phase == Phase.PERI) {
|
||||
if (!hideOriginal) {
|
||||
prepareFrameBuffer()
|
||||
mc.renderManager.getEntityRenderObject<Entity>(it.entity)?.doRender(it.entity, it.x, it.y, it.z, it.yaw, it.partialTicks)
|
||||
}
|
||||
|
||||
mc.framebuffer.bindFramebuffer(false)
|
||||
GlStateManager.disableOutlineMode()
|
||||
drawingOutline = false
|
||||
drawNametag = false
|
||||
listener<RenderEntityEvent.All> {
|
||||
if (it.phase == Phase.PRE
|
||||
&& mode.value == ESPMode.SHADER
|
||||
&& !mc.renderManager.renderOutlines
|
||||
&& hideOriginal
|
||||
&& entityList.contains(it.entity)) {
|
||||
it.cancel()
|
||||
}
|
||||
}
|
||||
|
||||
listener<RenderWorldEvent>(69420) {
|
||||
if (mode.value != ESPMode.SHADER) return@listener
|
||||
|
||||
GlStateManager.matrixMode(GL_PROJECTION)
|
||||
glPushMatrix()
|
||||
GlStateManager.matrixMode(GL_MODELVIEW)
|
||||
glPushMatrix()
|
||||
|
||||
shaderHelper.shader?.render(KamiTessellator.pTicks())
|
||||
|
||||
// Re-enable blend because shader rendering will disable it at the end
|
||||
GlStateManager.enableBlend()
|
||||
GlStateManager.disableDepth()
|
||||
|
||||
// Draw it on the main frame buffer
|
||||
mc.framebuffer.bindFramebuffer(false)
|
||||
frameBuffer?.framebufferRenderExt(mc.displayWidth, mc.displayHeight, false)
|
||||
|
||||
// Clean up the frame buffer
|
||||
frameBuffer?.framebufferClear()
|
||||
mc.framebuffer.bindFramebuffer(false)
|
||||
|
||||
GlStateManager.disableCull()
|
||||
GlStateManager.enableBlend()
|
||||
GlStateManager.enableDepth()
|
||||
GlStateManager.disableTexture2D()
|
||||
GlStateManager.depthMask(false)
|
||||
|
||||
GlStateManager.matrixMode(GL_PROJECTION)
|
||||
glPopMatrix()
|
||||
GlStateManager.matrixMode(GL_MODELVIEW)
|
||||
glPopMatrix()
|
||||
}
|
||||
}
|
||||
|
||||
private fun prepareFrameBuffer() {
|
||||
drawingOutline = true
|
||||
GlStateManager.enableOutlineMode(0xFFFFFF)
|
||||
frameBuffer?.bindFramebuffer(false)
|
||||
}
|
||||
|
||||
init {
|
||||
safeListener<EntityViewRenderEvent.FogColors> { event ->
|
||||
shaderHelper.shader?.listFrameBuffers?.forEach {
|
||||
it.setFramebufferColor(event.red, event.green, event.blue, 0.0f)
|
||||
}
|
||||
}
|
||||
|
||||
safeListener<RenderWorldEvent> {
|
||||
if (mc.renderManager.options == null) return@safeListener
|
||||
|
||||
safeListener<RenderWorldEvent>(69420) {
|
||||
when (mode.value) {
|
||||
ESPMode.BOX -> {
|
||||
val color = ColorHolder(r, g, b)
|
||||
|
@ -167,35 +109,104 @@ internal object ESP : Module(
|
|||
}
|
||||
renderer.render(true)
|
||||
}
|
||||
|
||||
ESPMode.SHADER -> {
|
||||
drawEntities()
|
||||
drawShader()
|
||||
}
|
||||
else -> {
|
||||
// Glow and Shader mode
|
||||
// Glow Mode
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun drawEntities() {
|
||||
// Clean up the frame buffer and bind it
|
||||
frameBuffer?.framebufferClear()
|
||||
frameBuffer?.bindFramebuffer(false)
|
||||
|
||||
val prevRenderOutlines = mc.renderManager.renderOutlines
|
||||
|
||||
GlStateUtils.texture2d(true)
|
||||
GlStateUtils.cull(true)
|
||||
|
||||
// Draw the entities into the framebuffer
|
||||
for (entity in entityList) {
|
||||
val renderer = mc.renderManager.getEntityRenderObject<Entity>(entity) ?: continue
|
||||
|
||||
val partialTicks = KamiTessellator.pTicks()
|
||||
val yaw = entity.prevRotationYaw + (entity.rotationYaw - entity.prevRotationYaw) * partialTicks
|
||||
val pos = EntityUtils.getInterpolatedPos(entity, partialTicks)
|
||||
.subtract(mc.renderManager.renderPosX, mc.renderManager.renderPosY, mc.renderManager.renderPosZ)
|
||||
|
||||
renderer.setRenderOutlines(true)
|
||||
renderer.doRender(entity, pos.x, pos.y, pos.z, yaw, partialTicks)
|
||||
renderer.setRenderOutlines(prevRenderOutlines)
|
||||
}
|
||||
|
||||
GlStateUtils.texture2d(false)
|
||||
}
|
||||
|
||||
private fun drawShader() {
|
||||
// Push matrix
|
||||
GlStateManager.matrixMode(GL_PROJECTION)
|
||||
GlStateManager.pushMatrix()
|
||||
GlStateManager.matrixMode(GL_MODELVIEW)
|
||||
GlStateManager.pushMatrix()
|
||||
|
||||
shaderHelper.shader?.render(KamiTessellator.pTicks())
|
||||
|
||||
// Re-enable blend because shader rendering will disable it at the end
|
||||
GlStateUtils.blend(true)
|
||||
GlStateUtils.depth(false)
|
||||
|
||||
// Draw it on the main frame buffer
|
||||
mc.framebuffer.bindFramebuffer(false)
|
||||
frameBuffer?.framebufferRenderExt(mc.displayWidth, mc.displayHeight, false)
|
||||
|
||||
// Revert states
|
||||
GlStateUtils.blend(true)
|
||||
GlStateUtils.depth(true)
|
||||
GlStateUtils.texture2d(false)
|
||||
GlStateManager.depthMask(false)
|
||||
GlStateUtils.cull(false)
|
||||
|
||||
// Revert matrix
|
||||
GlStateManager.matrixMode(GL_PROJECTION)
|
||||
GlStateManager.popMatrix()
|
||||
GlStateManager.matrixMode(GL_MODELVIEW)
|
||||
GlStateManager.popMatrix()
|
||||
}
|
||||
|
||||
init {
|
||||
safeListener<TickEvent.ClientTickEvent> {
|
||||
entityList.clear()
|
||||
entityList.addAll(getEntityList())
|
||||
|
||||
if (mode.value == ESPMode.GLOW) {
|
||||
if (entityList.isNotEmpty()) {
|
||||
for (shader in mc.renderGlobal.entityOutlineShader.listShaders) {
|
||||
shader.shaderManager.getShaderUniform("Radius")?.set(width)
|
||||
}
|
||||
when (mode.value) {
|
||||
ESPMode.GLOW -> {
|
||||
if (entityList.isNotEmpty()) {
|
||||
for (shader in mc.renderGlobal.entityOutlineShader.listShaders) {
|
||||
shader.shaderManager.getShaderUniform("Radius")?.set(width)
|
||||
}
|
||||
|
||||
for (entity in world.loadedEntityList) { // Set glow for entities in the list. Remove glow for entities not in the list
|
||||
entity.isGlowing = entityList.contains(entity)
|
||||
for (entity in world.loadedEntityList) { // Set glow for entities in the list. Remove glow for entities not in the list
|
||||
entity.isGlowing = entityList.contains(entity)
|
||||
}
|
||||
} else {
|
||||
resetGlow()
|
||||
}
|
||||
} else {
|
||||
resetGlow()
|
||||
}
|
||||
} else if (mode.value == ESPMode.SHADER) {
|
||||
shaderHelper.shader?.let {
|
||||
for (shader in it.listShaders) {
|
||||
setShaderSettings(shader)
|
||||
ESPMode.SHADER -> {
|
||||
shaderHelper.shader?.let {
|
||||
for (shader in it.listShaders) {
|
||||
setShaderSettings(shader)
|
||||
}
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
// Box Mode
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -240,8 +251,6 @@ internal object ESP : Module(
|
|||
}
|
||||
|
||||
mode.listeners.add {
|
||||
drawingOutline = false
|
||||
drawNametag = false
|
||||
resetGlow()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,8 @@ import org.kamiblue.client.util.graphics.font.*
|
|||
import org.kamiblue.client.util.items.originalName
|
||||
import org.kamiblue.client.util.math.Vec2d
|
||||
import org.kamiblue.client.util.threads.safeListener
|
||||
import org.kamiblue.commons.extension.ceilToInt
|
||||
import org.kamiblue.commons.extension.floorToInt
|
||||
import org.kamiblue.commons.utils.MathUtils
|
||||
import org.kamiblue.event.listener.listener
|
||||
import org.lwjgl.opengl.GL11.*
|
||||
|
@ -98,7 +100,6 @@ internal object Nametags : Module(
|
|||
private val bText = setting("Text Blue", 255, 0..255, 1, { page.value == Page.RENDERING })
|
||||
private val aText = setting("Text Alpha", 255, 0..255, 1, { page.value == Page.RENDERING })
|
||||
private val customFont = setting("Custom Font", true, { page.value == Page.RENDERING })
|
||||
private val textShadow = setting("Text Shadow", true, { page.value == Page.RENDERING })
|
||||
private val yOffset = setting("Y Offset", 0.5f, -2.5f..2.5f, 0.05f, { page.value == Page.RENDERING })
|
||||
private val scale = setting("Scale", 1f, 0.25f..5f, 0.25f, { page.value == Page.RENDERING })
|
||||
private val distScaleFactor = setting("Distance Scale Factor", 0.0f, 0.0f..1.0f, 0.05f, { page.value == Page.RENDERING })
|
||||
|
@ -137,36 +138,56 @@ internal object Nametags : Module(
|
|||
listener<RenderOverlayEvent> {
|
||||
if (entityMap.isEmpty() && itemMap.isEmpty()) return@listener
|
||||
GlStateUtils.rescaleActual()
|
||||
|
||||
val camPos = KamiTessellator.camPos
|
||||
val vertexHelper = VertexHelper(GlStateUtils.useVbo())
|
||||
val xRange = 0..mc.displayWidth
|
||||
val yRange = 0..mc.displayHeight
|
||||
|
||||
for ((entity, textComponent) in entityMap) {
|
||||
val pos = EntityUtils.getInterpolatedPos(entity, KamiTessellator.pTicks()).add(0.0, (entity.height + yOffset.value).toDouble(), 0.0)
|
||||
val screenPos = ProjectionUtils.toScreenPos(pos)
|
||||
val dist = camPos.distanceTo(pos).toFloat() * 0.2f
|
||||
val distFactor = if (distScaleFactor.value == 0f) 1f else max(1f / (dist * distScaleFactor.value + 1f), minDistScale.value)
|
||||
drawNametag(screenPos, (scale.value * 2f) * distFactor, vertexHelper, nameFrame.value, textComponent)
|
||||
drawItems(screenPos, (scale.value * 2f) * distFactor, vertexHelper, entity, textComponent)
|
||||
|
||||
if (drawNametag(screenPos, (scale.value * 2f) * distFactor, xRange, yRange, vertexHelper, nameFrame.value, textComponent)) {
|
||||
drawItems(screenPos, (scale.value * 2f) * distFactor, vertexHelper, entity, textComponent)
|
||||
}
|
||||
}
|
||||
|
||||
for (itemGroup in itemMap) {
|
||||
val pos = itemGroup.getCenter(KamiTessellator.pTicks()).add(0.0, yOffset.value.toDouble(), 0.0)
|
||||
val screenPos = ProjectionUtils.toScreenPos(pos)
|
||||
val dist = camPos.distanceTo(pos).toFloat() * 0.2f
|
||||
val distFactor = if (distScaleFactor.value == 0f) 1f else max(1f / (dist * distScaleFactor.value + 1f), minDistScale.value)
|
||||
drawNametag(screenPos, (scale.value * 2f) * distFactor, vertexHelper, dropItemFrame.value, itemGroup.textComponent)
|
||||
|
||||
drawNametag(screenPos, (scale.value * 2f) * distFactor, xRange, yRange, vertexHelper, dropItemFrame.value, itemGroup.textComponent)
|
||||
}
|
||||
|
||||
GlStateUtils.rescaleMc()
|
||||
}
|
||||
}
|
||||
|
||||
private fun drawNametag(screenPos: Vec3d, scale: Float, vertexHelper: VertexHelper, drawFrame: Boolean, textComponent: TextComponent) {
|
||||
private fun drawNametag(screenPos: Vec3d, scale: Float, xRange: IntRange, yRange: IntRange, vertexHelper: VertexHelper, drawFrame: Boolean, textComponent: TextComponent): Boolean {
|
||||
val halfWidth = textComponent.getWidth(customFont.value) / 2.0 + margins.value + 2.0
|
||||
val halfHeight = textComponent.getHeight(2, true, customFont.value) / 2.0 + margins.value + 2.0
|
||||
|
||||
val scaledHalfWidth = halfWidth * scale
|
||||
val scaledHalfHeight = halfHeight * scale
|
||||
|
||||
if ((screenPos.x - scaledHalfWidth).floorToInt() !in xRange
|
||||
&& (screenPos.x + scaledHalfWidth).ceilToInt() !in xRange
|
||||
|| (screenPos.y - scaledHalfHeight).floorToInt() !in yRange
|
||||
&& (screenPos.y + scaledHalfHeight).ceilToInt() !in yRange) return false
|
||||
|
||||
glPushMatrix()
|
||||
glTranslatef(screenPos.x.toFloat(), screenPos.y.toFloat(), 0f)
|
||||
glScalef(scale, scale, 1f)
|
||||
val halfWidth = textComponent.getWidth(customFont.value) / 2.0 + margins.value + 2.0
|
||||
val halfHeight = textComponent.getHeight(2, true, customFont.value) / 2.0 + margins.value + 2.0
|
||||
if (drawFrame) drawFrame(vertexHelper, Vec2d(-halfWidth, -halfHeight), Vec2d(halfWidth, halfHeight))
|
||||
textComponent.draw(drawShadow = textShadow.value, skipEmptyLine = true, horizontalAlign = HAlign.CENTER, verticalAlign = VAlign.CENTER, customFont = customFont.value)
|
||||
textComponent.draw(skipEmptyLine = true, horizontalAlign = HAlign.CENTER, verticalAlign = VAlign.CENTER, customFont = customFont.value)
|
||||
glPopMatrix()
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
private fun drawItems(screenPos: Vec3d, nameTagScale: Float, vertexHelper: VertexHelper, entity: Entity, textComponent: TextComponent) {
|
||||
|
@ -239,21 +260,21 @@ internal object Nametags : Module(
|
|||
val color = healthColorGradient.get(duraPercentage)
|
||||
val text = duraPercentage.roundToInt().toString()
|
||||
val textWidth = FontRenderAdapter.getStringWidth(text, customFont = customFont.value)
|
||||
FontRenderAdapter.drawString(text, 8f - textWidth / 2f, 17f, textShadow.value, color, customFont = customFont.value)
|
||||
FontRenderAdapter.drawString(text, 8f - textWidth / 2f, 17f, color = color, customFont = customFont.value)
|
||||
}
|
||||
|
||||
if (count.value && itemStack.count > 1) {
|
||||
val itemCount = itemStack.count.toString()
|
||||
glTranslatef(0f, 0f, 60f)
|
||||
val stringWidth = 17f - FontRenderAdapter.getStringWidth(itemCount, customFont = customFont.value)
|
||||
FontRenderAdapter.drawString(itemCount, stringWidth, 9f, textShadow.value, customFont = customFont.value)
|
||||
FontRenderAdapter.drawString(itemCount, stringWidth, 9f, customFont = customFont.value)
|
||||
glTranslatef(0f, 0f, -60f)
|
||||
}
|
||||
|
||||
glTranslatef(0f, -2f, 0f)
|
||||
if (enchantment.value) {
|
||||
val scale = if (customFont.value) 0.6f else 0.5f
|
||||
enchantmentText.draw(lineSpace = 2, scale = scale, drawShadow = textShadow.value, verticalAlign = VAlign.BOTTOM, customFont = customFont.value)
|
||||
enchantmentText.draw(lineSpace = 2, scale = scale, verticalAlign = VAlign.BOTTOM, customFont = customFont.value)
|
||||
}
|
||||
|
||||
glTranslatef(28f, 2f, 0f)
|
||||
|
|
|
@ -133,7 +133,7 @@ internal object NoRender : Module(
|
|||
}
|
||||
}
|
||||
|
||||
listener<RenderEntityEvent> {
|
||||
listener<RenderEntityEvent.All> {
|
||||
if (it.phase != Phase.PRE) return@listener
|
||||
|
||||
if (entityList.contains(it.entity.javaClass)
|
||||
|
|
|
@ -1,9 +1,14 @@
|
|||
package org.kamiblue.client.util
|
||||
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.client.entity.EntityPlayerSP
|
||||
import net.minecraft.entity.Entity
|
||||
import net.minecraft.init.MobEffects
|
||||
import net.minecraft.util.MovementInput
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import org.kamiblue.client.event.SafeClientEvent
|
||||
import org.kamiblue.client.util.EntityUtils.flooredPosition
|
||||
import org.kamiblue.client.util.math.VectorUtils.toVec3d
|
||||
import kotlin.math.cos
|
||||
import kotlin.math.hypot
|
||||
import kotlin.math.sin
|
||||
|
@ -50,4 +55,42 @@ object MovementUtils {
|
|||
player.getActivePotionEffect(MobEffects.SPEED)?.let {
|
||||
speed * (1.0 + (it.amplifier + 1) * 0.2)
|
||||
} ?: speed
|
||||
|
||||
fun EntityPlayerSP.centerPlayer(): Boolean {
|
||||
val center = this.flooredPosition.toVec3d(0.5, 0.0, 0.5)
|
||||
val centered = isCentered(this.flooredPosition)
|
||||
|
||||
if (!centered) {
|
||||
this.motionX = (center.x - this.posX) / 2.0
|
||||
this.motionZ = (center.z - this.posZ) / 2.0
|
||||
|
||||
val speed = this.speed
|
||||
|
||||
if (speed > 0.2805) {
|
||||
val multiplier = 0.2805 / speed
|
||||
this.motionX *= multiplier
|
||||
this.motionZ *= multiplier
|
||||
}
|
||||
}
|
||||
|
||||
return centered
|
||||
}
|
||||
|
||||
fun Entity.isCentered(pos: BlockPos) =
|
||||
this.posX in pos.x + 0.31..pos.x + 0.69
|
||||
&& this.posZ in pos.z + 0.31..pos.z + 0.69
|
||||
|
||||
fun MovementInput.resetMove() {
|
||||
moveForward = 0.0f
|
||||
moveStrafe = 0.0f
|
||||
forwardKeyDown = false
|
||||
backKeyDown = false
|
||||
leftKeyDown = false
|
||||
rightKeyDown = false
|
||||
}
|
||||
|
||||
fun MovementInput.resetJumpSneak() {
|
||||
jump = false
|
||||
sneak = false
|
||||
}
|
||||
}
|
|
@ -4,11 +4,9 @@ import net.minecraft.block.Block
|
|||
import net.minecraft.entity.Entity
|
||||
import net.minecraft.init.Blocks
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.util.math.Vec3d
|
||||
import org.kamiblue.client.event.SafeClientEvent
|
||||
import org.kamiblue.client.util.EntityUtils.flooredPosition
|
||||
import org.kamiblue.client.util.Wrapper
|
||||
import kotlin.math.round
|
||||
|
||||
object SurroundUtils {
|
||||
private val mc = Wrapper.minecraft
|
||||
|
@ -21,13 +19,6 @@ object SurroundUtils {
|
|||
BlockPos(-1, 0, 0) // west
|
||||
)
|
||||
|
||||
val surroundOffsetNoFloor = arrayOf(
|
||||
BlockPos(0, 0, -1), // north
|
||||
BlockPos(1, 0, 0), // east
|
||||
BlockPos(0, 0, 1), // south
|
||||
BlockPos(-1, 0, 0) // west
|
||||
)
|
||||
|
||||
fun SafeClientEvent.checkHole(entity: Entity) =
|
||||
checkHole(entity.flooredPosition)
|
||||
|
||||
|
@ -51,38 +42,10 @@ object SurroundUtils {
|
|||
return type
|
||||
}
|
||||
|
||||
fun checkBlock(block: Block): Boolean {
|
||||
private fun checkBlock(block: Block): Boolean {
|
||||
return block == Blocks.BEDROCK || block == Blocks.OBSIDIAN || block == Blocks.ENDER_CHEST || block == Blocks.ANVIL
|
||||
}
|
||||
|
||||
fun centerPlayer(tp: Boolean): Boolean {
|
||||
val centerDiff = getCenterDiff()
|
||||
val centered = isCentered()
|
||||
if (!centered) {
|
||||
if (tp) {
|
||||
val posX = mc.player.posX + (centerDiff.x).coerceIn(-0.2, 0.2)
|
||||
val posZ = mc.player.posZ + (centerDiff.z).coerceIn(-0.2, 0.2)
|
||||
mc.player.setPosition(posX, mc.player.posY, posZ)
|
||||
} else {
|
||||
mc.player.motionX = (centerDiff.x / 2.0).coerceIn(-0.2, 0.2)
|
||||
mc.player.motionZ = (centerDiff.z / 2.0).coerceIn(-0.2, 0.2)
|
||||
}
|
||||
}
|
||||
return centered
|
||||
}
|
||||
|
||||
private fun isCentered(): Boolean {
|
||||
return getCenterDiff().length() < 0.2
|
||||
}
|
||||
|
||||
private fun getCenterDiff(): Vec3d {
|
||||
return Vec3d(roundToCenter(mc.player.posX), mc.player.posY, roundToCenter(mc.player.posZ)).subtract(mc.player.positionVector)
|
||||
}
|
||||
|
||||
private fun roundToCenter(doubleIn: Double): Double {
|
||||
return round(doubleIn + 0.5) - 0.5
|
||||
}
|
||||
|
||||
enum class HoleType {
|
||||
NONE, OBBY, BEDROCK
|
||||
}
|
||||
|
|
|
@ -29,10 +29,6 @@ object GlStateUtils {
|
|||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
var colorLock = false
|
||||
private set
|
||||
|
||||
fun useVbo(): Boolean {
|
||||
return mc.gameSettings.useVbo
|
||||
}
|
||||
|
@ -102,11 +98,6 @@ object GlStateUtils {
|
|||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun colorLock(state: Boolean) {
|
||||
colorLock = state
|
||||
}
|
||||
|
||||
fun rescaleActual() {
|
||||
rescale(Wrapper.minecraft.displayWidth.toDouble(), Wrapper.minecraft.displayHeight.toDouble())
|
||||
}
|
||||
|
|
|
@ -18,8 +18,8 @@ import org.kamiblue.client.util.threads.onMainThreadSafe
|
|||
* or slot 0 if none
|
||||
*/
|
||||
inline fun <reified I : Block> SafeClientEvent.swapToBlockOrMove(
|
||||
crossinline predicateItem: (ItemStack) -> Boolean = { true },
|
||||
noinline predicateSlot: (ItemStack) -> Boolean = { true }
|
||||
predicateItem: (ItemStack) -> Boolean = { true },
|
||||
predicateSlot: (ItemStack) -> Boolean = { true }
|
||||
): Boolean {
|
||||
return if (swapToBlock<I>(predicateItem)) {
|
||||
true
|
||||
|
@ -59,8 +59,8 @@ fun SafeClientEvent.swapToBlockOrMove(
|
|||
* or slot 0 if none
|
||||
*/
|
||||
inline fun <reified I : Item> SafeClientEvent.swapToItemOrMove(
|
||||
crossinline predicateItem: (ItemStack) -> Boolean = { true },
|
||||
noinline predicateSlot: (ItemStack) -> Boolean = { true }
|
||||
predicateItem: (ItemStack) -> Boolean = { true },
|
||||
predicateSlot: (ItemStack) -> Boolean = { true }
|
||||
): Boolean {
|
||||
return if (swapToItem<I>(predicateItem)) {
|
||||
true
|
||||
|
@ -117,7 +117,7 @@ fun SafeClientEvent.swapToItemOrMove(
|
|||
/**
|
||||
* Try to swap selected hotbar slot to [I] that matches with [predicate]
|
||||
*/
|
||||
inline fun <reified I : Block> SafeClientEvent.swapToBlock(crossinline predicate: (ItemStack) -> Boolean = { true }): Boolean {
|
||||
inline fun <reified I : Block> SafeClientEvent.swapToBlock(predicate: (ItemStack) -> Boolean = { true }): Boolean {
|
||||
return player.hotbarSlots.firstBlock<I, HotbarSlot>(predicate)?.let {
|
||||
swapToSlot(it)
|
||||
true
|
||||
|
@ -137,7 +137,7 @@ fun SafeClientEvent.swapToBlock(block: Block, predicate: (ItemStack) -> Boolean
|
|||
/**
|
||||
* Try to swap selected hotbar slot to [I] that matches with [predicate]
|
||||
*/
|
||||
inline fun <reified I : Item> SafeClientEvent.swapToItem(crossinline predicate: (ItemStack) -> Boolean = { true }): Boolean {
|
||||
inline fun <reified I : Item> SafeClientEvent.swapToItem(predicate: (ItemStack) -> Boolean = { true }): Boolean {
|
||||
return player.hotbarSlots.firstItem<I, HotbarSlot>(predicate)?.let {
|
||||
swapToSlot(it)
|
||||
true
|
||||
|
@ -184,7 +184,7 @@ fun SafeClientEvent.swapToSlot(slot: Int) {
|
|||
* Swaps the item in [slotFrom] with the first empty hotbar slot
|
||||
* or matches with [predicate] or slot 0 if none of those found
|
||||
*/
|
||||
fun SafeClientEvent.moveToHotbar(slotFrom: Slot, predicate: (ItemStack) -> Boolean): Short {
|
||||
inline fun SafeClientEvent.moveToHotbar(slotFrom: Slot, predicate: (ItemStack) -> Boolean): Short {
|
||||
return moveToHotbar(slotFrom.slotNumber, predicate)
|
||||
}
|
||||
|
||||
|
@ -192,7 +192,7 @@ fun SafeClientEvent.moveToHotbar(slotFrom: Slot, predicate: (ItemStack) -> Boole
|
|||
* Swaps the item in [slotFrom] with the first empty hotbar slot
|
||||
* or matches with [predicate] or slot 0 if none of those found
|
||||
*/
|
||||
fun SafeClientEvent.moveToHotbar(slotFrom: Int, predicate: (ItemStack) -> Boolean): Short {
|
||||
inline fun SafeClientEvent.moveToHotbar(slotFrom: Int, predicate: (ItemStack) -> Boolean): Short {
|
||||
val hotbarSlots = player.hotbarSlots
|
||||
val slotTo = hotbarSlots.firstItem(Items.AIR)?.hotbarSlot
|
||||
?: hotbarSlots.firstByStack(predicate)?.hotbarSlot ?: 0
|
||||
|
|
|
@ -41,7 +41,7 @@ fun Container.getSlots(range: IntRange): List<Slot> =
|
|||
fun Iterable<Slot>.countEmpty() =
|
||||
count { it.stack.isEmpty }
|
||||
|
||||
inline fun <reified B : Block> Iterable<Slot>.countBlock(crossinline predicate: (ItemStack) -> Boolean = { true }) =
|
||||
inline fun <reified B : Block> Iterable<Slot>.countBlock(predicate: (ItemStack) -> Boolean = { true }) =
|
||||
countByStack { itemStack ->
|
||||
itemStack.item.let { it is ItemBlock && it.block is B } && predicate(itemStack)
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ fun Iterable<Slot>.countBlock(block: Block, predicate: (ItemStack) -> Boolean =
|
|||
itemStack.item.let { it is ItemBlock && it.block == block } && predicate(itemStack)
|
||||
}
|
||||
|
||||
inline fun <reified I : Item> Iterable<Slot>.countItem(crossinline predicate: (ItemStack) -> Boolean = { true }) =
|
||||
inline fun <reified I : Item> Iterable<Slot>.countItem(predicate: (ItemStack) -> Boolean = { true }) =
|
||||
countByStack { it.item is I && predicate(it) }
|
||||
|
||||
fun Iterable<Slot>.countItem(item: Item, predicate: (ItemStack) -> Boolean = { true }) =
|
||||
|
@ -60,7 +60,7 @@ fun Iterable<Slot>.countItem(item: Item, predicate: (ItemStack) -> Boolean = { t
|
|||
fun Iterable<Slot>.countID(itemID: Int, predicate: (ItemStack) -> Boolean = { true }) =
|
||||
countByStack { it.item.id == itemID && predicate(it) }
|
||||
|
||||
fun Iterable<Slot>.countByStack(predicate: (ItemStack) -> Boolean = { true }) =
|
||||
inline fun Iterable<Slot>.countByStack(predicate: (ItemStack) -> Boolean = { true }) =
|
||||
sumBy { slot ->
|
||||
slot.stack.let { if (predicate(it)) it.count else 0 }
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ fun Iterable<Slot>.countByStack(predicate: (ItemStack) -> Boolean = { true }) =
|
|||
fun <T : Slot> Iterable<T>.firstEmpty() =
|
||||
firstByStack { it.isEmpty }
|
||||
|
||||
inline fun <reified B : Block, T : Slot> Iterable<T>.firstBlock(crossinline predicate: (ItemStack) -> Boolean = { true }) =
|
||||
inline fun <reified B : Block, T : Slot> Iterable<T>.firstBlock(predicate: (ItemStack) -> Boolean = { true }) =
|
||||
firstByStack { itemStack ->
|
||||
itemStack.item.let { it is ItemBlock && it.block is B } && predicate(itemStack)
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ fun <T : Slot> Iterable<T>.firstBlock(block: Block, predicate: (ItemStack) -> Bo
|
|||
itemStack.item.let { it is ItemBlock && it.block == block } && predicate(itemStack)
|
||||
}
|
||||
|
||||
inline fun <reified I : Item, T : Slot> Iterable<T>.firstItem(crossinline predicate: (ItemStack) -> Boolean = { true }) =
|
||||
inline fun <reified I : Item, T : Slot> Iterable<T>.firstItem(predicate: (ItemStack) -> Boolean = { true }) =
|
||||
firstByStack {
|
||||
it.item is I && predicate(it)
|
||||
}
|
||||
|
@ -94,14 +94,14 @@ fun <T : Slot> Iterable<T>.firstID(itemID: Int, predicate: (ItemStack) -> Boolea
|
|||
it.item.id == itemID && predicate(it)
|
||||
}
|
||||
|
||||
fun <T : Slot> Iterable<T>.firstByStack(predicate: (ItemStack) -> Boolean): T? =
|
||||
inline fun <T : Slot> Iterable<T>.firstByStack(predicate: (ItemStack) -> Boolean): T? =
|
||||
firstOrNull { predicate(it.stack) }
|
||||
|
||||
|
||||
inline fun <reified B : Block, T : Slot> Iterable<T>.forEmpty() =
|
||||
filterByStack { it.isEmpty }
|
||||
|
||||
inline fun <reified B : Block, T : Slot> Iterable<T>.filterByBlock(crossinline predicate: (ItemStack) -> Boolean = { true }) =
|
||||
inline fun <reified B : Block, T : Slot> Iterable<T>.filterByBlock(predicate: (ItemStack) -> Boolean = { true }) =
|
||||
filterByStack { itemStack ->
|
||||
itemStack.item.let { it is ItemBlock && it.block is B } && predicate(itemStack)
|
||||
}
|
||||
|
@ -111,7 +111,7 @@ fun <T : Slot> Iterable<T>.filterByBlock(block: Block, predicate: (ItemStack) ->
|
|||
itemStack.item.let { it is ItemBlock && it.block == block } && predicate(itemStack)
|
||||
}
|
||||
|
||||
inline fun <reified I : Item, T : Slot> Iterable<T>.filterByItem(crossinline predicate: (ItemStack) -> Boolean = { true }) =
|
||||
inline fun <reified I : Item, T : Slot> Iterable<T>.filterByItem(predicate: (ItemStack) -> Boolean = { true }) =
|
||||
filterByStack {
|
||||
it.item is I && predicate(it)
|
||||
}
|
||||
|
@ -124,7 +124,7 @@ fun <T : Slot> Iterable<T>.filterByItem(item: Item, predicate: (ItemStack) -> Bo
|
|||
fun <T : Slot> Iterable<T>.filterByID(itemID: Int, predicate: (ItemStack) -> Boolean = { true }) =
|
||||
filterByStack { it.item.id == itemID && predicate(it) }
|
||||
|
||||
fun <T : Slot> Iterable<T>.filterByStack(predicate: (ItemStack) -> Boolean = { true }) =
|
||||
inline fun <T : Slot> Iterable<T>.filterByStack(predicate: (ItemStack) -> Boolean = { true }) =
|
||||
filter { predicate(it.stack) }
|
||||
|
||||
fun Slot.toHotbarSlotOrNull() =
|
||||
|
|
|
@ -29,14 +29,14 @@ object MainThreadExecutor {
|
|||
runBlocking {
|
||||
mutex.withLock {
|
||||
jobs.forEach {
|
||||
launch { it.run() }
|
||||
it.run()
|
||||
}
|
||||
jobs.clear()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun <T> add(block: suspend () -> T) =
|
||||
suspend fun <T> add(block: () -> T) =
|
||||
MainThreadJob(block).apply {
|
||||
if (Wrapper.minecraft.isCallingFromMinecraftThread) {
|
||||
run()
|
||||
|
@ -47,10 +47,10 @@ object MainThreadExecutor {
|
|||
}
|
||||
}.deferred
|
||||
|
||||
private class MainThreadJob<T>(private val block: suspend () -> T) {
|
||||
private class MainThreadJob<T>(private val block: () -> T) {
|
||||
val deferred = CompletableDeferred<T>()
|
||||
|
||||
suspend fun run() {
|
||||
fun run() {
|
||||
deferred.completeWith(
|
||||
runCatching { block.invoke() }
|
||||
)
|
||||
|
|
|
@ -11,11 +11,19 @@ import org.kamiblue.event.listener.DEFAULT_PRIORITY
|
|||
import org.kamiblue.event.listener.Listener
|
||||
|
||||
inline fun <reified T : Any> Any.safeAsyncListener(noinline function: suspend SafeClientEvent.(T) -> Unit) {
|
||||
ListenerManager.register(this, AsyncListener(this, T::class.java) { runSafeSuspend { function(it) } })
|
||||
this.safeAsyncListener(T::class.java, function)
|
||||
}
|
||||
|
||||
fun <T : Any> Any.safeAsyncListener(clazz: Class<T>, function: suspend SafeClientEvent.(T) -> Unit) {
|
||||
ListenerManager.register(this, AsyncListener(this, clazz) { runSafeSuspend { function(it) } })
|
||||
}
|
||||
|
||||
inline fun <reified T : Any> Any.safeListener(priority: Int = DEFAULT_PRIORITY, noinline function: SafeClientEvent.(T) -> Unit) {
|
||||
ListenerManager.register(this, Listener(this, T::class.java, priority) { runSafe { function(it) } })
|
||||
this.safeListener(priority, T::class.java, function)
|
||||
}
|
||||
|
||||
fun <T : Any> Any.safeListener(priority: Int = DEFAULT_PRIORITY ,clazz: Class<T>, function: SafeClientEvent.(T) -> Unit) {
|
||||
ListenerManager.register(this, Listener(this, clazz, priority) { runSafe { function(it) } })
|
||||
}
|
||||
|
||||
fun ClientEvent.toSafe() =
|
||||
|
@ -26,11 +34,11 @@ fun ClientExecuteEvent.toSafe() =
|
|||
if (world != null && player != null && playerController != null && connection != null) SafeExecuteEvent(world, player, playerController, connection, this)
|
||||
else null
|
||||
|
||||
fun runSafe(block: SafeClientEvent.() -> Unit) {
|
||||
inline fun runSafe(block: SafeClientEvent.() -> Unit) {
|
||||
ClientEvent().toSafe()?.let { block(it) }
|
||||
}
|
||||
|
||||
fun <R> runSafeR(block: SafeClientEvent.() -> R): R? {
|
||||
inline fun <R> runSafeR(block: SafeClientEvent.() -> R): R? {
|
||||
return ClientEvent().toSafe()?.let { block(it) }
|
||||
}
|
||||
|
||||
|
@ -46,7 +54,7 @@ suspend fun <R> runSafeSuspend(block: suspend SafeClientEvent.() -> R): R? {
|
|||
*
|
||||
* @see [onMainThread]
|
||||
*/
|
||||
suspend fun <T> onMainThreadSafe(block: suspend SafeClientEvent.() -> T) =
|
||||
suspend fun <T> onMainThreadSafe(block: SafeClientEvent.() -> T) =
|
||||
onMainThread { ClientEvent().toSafe()?.block() }
|
||||
|
||||
/**
|
||||
|
@ -56,5 +64,5 @@ suspend fun <T> onMainThreadSafe(block: suspend SafeClientEvent.() -> T) =
|
|||
*
|
||||
* @see [onMainThreadSafe]
|
||||
*/
|
||||
suspend fun <T> onMainThread(block: suspend () -> T) =
|
||||
suspend fun <T> onMainThread(block: () -> T) =
|
||||
MainThreadExecutor.add(block)
|
||||
|
|
|
@ -52,22 +52,22 @@
|
|||
"render.MixinDebugRendererChunkBorder",
|
||||
"render.MixinEntityRenderer",
|
||||
"render.MixinFontRenderer",
|
||||
"render.MixinGlStateManager",
|
||||
"render.MixinItemRenderer",
|
||||
"render.MixinLayerArmorBase",
|
||||
"render.MixinLayerCape",
|
||||
"render.MixinLayerElytra",
|
||||
"render.MixinLayerHeldItem",
|
||||
"render.MixinMapItemRenderer",
|
||||
"render.MixinModelBiped",
|
||||
"render.MixinModelBoat",
|
||||
"render.MixinParticleManager",
|
||||
"render.MixinRender",
|
||||
"render.MixinRenderGlobal",
|
||||
"render.MixinRenderLivingBase",
|
||||
"render.MixinRenderManager",
|
||||
"render.MixinRenderPlayer",
|
||||
"render.MixinTileEntityRendererDispatcher",
|
||||
"render.MixinTileEntitySignRenderer",
|
||||
"render.MixinViewFrustum",
|
||||
"render.MixinVisGraph",
|
||||
"world.MixinBlockLiquid",
|
||||
"world.MixinBlockSoulSand",
|
||||
|
|
Loading…
Reference in New Issue