Skip to content

Commit

Permalink
Added Mob Owners and Ghost Hand (Closes CCBlueX#605)
Browse files Browse the repository at this point in the history
  • Loading branch information
superblaubeere27 committed Aug 1, 2021
1 parent 4f25029 commit 2d9230f
Show file tree
Hide file tree
Showing 11 changed files with 413 additions and 57 deletions.
69 changes: 69 additions & 0 deletions src/main/java/net/ccbluex/liquidbounce/common/TweakedMethods.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* This file is part of LiquidBounce (https://github.com/CCBlueX/LiquidBounce)
*
* Copyright (c) 2016 - 2021 CCBlueX
*
* LiquidBounce is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* LiquidBounce is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with LiquidBounce. If not, see <https://www.gnu.org/licenses/>.
*/

package net.ccbluex.liquidbounce.common;

import net.ccbluex.liquidbounce.features.module.modules.exploit.ModuleGhostHand;
import net.minecraft.block.BlockState;
import net.minecraft.fluid.FluidState;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.world.BlockView;
import net.minecraft.world.RaycastContext;

public class TweakedMethods {

public static BlockHitResult tweakedRaycast(BlockView blockView, RaycastContext context) {
if (ModuleGhostHand.INSTANCE.getEnabled()) {
var returned = (BlockHitResult) BlockView.raycast(context.getStart(), context.getEnd(), context, (contextx, pos) -> {
BlockState blockState = blockView.getBlockState(pos);

if (!ModuleGhostHand.INSTANCE.getTargetedBlocks().contains(blockState.getBlock()))
return null;

VoxelShape voxelShape = contextx.getBlockShape(blockState, blockView, pos);

return blockView.raycastBlock(contextx.getStart(), contextx.getEnd(), pos, voxelShape, blockState);
}, (contextx) -> null);

if (returned != null)
return returned;
}

return BlockView.raycast(context.getStart(), context.getEnd(), context, (contextx, pos) -> {
BlockState blockState = blockView.getBlockState(pos);
FluidState fluidState = blockView.getFluidState(pos);
Vec3d vec3d = contextx.getStart();
Vec3d vec3d2 = contextx.getEnd();
VoxelShape voxelShape = contextx.getBlockShape(blockState, blockView, pos);
BlockHitResult blockHitResult = blockView.raycastBlock(vec3d, vec3d2, pos, voxelShape, blockState);
VoxelShape voxelShape2 = contextx.getFluidShape(fluidState, blockView, pos);
BlockHitResult blockHitResult2 = voxelShape2.raycast(vec3d, vec3d2, pos);
double d = blockHitResult == null ? Double.MAX_VALUE : contextx.getStart().squaredDistanceTo(blockHitResult.getPos());
double e = blockHitResult2 == null ? Double.MAX_VALUE : contextx.getStart().squaredDistanceTo(blockHitResult2.getPos());
return d <= e ? blockHitResult : blockHitResult2;
}, contextx -> {
Vec3d vec3d = contextx.getStart().subtract(contextx.getEnd());
return BlockHitResult.createMissed(contextx.getEnd(), Direction.getFacing(vec3d.x, vec3d.y, vec3d.z), new BlockPos(contextx.getEnd()));
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* This file is part of LiquidBounce (https://github.com/CCBlueX/LiquidBounce)
*
* Copyright (c) 2016 - 2021 CCBlueX
*
* LiquidBounce is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* LiquidBounce is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with LiquidBounce. If not, see <https://www.gnu.org/licenses/>.
*/

package net.ccbluex.liquidbounce.injection.mixins.minecraft.block;

import net.ccbluex.liquidbounce.common.TweakedMethods;
import net.minecraft.block.BlockState;
import net.minecraft.fluid.FluidState;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.world.BlockView;
import net.minecraft.world.RaycastContext;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow;

import java.util.function.BiFunction;
import java.util.function.Function;

@Mixin(BlockView.class)
public interface MixinBlockView {

@Shadow
static <T, C> T raycast(Vec3d start, Vec3d end, C context, BiFunction<C, BlockPos, T> blockHitFactory, Function<C, T> missFactory) {
return null;
}

@Shadow
BlockState getBlockState(BlockPos pos);

@Shadow @Nullable BlockHitResult raycastBlock(Vec3d start, Vec3d end, BlockPos pos, VoxelShape shape, BlockState state);

@Shadow FluidState getFluidState(BlockPos pos);

/**
* @author superblaubeere27
*/
@Overwrite
default BlockHitResult raycast(RaycastContext context) {
return TweakedMethods.tweakedRaycast((BlockView) this, context);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,66 @@

package net.ccbluex.liquidbounce.injection.mixins.minecraft.render;

import net.ccbluex.liquidbounce.features.module.modules.render.ModuleMobOwners;
import net.ccbluex.liquidbounce.features.module.modules.render.ModuleNametags;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.entity.EntityRenderDispatcher;
import net.minecraft.client.render.entity.EntityRenderer;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.Entity;
import net.minecraft.text.Text;
import net.minecraft.util.math.Matrix4f;
import org.spongepowered.asm.mixin.Final;
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;

@Mixin(EntityRenderer.class)
public class MixinEntityRenderer<T extends Entity> {
public abstract class MixinEntityRenderer<T extends Entity> {

@Shadow @Final protected EntityRenderDispatcher dispatcher;

@Shadow public abstract TextRenderer getTextRenderer();

@Inject(method = "render", at = @At("HEAD"), cancellable = true)
private void renderMobOwners(T entity, float yaw, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, CallbackInfo ci) {
var ownerName = ModuleMobOwners.INSTANCE.getOwnerInfoText(entity);

if (ownerName != null) {
double d = this.dispatcher.getSquaredDistanceToCamera(entity);

if (d > 4096.0) {
return;
}

float f = entity.getHeight() / 2.0F;

matrices.push();
matrices.translate(0.0D, f, 0.0D);
matrices.multiply(this.dispatcher.getRotation());
matrices.scale(-0.025F, -0.025F, 0.025F);

Matrix4f matrix4f = matrices.peek().getModel();

float g = MinecraftClient.getInstance().options.getTextBackgroundOpacity(0.25F);
int j = (int)(g * 255.0F) << 24;
TextRenderer textRenderer = this.getTextRenderer();
float h = (float)(-textRenderer.getWidth(ownerName) / 2);

// textRenderer.draw(ownerName, h, (float) 0, 553648127, false, matrix4f, vertexConsumers, true, j, light);
textRenderer.draw(ownerName, h, 0, -1, false, matrix4f, vertexConsumers, true, j, light);


matrices.pop();
}
}

@Inject(method = "renderLabelIfPresent", at = @At("HEAD"), cancellable = true)
private void disableDuplicateNametags(T entity, Text text, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, CallbackInfo ci) {
private void disableDuplicateNametagsAndInjectMobOwners(T entity, Text text, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, CallbackInfo ci) {
// Don't render nametags
if (ModuleNametags.INSTANCE.getEnabled() && ModuleNametags.shouldRenderNametag(entity))
ci.cancel();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,9 @@ object ModuleManager : Listenable, Iterable<Module> by modules {
ModuleAutoSoup,
ModuleNotifier,
ModuleHoleESP,
ModuleNoSignRender
ModuleNoSignRender,
ModuleMobOwners,
ModuleGhostHand
)

builtin.apply {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* This file is part of LiquidBounce (https://github.com/CCBlueX/LiquidBounce)
*
* Copyright (c) 2016 - 2021 CCBlueX
*
* LiquidBounce is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* LiquidBounce is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with LiquidBounce. If not, see <https://www.gnu.org/licenses/>.
*/
package net.ccbluex.liquidbounce.features.module.modules.exploit

import net.ccbluex.liquidbounce.features.module.Category
import net.ccbluex.liquidbounce.features.module.Module
import net.minecraft.block.Blocks

object ModuleGhostHand : Module("GhostHand", Category.EXPLOIT) {

val targetedBlocks by blocks("TargetedBlocks", hashSetOf(Blocks.CHEST, Blocks.ENDER_CHEST, Blocks.TRAPPED_CHEST))

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*
* This file is part of LiquidBounce (https://github.com/CCBlueX/LiquidBounce)
*
* Copyright (c) 2016 - 2021 CCBlueX
*
* LiquidBounce is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* LiquidBounce is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with LiquidBounce. If not, see <https://www.gnu.org/licenses/>.
*/

package net.ccbluex.liquidbounce.features.module.modules.render

import net.ccbluex.liquidbounce.config.util.decode
import net.ccbluex.liquidbounce.features.module.Category
import net.ccbluex.liquidbounce.features.module.Module
import net.ccbluex.liquidbounce.utils.io.HttpClient
import net.minecraft.entity.Entity
import net.minecraft.entity.passive.HorseBaseEntity
import net.minecraft.entity.passive.TameableEntity
import net.minecraft.entity.projectile.ProjectileEntity
import net.minecraft.text.OrderedText
import net.minecraft.text.Style
import net.minecraft.util.Formatting
import java.util.*
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.Executors

object ModuleMobOwners : Module("MobOwners", Category.RENDER) {

val projectiles by boolean("Projectiles", false)

val uuidNameCache = ConcurrentHashMap<UUID, OrderedText>()

var asyncRequestExecutor = Executors.newSingleThreadExecutor()

fun getOwnerInfoText(entity: Entity): OrderedText? {
if (!this.enabled)
return null

val ownerId = when {
entity is TameableEntity -> entity.ownerUuid
entity is HorseBaseEntity -> entity.ownerUuid
entity is ProjectileEntity && projectiles -> entity.ownerUuid
else -> null
} ?: return null

return world.getPlayerByUuid(ownerId)
?.let { OrderedText.styledForwardsVisitedString(it.entityName, Style.EMPTY) }
?: getFromMojangApi(ownerId)
}

private fun getFromMojangApi(ownerId: UUID): OrderedText {
return uuidNameCache.computeIfAbsent(ownerId) {
this.asyncRequestExecutor.submit {
try {
class UsernameRecord(var name: String, var changedToAt: Int?)

val response = decode<Array<UsernameRecord>>(HttpClient.get("https://api.mojang.com/user/profiles/${it.toString().replace("-", "")}/names"))

val entityName = response.first { it.changedToAt == null }.name

uuidNameCache[it] = OrderedText.styledForwardsVisitedString(entityName, Style.EMPTY)
} catch (e: InterruptedException) {

} catch (e: Exception) {
uuidNameCache[it] = OrderedText.styledForwardsVisitedString("Failed to query Mojang API", Style.EMPTY.withItalic(true).withColor(Formatting.RED))
}
}

OrderedText.styledForwardsVisitedString("Loading", Style.EMPTY.withItalic(true))
}
}

override fun disable() {
this.asyncRequestExecutor.shutdownNow()

this.asyncRequestExecutor = Executors.newSingleThreadExecutor()
}

}
Loading

0 comments on commit 2d9230f

Please sign in to comment.