Skip to content

Commit

Permalink
Merge branch 'nextgen' into target
Browse files Browse the repository at this point in the history
  • Loading branch information
Zirada authored Feb 8, 2025
2 parents ba0010e + d4274ef commit a257e26
Show file tree
Hide file tree
Showing 45 changed files with 1,333 additions and 234 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ fabric_version=0.111.0+1.21.4
# Loom
loom_version=1.9-SNAPSHOT
# Mod Properties
mod_version=0.25.1
mod_version=0.26.1
maven_group=net.ccbluex
archives_base_name=liquidbounce
# Kotlin
Expand Down
29 changes: 26 additions & 3 deletions src-theme/src/routes/clickgui/Description.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,28 @@
description.subscribe((v) => {
data = v;
});
let element: HTMLElement | null = null;
let left = 0;
let anchor: "right" | "left" = "right";
$: {
if (data?.x !== undefined && element !== null) {
anchor = data.anchor;
if (data.anchor === "left") {
left = data.x - element.clientWidth - 20;
} else {
left = data.x + 20;
}
}
}
</script>

{#key data}
{#if data !== null}
<div transition:fly|global={{duration: 200, x: -15}} class="description-wrapper"
style="top: {data.y}px; left: {data.x + 20}px;">
<div class="description">
<div transition:fly|global={{duration: 200, x: anchor === "right" ? -15 : 15}} class="description-wrapper"
style="top: {data.y}px; left: {left}px;" bind:this={element}>
<div class="description" class:right={anchor === "left"}>
<div class="text">{data.description}</div>
</div>
</div>
Expand Down Expand Up @@ -48,6 +63,14 @@
top: 50%;
transform: translateY(-50%);
}
&.right {
&::before {
transform: translateY(-50%) rotate(180deg);
left: unset;
right: -8px;
}
}
}
.text {
Expand Down
32 changes: 25 additions & 7 deletions src-theme/src/routes/clickgui/Module.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -58,17 +58,35 @@
}
function setDescription() {
const y = (moduleNameElement?.getBoundingClientRect().top ?? 0) + ((moduleNameElement?.clientHeight ?? 0) / 2);
const x = moduleNameElement?.getBoundingClientRect().right ?? 0;
if (!moduleNameElement) return;
const boundingRect = moduleNameElement.getBoundingClientRect();
const y = (boundingRect.top + (moduleNameElement.clientHeight / 2)) * (2 / $scaleFactor);
let moduleDescription = description;
if (aliases.length > 0) {
moduleDescription += ` (aka ${aliases.map(name => $spaceSeperatedNames ? convertToSpacedString(name) : name).join(", ")})`;
}
descriptionStore.set({
x: x * (2 / $scaleFactor),
y: y * (2 / $scaleFactor),
description: moduleDescription
});
// If element is less than 300px from the right, display description on the left
if (window.innerWidth - boundingRect.right > 300) {
const x = boundingRect.right * (2 / $scaleFactor);
descriptionStore.set({
x,
y,
anchor: "right",
description: moduleDescription
});
} else {
const x = boundingRect.left * (2 / $scaleFactor);
descriptionStore.set({
x,
y,
anchor: "left",
description: moduleDescription
});
}
}
async function toggleExpanded() {
Expand Down
1 change: 1 addition & 0 deletions src-theme/src/routes/clickgui/clickgui_store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {type Writable, writable} from "svelte/store";

export interface TDescription {
description: string;
anchor: "left" | "right",
x: number;
y: number;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,15 +174,27 @@ private Vec3d hookSlowVelocity(Vec3d instance, double x, double y, double z) {
return instance.multiply(x, y, z);
}

@SuppressWarnings("UnreachableCode")
@WrapWithCondition(method = "attack", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/PlayerEntity;setSprinting(Z)V", ordinal = 0))
private boolean hookSlowVelocity(PlayerEntity instance, boolean b) {
if ((Object) this == MinecraftClient.getInstance().player) {
ModuleKeepSprint.INSTANCE.setSprinting(b);
return !ModuleKeepSprint.INSTANCE.getRunning() || b;
}

return true;
}

@SuppressWarnings({"UnreachableCode", "ConstantValue"})
@ModifyExpressionValue(method = "attack", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/PlayerEntity;isSprinting()Z"))
private boolean hookSlowVelocity(boolean original) {
if ((Object) this == MinecraftClient.getInstance().player && ModuleKeepSprint.INSTANCE.getRunning()) {
return ModuleKeepSprint.INSTANCE.getSprinting();
}

return original;
}

@ModifyReturnValue(method = "getEntityInteractionRange", at = @At("RETURN"))
private double hookEntityInteractionRange(double original) {
if ((Object) this == MinecraftClient.getInstance().player && ModuleReach.INSTANCE.getRunning()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import net.ccbluex.liquidbounce.render.engine.RenderingFlags;
import net.ccbluex.liquidbounce.render.shader.shaders.OutlineShader;
import net.ccbluex.liquidbounce.utils.client.ClientUtilsKt;
import net.ccbluex.liquidbounce.utils.client.ErrorHandler;
import net.ccbluex.liquidbounce.utils.combat.CombatExtensionsKt;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gl.Framebuffer;
Expand Down Expand Up @@ -75,9 +76,16 @@ public abstract class MixinWorldRenderer {

@Inject(method = "loadEntityOutlinePostProcessor", at = @At("RETURN"))
private void onLoadEntityOutlineShader(CallbackInfo info) {
// load the shader class to compile the shaders
//noinspection unused
var instance = OutlineShader.INSTANCE;
try {
// load the shader class to compile the shaders
//noinspection unused
var instance = OutlineShader.INSTANCE;
} catch (Exception e) {
ErrorHandler.INSTANCE.fatal(e, "Failed to load outline shader");

// This will make Minecraft unable to continue loading
throw e;
}
}

@Inject(method = "render", at = @At("HEAD"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,32 @@
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

@Pseudo
@Mixin(targets = "com/oracle/truffle/host/HostClassDesc$Members")
public abstract class MixinHostClassDesc {

@Unique
private static Method mergeMethod;

@Unique
private static Method getMergeMethod() {
if (mergeMethod == null) {
try {
Class<?> hostMethodDescClass = Class.forName("com.oracle.truffle.host.HostMethodDesc");
mergeMethod = Class.forName("com.oracle.truffle.host.HostClassDesc$Members")
.getDeclaredMethod("merge", hostMethodDescClass, hostMethodDescClass);
mergeMethod.setAccessible(true);
} catch (Exception e) {
throw new RuntimeException("Failed to get merge method", e);
}
}
return mergeMethod;
}

@Shadow(remap = false)
@Final
Map<String, Object> methods;
Expand All @@ -53,16 +72,76 @@ public abstract class MixinHostClassDesc {
@Final
Map<String, Object> staticMethods;


@Inject(method = "<init>", at = @At("RETURN"), remap = false)
private void remapClassDesc(CallbackInfo ci) {
remapEntries(methods, this::getMethod);
remapEntries(fields, this::getField);
remapEntries(staticFields, this::getField);
remapEntries(staticMethods, this::getMethod);
remapFieldEntries(fields, this::getField);
remapFieldEntries(staticFields, this::getField);

remapMethodEntries(methods);
remapMethodEntries(staticMethods);
}

@Unique
private void remapMethodEntries(Map<String, Object> map) {
final var entries = new HashMap<>(map).entrySet();

for (var entry : entries) {
String key = entry.getKey();
Object value = entry.getValue();
try {
// this is a bit more complicated than fields because of overloads

final var methodsToRemap = new ArrayList<Method>();

try {
// value instanceof HostMethodDesc.SingleMethod
methodsToRemap.add(getReflectionMethodFromSingleMethod(value));
} catch (NoSuchMethodException _ignored) {
// value instanceof HostMethodDesc.OverloadedMethod
// which probably should not happen because intermediary names have no overloads?
final Method getOverloads = value.getClass().getDeclaredMethod("getOverloads");
getOverloads.setAccessible(true);
final var overloads = (Object[]) getOverloads.invoke(value);

for (final var overload : overloads) {
methodsToRemap.add(getReflectionMethodFromSingleMethod(overload));
}
}

for (final Method method : methodsToRemap) {
final String remappedName = remapDescriptor(method);

if (remappedName != null) {
if (map.containsKey(remappedName)) {
final Object mergedMethod = getMergeMethod().invoke(null, map.get(remappedName), value);
map.remove(key);
map.put(remappedName, mergedMethod);

} else {
map.remove(key);
map.put(remappedName, value);
}
}
}


} catch (Exception e) {
ClientUtilsKt.getLogger().error("Failed to remap method: {}", key, e);
}
}
}

@Unique
private void remapEntries(Map<String, Object> map, MemberRetriever retriever) {
private static Method getReflectionMethodFromSingleMethod(Object value)
throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
final Method descMethod = value.getClass().getDeclaredMethod("getReflectionMethod");
descMethod.setAccessible(true);
return (Method) descMethod.invoke(value);
}

@Unique
private void remapFieldEntries(Map<String, Object> map, MemberRetriever retriever) {
var entries = new HashMap<>(map).entrySet();

for (var entry : entries) {
Expand All @@ -74,7 +153,7 @@ private void remapEntries(Map<String, Object> map, MemberRetriever retriever) {
Member member = retriever.getMember(value);
remapped = remapDescriptor(member);
} catch (ReflectiveOperationException e) {
ClientUtilsKt.getLogger().error("Failed to remap: {}", key, e);
ClientUtilsKt.getLogger().error("Failed to remap field: {}", key, e);
continue;
}

Expand All @@ -85,28 +164,6 @@ private void remapEntries(Map<String, Object> map, MemberRetriever retriever) {
}
}

@Unique
private Member getMethod(Object o) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
try {
// If this works, it is likely a SingleMethod instance
Method descMethod = o.getClass().getDeclaredMethod("getReflectionMethod");

descMethod.setAccessible(true);
return (Member) descMethod.invoke(o);
} catch (NoSuchMethodException ignored) {
try {
var getOverloads = o.getClass().getDeclaredMethod("getOverloads");
var overloads = (Object[]) getOverloads.invoke(o);

return getMethod(overloads[0]);
} catch (NoSuchMethodException ignored2) {
ClientUtilsKt.getLogger().error("Unsupported method type: {}", o.getClass().getName());
}

return null;
}
}

@Unique
private Member getField(Object o) throws IllegalAccessException, NoSuchFieldException {
var descField = o.getClass().getDeclaredField("field");
Expand Down
7 changes: 7 additions & 0 deletions src/main/kotlin/net/ccbluex/liquidbounce/LiquidBounce.kt
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ import net.ccbluex.liquidbounce.integration.theme.ThemeManager
import net.ccbluex.liquidbounce.integration.theme.component.ComponentOverlay
import net.ccbluex.liquidbounce.lang.LanguageManager
import net.ccbluex.liquidbounce.render.FontManager
import net.ccbluex.liquidbounce.render.HAS_AMD_VEGA_APU
import net.ccbluex.liquidbounce.render.ui.ItemImageAtlas
import net.ccbluex.liquidbounce.script.ScriptManager
import net.ccbluex.liquidbounce.utils.aiming.PostRotationExecutor
Expand Down Expand Up @@ -231,6 +232,12 @@ object LiquidBounce : EventListener {
}

ItemImageAtlas

if (HAS_AMD_VEGA_APU) {
logger.info("AMD Vega iGPU detected, enabling different line smooth handling. " +
"If you believe this is a mistake, please create an issue at " +
"https://github.com/CCBlueX/LiquidBounce/issues.")
}
}.onSuccess {
logger.info("Successfully loaded client!")
}.onFailure(ErrorHandler::fatal)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,26 +23,28 @@ package net.ccbluex.liquidbounce.config.gson.util

import com.google.gson.*
import com.google.gson.reflect.TypeToken
import net.ccbluex.liquidbounce.config.gson.publicGson
import java.io.InputStream
import java.io.Reader

/**
* Decode JSON content
*/
inline fun <reified T> decode(stringJson: String): T =
Gson().fromJson(stringJson, object : TypeToken<T>() {}.type)
stringJson.reader().use(::decode)

/**
* Decode JSON content from an Input Stream
* Decode JSON content from an [InputStream] and close it
*/
inline fun <reified T> decode(inputStream: InputStream): T =
decode(inputStream.bufferedReader())
inputStream.bufferedReader().use(::decode)

/**
* Decode JSON content from a Reader
* Decode JSON content from a [Reader] and close it
*/
inline fun <reified T> decode(reader: Reader): T =
Gson().fromJson(reader, object : TypeToken<T>() {}.type)
inline fun <reified T> decode(reader: Reader): T = reader.use {
publicGson.fromJson(reader, object : TypeToken<T>() {}.type)
}

fun String.toJsonPrimitive(): JsonPrimitive = JsonPrimitive(this)
fun Char.toJsonPrimitive(): JsonPrimitive = JsonPrimitive(this)
Expand Down
Loading

0 comments on commit a257e26

Please sign in to comment.