Skip to content

Commit 791cdfa

Browse files
committed
Shader ESP Mode, Performance Overlay
1 parent ea25a54 commit 791cdfa

23 files changed

+2322
-38
lines changed

README.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ I'm pleased to note that many of the features and improvements below are complet
101101
- Mention
102102
- Force Allow Chats
103103
- MusicAura
104+
- Performance Overlay
104105
- Redstone, Bed, Sign & Workstation ESP
105106
- PearlESP (Not a simple trajectory hack)
106107
- SignFramePassThrough (I didn't know something like this existed as a mod already)
@@ -890,6 +891,19 @@ Purpose: helps you avoid and debug anticheat flags by cleaning risky movement pa
890891

891892
![Scan](https://i.imgur.com/Zwf22jU.png)
892893

894+
### Performance Overlay (Per-Hack Profiler)
895+
- Added a new PerformanceOverlay feature to help find lag sources across enabled hacks.
896+
- It shows per-hack timing in HUD with 1s window stats and sorting modes (total / peak), including:
897+
- T: total time
898+
- U: update time
899+
- R: world render time
900+
- G: GUI render time
901+
- P: peak callback time
902+
- Use it to identify which specific hacks are causing sustained load (total) vs stutters (peak).
903+
- You're able to drag the overlay with your mouse when a container is open
904+
905+
![Perfmon](https://i.imgur.com/XKDvPQf.png)
906+
893907
## What's changed or improved in this fork?
894908

895909
### ChestESP
@@ -1191,6 +1205,18 @@ Examples:
11911205
- Optimized Search when using corners only ESP to avoid unnecessary heavy mesh work making detection faster.
11921206
- Reduced lag spikes on large scans by using cheaper nearest-result selection paths.
11931207

1208+
### Global ESP Render Modes
1209+
- Added a global ESP pipeline toggle in GlobalToggle:
1210+
- LEGACY: keeps the original per-hack ESP rendering path.
1211+
- SHADER_OUTLINE: redirects supported RenderUtils ESP draws into a centralized global collector/renderer for batched rendering.
1212+
1213+
- Why use SHADER_OUTLINE:
1214+
- Scales better when many ESP hacks are active (reduces per-hack draw overhead).
1215+
- Produces more consistent ESP rendering across hacks.
1216+
- Makes global ESP improvements easier (one pipeline to optimize/extend).
1217+
- Keeps hack compatibility without rewriting each ESP hack manually.
1218+
1219+
11941220
### Easier/Quicker ESP Commands
11951221
- ```.search <query>``` -> query mode + set query + enable
11961222
- ```.search off``` / ```.search on```

src/main/java/net/wurstclient/WurstClient.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import net.wurstclient.update.ProblematicResourcePackDetector;
4343
import net.wurstclient.update.ForkUpdateChecker;
4444
import net.wurstclient.update.WurstUpdater;
45+
import net.wurstclient.render.globalesp.GlobalEspManager;
4546
import net.wurstclient.util.PlayerRangeAlertManager;
4647
import net.wurstclient.util.SetbackDetector;
4748
import net.wurstclient.util.ServerObserver;
@@ -246,6 +247,7 @@ public void reloadSettings()
246247

247248
public void reloadFromDisk()
248249
{
250+
GlobalEspManager.getInstance().cleanup();
249251
reloadSettings();
250252

251253
if(hax != null)

src/main/java/net/wurstclient/WurstRenderLayers.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import net.minecraft.client.renderer.rendertype.OutputTarget;
1212
import net.minecraft.client.renderer.rendertype.RenderSetup;
1313
import net.minecraft.client.renderer.rendertype.RenderType;
14+
import net.wurstclient.render.globalesp.GlobalEspManager;
1415

1516
public enum WurstRenderLayers
1617
{
@@ -74,6 +75,7 @@ public enum WurstRenderLayers
7475
*/
7576
public static RenderType getQuads(boolean depthTest)
7677
{
78+
GlobalEspManager.getInstance().noteQuadLayerRequest(depthTest);
7779
return depthTest ? QUADS : ESP_QUADS;
7880
}
7981

@@ -83,6 +85,7 @@ public static RenderType getQuads(boolean depthTest)
8385
*/
8486
public static RenderType getLines(boolean depthTest)
8587
{
88+
GlobalEspManager.getInstance().noteLineLayerRequest(depthTest);
8689
return depthTest ? LINES : ESP_LINES;
8790
}
8891

src/main/java/net/wurstclient/clickgui/ClickGui.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,12 @@ public void init()
141141
windowMap.get(f.getCategory()).add(new FeatureButton(f));
142142
}
143143
}
144+
145+
// Bridge selected category-less "Other Features" into Other so they
146+
// remain discoverable in the hack-style category layout.
147+
windowMap.get(net.wurstclient.Category.OTHER)
148+
.add(new FeatureButton(WURST.getOtfs().performanceOverlayOtf));
149+
144150
// Keep the "Other" category usable: it contains a mixed bag of hacks,
145151
// commands and other-features, so insertion order is not meaningful.
146152
Window otherWindow = windowMap.get(net.wurstclient.Category.OTHER);

src/main/java/net/wurstclient/events/GUIRenderListener.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import net.minecraft.client.gui.GuiGraphics;
1212
import net.wurstclient.event.Event;
1313
import net.wurstclient.event.Listener;
14+
import net.wurstclient.util.HackPerformanceTracker;
1415

1516
public interface GUIRenderListener extends Listener
1617
{
@@ -30,8 +31,27 @@ public GUIRenderEvent(GuiGraphics context, float partialTicks)
3031
@Override
3132
public void fire(ArrayList<GUIRenderListener> listeners)
3233
{
34+
boolean profile = HackPerformanceTracker.shouldProfile();
3335
for(GUIRenderListener listener : listeners)
34-
listener.onRenderGUI(context, partialTicks);
36+
{
37+
if(!profile)
38+
{
39+
listener.onRenderGUI(context, partialTicks);
40+
continue;
41+
}
42+
43+
long start = System.nanoTime();
44+
try
45+
{
46+
listener.onRenderGUI(context, partialTicks);
47+
48+
}finally
49+
{
50+
HackPerformanceTracker.record(listener,
51+
HackPerformanceTracker.Phase.GUI,
52+
System.nanoTime() - start);
53+
}
54+
}
3555
}
3656

3757
@Override

src/main/java/net/wurstclient/events/RenderListener.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import java.util.ArrayList;
1212
import net.wurstclient.event.Event;
1313
import net.wurstclient.event.Listener;
14+
import net.wurstclient.util.HackPerformanceTracker;
1415

1516
public interface RenderListener extends Listener
1617
{
@@ -30,8 +31,27 @@ public RenderEvent(PoseStack matrixStack, float partialTicks)
3031
@Override
3132
public void fire(ArrayList<RenderListener> listeners)
3233
{
34+
boolean profile = HackPerformanceTracker.shouldProfile();
3335
for(RenderListener listener : listeners)
34-
listener.onRender(matrixStack, partialTicks);
36+
{
37+
if(!profile)
38+
{
39+
listener.onRender(matrixStack, partialTicks);
40+
continue;
41+
}
42+
43+
long start = System.nanoTime();
44+
try
45+
{
46+
listener.onRender(matrixStack, partialTicks);
47+
48+
}finally
49+
{
50+
HackPerformanceTracker.record(listener,
51+
HackPerformanceTracker.Phase.RENDER,
52+
System.nanoTime() - start);
53+
}
54+
}
3555
}
3656

3757
@Override

src/main/java/net/wurstclient/events/UpdateListener.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import net.wurstclient.event.Event;
1313
import net.wurstclient.event.Listener;
1414
import net.wurstclient.util.HackActivityTracker;
15+
import net.wurstclient.util.HackPerformanceTracker;
1516

1617
public interface UpdateListener extends Listener
1718
{
@@ -24,10 +25,27 @@ public static class UpdateEvent extends Event<UpdateListener>
2425
@Override
2526
public void fire(ArrayList<UpdateListener> listeners)
2627
{
28+
boolean profile = HackPerformanceTracker.shouldProfile();
2729
for(UpdateListener listener : listeners)
2830
{
2931
HackActivityTracker.markActive(listener);
30-
listener.onUpdate();
32+
if(!profile)
33+
{
34+
listener.onUpdate();
35+
continue;
36+
}
37+
38+
long start = System.nanoTime();
39+
try
40+
{
41+
listener.onUpdate();
42+
43+
}finally
44+
{
45+
HackPerformanceTracker.record(listener,
46+
HackPerformanceTracker.Phase.UPDATE,
47+
System.nanoTime() - start);
48+
}
3149
}
3250
}
3351

src/main/java/net/wurstclient/hacks/GlobalToggleHack.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import net.wurstclient.hack.AboveGroundFilterManager;
1616
import net.wurstclient.hack.CheckboxOverrideManager;
1717
import net.wurstclient.hack.Hack;
18+
import net.wurstclient.render.globalesp.GlobalEspRenderMode;
1819
import net.wurstclient.settings.CheckboxSetting;
1920
import net.wurstclient.settings.EnumSetting;
2021
import net.wurstclient.settings.SliderSetting;
@@ -54,6 +55,11 @@ public final class GlobalToggleHack extends Hack implements UpdateListener
5455
"FULL: Update only when full area scan is done (old behavior).\n"
5556
+ "PARTIAL: Update from ready chunks immediately (faster detection).",
5657
ChunkScanMode.values(), ChunkScanMode.FULL);
58+
private final EnumSetting<GlobalEspRenderMode> globalEspRenderMode =
59+
new EnumSetting<>("Global ESP render mode",
60+
"LEGACY: existing per-hack draw path.\n"
61+
+ "SHADER_OUTLINE: centralized global ESP pipeline.",
62+
GlobalEspRenderMode.values(), GlobalEspRenderMode.LEGACY);
5763

5864
private Map<CheckboxSetting, Boolean> stickySnapshot = Map.of();
5965
private Map<CheckboxSetting, Boolean> yLimitSnapshot = Map.of();
@@ -79,6 +85,7 @@ public GlobalToggleHack()
7985
addSetting(searchThreadPriority);
8086
addSetting(setSliderLimitOverride);
8187
addSetting(chunkScanMode);
88+
addSetting(globalEspRenderMode);
8289

8390
lastYLimitValue = yLimitValue.getValueI();
8491
lastSearchThreadPriority = searchThreadPriority.getValueI();
@@ -237,6 +244,11 @@ public boolean isSetSliderLimitOverrideAllowed()
237244
return setSliderLimitOverride.isChecked();
238245
}
239246

247+
public GlobalEspRenderMode getGlobalEspRenderMode()
248+
{
249+
return globalEspRenderMode.getSelected();
250+
}
251+
240252
private enum OverrideState
241253
{
242254
NONE,

src/main/java/net/wurstclient/hacks/autofish/AutoFishDebugDraw.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,8 @@ private void drawFishingSpots(PoseStack matrices)
128128
playerPos.z - camPos.z);
129129
matrices.mulPose(spot.input().rotation().toQuaternion());
130130

131-
VertexConsumer lineBuffer =
132-
vcp.getBuffer(WurstRenderLayers.ESP_LINES);
131+
var lineLayer = WurstRenderLayers.getLines(false);
132+
VertexConsumer lineBuffer = vcp.getBuffer(lineLayer);
133133

134134
RenderUtils.drawOutlinedBox(matrices, lineBuffer, headBox, color);
135135
RenderUtils.drawOutlinedBox(matrices, lineBuffer, noseBox, color);
@@ -142,7 +142,7 @@ private void drawFishingSpots(PoseStack matrices)
142142
playerPos.subtract(camPos), bobberPos.subtract(camPos), color,
143143
0.1F);
144144

145-
vcp.endBatch(WurstRenderLayers.ESP_LINES);
145+
vcp.endBatch(lineLayer);
146146
}
147147
}
148148

src/main/java/net/wurstclient/hud/IngameHUD.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import net.wurstclient.clickgui.ClickGui;
1313
import net.wurstclient.clickgui.screens.ClickGuiScreen;
1414
import net.wurstclient.events.GUIRenderListener;
15+
import net.wurstclient.util.HackPerformanceOverlay;
1516

1617
public final class IngameHUD implements GUIRenderListener
1718
{
@@ -25,6 +26,8 @@ public final class IngameHUD implements GUIRenderListener
2526
new GameStatsHud(WurstClient.INSTANCE.getHax().gameStatsHack);
2627
private final ClientMessageOverlay clientMessageOverlay =
2728
ClientMessageOverlay.getInstance();
29+
private final HackPerformanceOverlay performanceOverlay =
30+
HackPerformanceOverlay.getInstance();
2831
private TabGui tabGui;
2932
private net.wurstclient.hacks.itemhandler.ItemHandlerHud itemHandlerHud;
3033

@@ -53,6 +56,7 @@ public void onRenderGUI(GuiGraphics context, float partialTicks)
5356
itemHandlerHud =
5457
new net.wurstclient.hacks.itemhandler.ItemHandlerHud();
5558
itemHandlerHud.render(context, partialTicks);
59+
performanceOverlay.render(context);
5660

5761
// pinned windows
5862
if(!(WurstClient.MC.screen instanceof ClickGuiScreen))

0 commit comments

Comments
 (0)