fix(hud): rewrite PlayerListHud.PlayerEntry to match obfuscated semantics
The hand-written PlayerEntry never initialized widthAnim, so the render path read 0 for entry width and drew nothing visible. Other gaps: - nameWidth was never measured, so item layouts collapsed. - displayName bypassed NameProtect.replacePlayerName, leaking real IGNs through the streamer/anti-doxx filter. - startRemove() flipped a flag but never triggered the slide-out or height-collapse animations, so isRemoveDone() (which used a custom alpha decay) effectively never returned true. - tick() mutated alpha / currentY by hand instead of just ticking the animation timers the render code already consults. Rewrite per Recaf's PlayerListHud$PlayerEntry: - Constructor seeds itemStacks/cheatItems from initialItems, calls updateItems(...) to set displayName, nameWidth, totalWidth, then primes slide/height/alpha/width anims (width starts at totalWidth so the row is visible from frame 1, then animates if it grows). - updateItems() recomputes displayName via NameProtect, the cached nameWidth via headerFont, the totalWidth from padding/head/items, and animates widthAnim to the new total. - startRemove() actually slides the entry out and animates height to 0; isRemoveDone() defers to heightAnim.isDone(). - Drop the dead alpha / targetY / currentY / parent fields. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -127,6 +127,8 @@ repositories {
|
||||
// flatDir {
|
||||
// dir 'libs'
|
||||
// }
|
||||
|
||||
maven { url = "https://pkgs.dev.azure.com/djtheredstoner/DevAuth/_packaging/public/maven/v1" }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
@@ -146,6 +148,9 @@ dependencies {
|
||||
implementation 'org.ow2.asm:asm-commons:9.6'
|
||||
implementation 'org.ow2.asm:asm-util:9.6'
|
||||
|
||||
// Dev Auth
|
||||
runtimeOnly("me.djtheredstoner:DevAuth-forge-latest:1.2.2")
|
||||
|
||||
// Example mod dependency with JEI - using fg.deobf() ensures the dependency is remapped to your development mappings
|
||||
// The JEI API is declared for compile time use, while the full JEI artifact is used at runtime
|
||||
// compileOnly fg.deobf("mezz.jei:jei-${mc_version}-common-api:${jei_version}")
|
||||
|
||||
@@ -22,6 +22,7 @@ import net.minecraft.world.item.BowItem;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import shit.zen.modules.impl.render.NameProtect;
|
||||
import shit.zen.event.impl.GlRenderEvent;
|
||||
import shit.zen.event.impl.PacketEvent;
|
||||
import shit.zen.event.impl.Render2DEvent;
|
||||
@@ -42,56 +43,79 @@ import shit.zen.event.EventTarget;
|
||||
public class PlayerListHud
|
||||
extends HudElement {
|
||||
public static final class PlayerEntry {
|
||||
public final PlayerListHud parent;
|
||||
public final PlayerListHud outer;
|
||||
public final net.minecraft.world.entity.player.Player player;
|
||||
public String displayName;
|
||||
public float nameWidth;
|
||||
public java.util.List<ItemStack> items;
|
||||
public final java.util.Map<net.minecraft.world.item.Item, ItemStack> itemStacks = new java.util.HashMap<>();
|
||||
public float totalWidth;
|
||||
public final java.util.Map<net.minecraft.world.item.Item, Integer> cheatItems = new java.util.HashMap<>();
|
||||
public final java.util.Set<net.minecraft.world.item.Item> flaggedItems = new java.util.HashSet<>();
|
||||
public final SmoothAnimationTimer fadeAnim = new SmoothAnimationTimer();
|
||||
public final java.util.Map<net.minecraft.world.item.Item, ItemStack> itemStacks = new java.util.HashMap<>();
|
||||
public final long createdTime;
|
||||
public final SmoothAnimationTimer slideAnim = new SmoothAnimationTimer();
|
||||
public final SmoothAnimationTimer fadeAnim = new SmoothAnimationTimer();
|
||||
public final SmoothAnimationTimer heightAnim = new SmoothAnimationTimer();
|
||||
public final SmoothAnimationTimer alphaAnim = new SmoothAnimationTimer();
|
||||
public final SmoothAnimationTimer widthAnim = new SmoothAnimationTimer();
|
||||
public String displayName;
|
||||
public float nameWidth;
|
||||
public boolean visible = true;
|
||||
public boolean rightAligned = false;
|
||||
public float alpha = 1.0f;
|
||||
public float targetY;
|
||||
public float currentY;
|
||||
public boolean removing = false;
|
||||
public boolean visible = true;
|
||||
public final boolean rightAligned;
|
||||
|
||||
public PlayerEntry(PlayerListHud parent, net.minecraft.world.entity.player.Player player, java.util.List<ItemStack> items) {
|
||||
this.parent = parent;
|
||||
public PlayerEntry(PlayerListHud outer, net.minecraft.world.entity.player.Player player, java.util.List<ItemStack> initialItems) {
|
||||
this.outer = outer;
|
||||
this.player = player;
|
||||
this.items = items;
|
||||
this.displayName = player.getName().getString();
|
||||
for (ItemStack stack : items) {
|
||||
this.itemStacks.put(stack.getItem(), stack);
|
||||
this.rightAligned = outer.wasRightAligned;
|
||||
this.createdTime = System.currentTimeMillis();
|
||||
initialItems.forEach(this::addItemStack);
|
||||
ArrayList<ItemStack> initialList = new ArrayList<>();
|
||||
for (ItemStack stack : this.itemStacks.values()) {
|
||||
if (ItemUtil.isOtherCheat(stack)) {
|
||||
this.cheatItems.put(stack.getItem(), stack.getDamageValue());
|
||||
}
|
||||
initialList.add(stack);
|
||||
}
|
||||
this.updateItems(initialList);
|
||||
this.slideAnim.setCurrentValue(this.rightAligned ? 20.0 : -20.0);
|
||||
this.heightAnim.setCurrentValue(0.0);
|
||||
this.alphaAnim.setCurrentValue(0.0);
|
||||
this.widthAnim.setCurrentValue(this.totalWidth);
|
||||
}
|
||||
|
||||
public void updateItems(java.util.List<ItemStack> items) {
|
||||
this.items = items;
|
||||
this.displayName = NameProtect.replacePlayerName(this.player.getName().getString());
|
||||
this.nameWidth = GlHelper.getStringWidth(this.displayName, this.outer.headerFont);
|
||||
float padding = 5.0f;
|
||||
float gap = 3.0f;
|
||||
float headSize = 20.0f;
|
||||
float itemSize = 16.0f;
|
||||
this.totalWidth = padding + headSize + gap + this.nameWidth + gap + items.size() * (itemSize + gap) + padding;
|
||||
this.widthAnim.animate(this.totalWidth, 0.25, Easings.EASE_OUT_SINE);
|
||||
}
|
||||
|
||||
public void startRemove() {
|
||||
if (this.removing) return;
|
||||
this.removing = true;
|
||||
}
|
||||
|
||||
public void updateItems(java.util.List<ItemStack> newItems) {
|
||||
this.items = newItems;
|
||||
}
|
||||
|
||||
public boolean isRemoveDone() {
|
||||
return this.removing && this.alpha <= 0.01f;
|
||||
float dist = 40.0f;
|
||||
this.slideAnim.animate(this.rightAligned ? dist : -dist, 0.2, Easings.EASE_IN_POW3);
|
||||
this.heightAnim.animate(0.0, 0.2, Easings.EASE_OUT_POW3);
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
float target = this.removing ? 0.0f : 1.0f;
|
||||
this.alpha += (target - this.alpha) * 0.18f;
|
||||
this.currentY += (this.targetY - this.currentY) * 0.18f;
|
||||
this.fadeAnim.tick();
|
||||
this.slideAnim.tick();
|
||||
this.fadeAnim.tick();
|
||||
this.heightAnim.tick();
|
||||
this.alphaAnim.tick();
|
||||
this.widthAnim.tick();
|
||||
}
|
||||
|
||||
public boolean isRemoveDone() {
|
||||
return this.removing && this.heightAnim.isDone();
|
||||
}
|
||||
|
||||
private void addItemStack(ItemStack stack) {
|
||||
this.itemStacks.putIfAbsent(stack.getItem(), stack);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user