Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ httpServer = "2.5.2"
discordIpc = "4.0.0"
semver4j = "3.1.0"
ahocorasick = "0.6.3"
fastutil4k = "0.2.3"
fastutil4k = "0.2.5"

# Recommended mods
modmenu = "17.0.0-beta.1"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
import com.mojang.blaze3d.platform.Window;
import com.mojang.blaze3d.systems.RenderSystem;
import net.ccbluex.liquidbounce.render.ClientTesselator;
import net.ccbluex.liquidbounce.render.GrowableMappableRingBuffer;
import net.minecraft.client.renderer.MappableRingBuffer;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
Expand All @@ -34,6 +36,12 @@ public abstract class MixinRenderSystem {
@Inject(method = "flipFrame", at = @At("RETURN"))
private static void onFlipFrame(Window window, TracyFrameCapture tracyFrameCapture, CallbackInfo ci) {
ClientTesselator.Shared.clear();
if (!GrowableMappableRingBuffer.DISCARD_QUEUE.isEmpty()) {
for (MappableRingBuffer mappableRingBuffer : GrowableMappableRingBuffer.DISCARD_QUEUE) {
mappableRingBuffer.close();
}
GrowableMappableRingBuffer.DISCARD_QUEUE.clear();
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ open class Configurable(
vararg default: T,
canBeNone: Boolean = true,
) where T : Enum<T>, T : NamedChoice =
multiEnumChoice(name, enumSetOf(elements = default), canBeNone = canBeNone)
multiEnumChoice(name, default.toEnumSet(), canBeNone = canBeNone)

inline fun <reified T> multiEnumChoice(
name: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ object ModuleCombineMobs : ClientModule("CombineMobs", Category.RENDER) {
}

fun getCombinedCount(entity: Entity): Int {
if (!running) return 1

val key = keyFor(entity)
val pos = entity.blockPosition().asLong()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,15 +113,19 @@ object ModuleStorageESP : ClientModule("StorageESP", Category.RENDER, aliases =
object Pot : ChestType("Pot", Color4b(209, 134, 0))
}

private val allTypes = arrayOf(
ChestType.Chest,
ChestType.EnderChest,
ChestType.Furnace,
ChestType.BrewingStand,
ChestType.Dispenser,
ChestType.Hopper,
ChestType.ShulkerBox,
ChestType.Pot,
)

init {
tree(ChestType.Chest)
tree(ChestType.EnderChest)
tree(ChestType.Furnace)
tree(ChestType.BrewingStand)
tree(ChestType.Dispenser)
tree(ChestType.Hopper)
tree(ChestType.ShulkerBox)
tree(ChestType.Pot)
allTypes.forEach { tree(it) }
}

private val requiresChestStealer by boolean("RequiresChestStealer", false)
Expand Down Expand Up @@ -327,9 +331,10 @@ object ModuleStorageESP : ClientModule("StorageESP", Category.RENDER, aliases =

@Suppress("unused")
private val renderHandler = handler<WorldRenderEvent> { event ->
if (StorageScanner.isEmpty()) {
return@handler
}
if (StorageScanner.isEmpty()) return@handler

val types = allTypes.filter { it.tracers && !it.color.isTransparent }
if (types.isEmpty()) return@handler

renderEnvironmentForWorld(event.matrixStack) {
val eyeVector = Vec3f(0.0, 0.0, 1.0)
Expand All @@ -338,11 +343,13 @@ object ModuleStorageESP : ClientModule("StorageESP", Category.RENDER, aliases =

startBatch()
longLines {
for ((blockPos, type) in StorageScanner.iterate()) {
if (!type.tracers || type.color.isTransparent || !type.shouldRender(blockPos)) continue
val pos = relativeToCamera(blockPos.center).toVec3f()
for (type in types) {
for (blockPos in StorageScanner.iterate(type)) {
if (!type.shouldRender(blockPos)) continue
val pos = relativeToCamera(blockPos.center).toVec3f()

drawLine(eyeVector, pos, type.color.argb)
drawLine(eyeVector, pos, type.color.argb)
}
}
}
commitBatch()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
*/
package net.ccbluex.liquidbounce.features.module.modules.render.nametags

import net.ccbluex.fastutil.Pool
import net.ccbluex.liquidbounce.event.events.OverlayRenderEvent
import net.ccbluex.liquidbounce.event.handler
import net.ccbluex.liquidbounce.features.module.Category
Expand Down Expand Up @@ -54,11 +55,12 @@ object ModuleNametags : ClientModule("Nametags", Category.RENDER) {
val fontRenderer
get() = FontManager.FONT_RENDERER

private val nametagsToRender = mutableListOf<Nametag>()
private val nametagsToRender = mutableListOf<NametagRenderState>()
private val nametagPool = Pool(::NametagRenderState, NametagRenderState::clear)

override fun onDisabled() {
RenderedEntities.unsubscribe(this)
nametagsToRender.clear()
nametagPool.recycleAll(nametagsToRender)
}

override fun onEnabled() {
Expand Down Expand Up @@ -87,9 +89,10 @@ object ModuleNametags : ClientModule("Nametags", Category.RENDER) {

/**
* Collects all entities that should be rendered, gets the screen position, where the name tag should be displayed,
* add what should be rendered ([Nametag]). The nametags are sorted in order of rendering.
* add what should be rendered. The nametags are sorted in order of rendering.
*/
private fun collectAndSortNametagsToRender() {
nametagPool.recycleAll(nametagsToRender)
nametagsToRender.clear()
val maximumDistanceSquared = maximumDistance.sq()

Expand All @@ -98,13 +101,13 @@ object ModuleNametags : ClientModule("Nametags", Category.RENDER) {
continue
}

nametagsToRender += Nametag(entity)
nametagsToRender += nametagPool.borrow().update(entity)
}
nametagsToRender.sortWith(NAMETAG_COMPARATOR)
}

private val NAMETAG_COMPARATOR = Comparator.comparingDouble<Nametag> { nametag ->
nametag.entity.distanceToSqr(mc.cameraEntity!!)
private val NAMETAG_COMPARATOR = Comparator.comparingDouble<NametagRenderState> { nametag ->
nametag.entity!!.distanceToSqr(mc.cameraEntity!!)
}

fun shouldRenderVanillaNametag(state: EntityRenderState): Boolean {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,39 +21,47 @@ package net.ccbluex.liquidbounce.features.module.modules.render.nametags
import net.ccbluex.liquidbounce.render.engine.type.Vec3f
import net.ccbluex.liquidbounce.utils.entity.interpolateCurrentPosition
import net.ccbluex.liquidbounce.utils.render.WorldToScreen
import net.ccbluex.liquidbounce.utils.text.PlainText
import net.minecraft.world.entity.Entity
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.item.ItemStack
import net.minecraft.network.chat.Component

class Nametag private constructor(
val entity: Entity,
/**
* The text to render as nametag
*/
val text: Component,
/**
* The items that should be rendered above the name tag
*/
val items: List<ItemStack>
) {
class NametagRenderState {
@JvmField
var entity: Entity? = null

@JvmField
var text: Component = PlainText.EMPTY

@JvmField
var items: List<ItemStack> = emptyList()

@JvmField
var screenPos: Vec3f? = null
private set

constructor(entity: LivingEntity) : this(
entity,
NametagTextFormatter.format(entity),
NametagEquipment.createItemList(entity),
)
fun update(entity: Entity) = apply {
this.entity = entity
this.text = NametagTextFormatter.format(entity)
if (entity is LivingEntity) {
this.items = NametagEquipment.createItemList(entity)
}
}

fun calculateScreenPos(tickDelta: Float): Vec3f? {
val entity = this.entity ?: return null
val nametagPos = entity.interpolateCurrentPosition(tickDelta)
.add(0.0, entity.getEyeHeight(entity.pose) + 0.55, 0.0)

screenPos = WorldToScreen.calculateScreenPos(nametagPos)
return screenPos
}

}
fun clear() {
this.entity = null
this.text = PlainText.EMPTY
this.items = emptyList()
this.screenPos = null
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,11 @@ private const val BACKGROUND_Y_OFFSET_TOP = -0.1f
private const val BACKGROUND_Y_OFFSET_BOTTOM = 1.1f
private const val BACKGROUND_X_PADDING = 0.2f * FONT_SIZE

internal fun GuiGraphics.drawNametag(nametag: Nametag, posX: Float, posY: Float) {
internal fun GuiGraphics.drawNametag(nametag: NametagRenderState, posX: Float, posY: Float) {
val entity = nametag.entity
if (nametag.items.any { !it.isEmpty }) {
val currentItemStackRenderer = if (NametagEquipment.showInfo) {
if (nametag.entity === player) {
if (entity === player) {
ItemStackListRenderer.SingleItemStackRenderer.All
} else {
ItemStackListRenderer.SingleItemStackRenderer.ForOtherPlayer
Expand Down Expand Up @@ -89,13 +90,13 @@ internal fun GuiGraphics.drawNametag(nametag: Nametag, posX: Float, posY: Float)
}

// Draw enchantments directly for the entity (regardless of whether items are shown)
if (NametagEnchantmentRenderer.running && nametag.entity is LivingEntity) {
val entityPos = nametag.entity.position()
if (NametagEnchantmentRenderer.running && entity is LivingEntity) {
val entityPos = entity.position()
val worldX = entityPos.x.toFloat()
val worldY = (entityPos.y + nametag.entity.bbHeight + 0.5f).toFloat()
val worldY = (entityPos.y + entity.bbHeight + 0.5f).toFloat()

drawEntityEnchantments(
nametag.entity,
entity,
worldX,
worldY,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import net.ccbluex.liquidbounce.features.module.modules.misc.antibot.ModuleAntiB
import net.ccbluex.liquidbounce.features.module.modules.render.ModuleCombineMobs
import net.ccbluex.liquidbounce.utils.text.PlainText
import net.ccbluex.liquidbounce.utils.client.asPlainText
import net.ccbluex.liquidbounce.utils.client.asText
import net.ccbluex.liquidbounce.utils.client.joinToText
import net.ccbluex.liquidbounce.utils.client.player
import net.ccbluex.liquidbounce.utils.client.textOf
Expand Down Expand Up @@ -94,28 +93,24 @@ internal object NametagTextFormatter : Configurable("Text") {
},

NAME("Name") {
override fun apply(entity: Entity): Component = buildList(4) {
val name = entity.displayName
val nameColor = entity.nameColor

if (entity is LivingEntity && entity.isBaby) {
this += BABY_TEXT
}

this += if (nameColor != null) {
name.copy().withColor(nameColor)
} else {
name
override fun apply(entity: Entity): Component {
val isBaby = entity is LivingEntity && entity.isBaby

// Optimized entity.getDisplayName()
val displayName = entity.team?.getFormattedName(entity.name) ?: entity.name

val coloredName = entity.nameColor?.let { nameColor ->
displayName.copy().withColor(nameColor)
} ?: displayName

val count = ModuleCombineMobs.getCombinedCount(entity)
return when {
isBaby && count > 1 -> textOf(BABY_TEXT, coloredName, " ($count)".asPlainText(COUNT_STYLE))
isBaby -> textOf(BABY_TEXT, coloredName)
count > 1 -> textOf(coloredName, " ($count)".asPlainText(COUNT_STYLE))
else -> coloredName
}

if (ModuleCombineMobs.running) {
val count = ModuleCombineMobs.getCombinedCount(entity)
if (count > 1) {
this += PlainText.SPACE
this += ("x $count").asPlainText(COUNT_STYLE)
}
}
}.asText()
}
},

HEALTH("Health") {
Expand Down Expand Up @@ -151,16 +146,11 @@ internal object NametagTextFormatter : Configurable("Text") {
private val Entity.isBot get() = ModuleAntiBot.isBot(this)

private val Entity.nameColor: TextColor?
get() {
val tagColor = EntityTaggingManager.getTag(this).color

return when {
isBot -> ChatFormatting.DARK_AQUA.toTextColor()
isInvisible -> ChatFormatting.GOLD.toTextColor()
isShiftKeyDown -> ChatFormatting.DARK_RED.toTextColor()
tagColor != null -> tagColor.toTextColor()
else -> null
}
get() = when {
isBot -> ChatFormatting.DARK_AQUA.toTextColor()
isInvisible -> ChatFormatting.GOLD.toTextColor()
isShiftKeyDown -> ChatFormatting.DARK_RED.toTextColor()
else -> EntityTaggingManager.getTag(this).color?.toTextColor()
}

private fun ChatFormatting.toTextColor(): TextColor {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import com.mojang.blaze3d.buffers.GpuBuffer
import com.mojang.blaze3d.buffers.GpuBufferSlice
import net.ccbluex.liquidbounce.utils.client.formatAsCapacity
import net.ccbluex.liquidbounce.utils.client.logger
import net.ccbluex.liquidbounce.utils.client.mc
import net.ccbluex.liquidbounce.utils.render.mapBuffer
import net.minecraft.client.renderer.MappableRingBuffer
import org.lwjgl.system.MemoryUtil
Expand All @@ -48,7 +47,7 @@ import java.nio.ByteBuffer
class GrowableMappableRingBuffer @JvmOverloads constructor(
val label: String,
val usage: @GpuBuffer.Usage Int,
val growPolicy: GrowPolicy = GrowPolicy.of(paddingScale = 7, min = 0), // 128 bytes padding
val growPolicy: GrowPolicy = GrowPolicy.DEFAULT,
) {

private var ring: MappableRingBuffer? = null
Expand All @@ -71,7 +70,7 @@ class GrowableMappableRingBuffer @JvmOverloads constructor(
val newSize = growPolicy.getNewSize(minSize, current?.size() ?: 0)
current?.let {
// Defer closing the old ring buffer to avoid races with GPU usage.
mc.schedule(it::close)
DISCARD_QUEUE.add(it)
}
ring = MappableRingBuffer(
Suppliers.ofInstance(label),
Expand Down Expand Up @@ -162,6 +161,12 @@ class GrowableMappableRingBuffer @JvmOverloads constructor(
fun getNewSize(requested: Int, current: Int): Int

companion object {
/**
* 128 bytes padding, minimum 0
*/
@JvmField
val DEFAULT = of(paddingScale = 7, min = 0)

@JvmStatic
fun of(paddingScale: Int, min: Int) = GrowPolicy { requested, current ->
val base = maxOf(min, requested, current)
Expand All @@ -170,5 +175,15 @@ class GrowableMappableRingBuffer @JvmOverloads constructor(
}
}
}

companion object {
/**
* [MappableRingBuffer] to be closed.
*
* @see net.ccbluex.liquidbounce.injection.mixins.blaze3d.MixinRenderSystem.onFlipFrame
*/
@JvmField
val DISCARD_QUEUE = ArrayDeque<MappableRingBuffer>()
}
}

Loading