Skip to content

Commit bd536bb

Browse files
committed
Added BarrierESP
1 parent d001500 commit bd536bb

3 files changed

Lines changed: 319 additions & 2 deletions

File tree

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

Lines changed: 307 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,323 @@
77
*/
88
package net.wurstclient.hacks;
99

10+
import com.mojang.blaze3d.vertex.PoseStack;
11+
import java.awt.Color;
12+
import java.util.ArrayList;
13+
import java.util.List;
14+
import java.util.function.BiPredicate;
15+
import net.minecraft.core.BlockPos;
16+
import net.minecraft.world.level.ChunkPos;
17+
import net.minecraft.world.level.block.Blocks;
18+
import net.minecraft.world.level.block.state.BlockState;
19+
import net.minecraft.world.phys.AABB;
20+
import net.minecraft.world.phys.Vec3;
1021
import net.wurstclient.Category;
1122
import net.wurstclient.SearchTags;
23+
import net.wurstclient.events.CameraTransformViewBobbingListener;
24+
import net.wurstclient.events.RenderListener;
25+
import net.wurstclient.events.UpdateListener;
1226
import net.wurstclient.hack.Hack;
27+
import net.wurstclient.settings.CheckboxSetting;
28+
import net.wurstclient.settings.ChunkAreaSetting;
29+
import net.wurstclient.settings.ColorSetting;
30+
import net.wurstclient.settings.EspStyleSetting;
31+
import net.wurstclient.settings.EnumSetting;
32+
import net.wurstclient.settings.SliderSetting;
33+
import net.wurstclient.util.BlockUtils;
34+
import net.wurstclient.util.EspLimitUtils;
35+
import net.wurstclient.util.RenderUtils;
36+
import net.wurstclient.util.RotationUtils;
37+
import net.wurstclient.util.chunk.ChunkSearcher.Result;
38+
import net.wurstclient.util.chunk.ChunkSearcherCoordinator;
1339

1440
@SearchTags({"barrier esp"})
15-
public class BarrierEspHack extends Hack
41+
public final class BarrierEspHack extends Hack implements UpdateListener,
42+
CameraTransformViewBobbingListener, RenderListener
1643
{
44+
private final EnumSetting<RenderMode> renderMode = new EnumSetting<>(
45+
"Render mode", "description.wurst.setting.barrieresp.render_mode",
46+
RenderMode.values(), RenderMode.ESP_AND_ICONS);
47+
private final EspStyleSetting style = new EspStyleSetting();
48+
private final CheckboxSetting stickyArea =
49+
new CheckboxSetting("Sticky area",
50+
"description.wurst.setting.barrieresp.sticky_area", false);
51+
private final ColorSetting color = new ColorSetting("Barrier color",
52+
"description.wurst.setting.barrieresp.barrier_color",
53+
new Color(0xFF5555));
54+
private final CheckboxSetting fillBoxes = new CheckboxSetting("Fill boxes",
55+
"description.wurst.setting.barrieresp.fill_boxes", true);
56+
private final CheckboxSetting tracerFlash =
57+
new CheckboxSetting("Tracer flash",
58+
"description.wurst.setting.barrieresp.tracer_flash", false);
59+
private final ChunkAreaSetting area = new ChunkAreaSetting("Area",
60+
"description.wurst.setting.barrieresp.area");
61+
private final CheckboxSetting onlyAboveGround =
62+
new CheckboxSetting("Above ground only",
63+
"description.wurst.setting.barrieresp.above_ground_only", false);
64+
private final SliderSetting aboveGroundY =
65+
new SliderSetting("Set ESP Y limit",
66+
"description.wurst.setting.barrieresp.set_esp_y_limit", 62, -65,
67+
255, 1, SliderSetting.ValueDisplay.INTEGER);
68+
private final BiPredicate<BlockPos, BlockState> query =
69+
(pos, state) -> state.getBlock() == Blocks.BARRIER;
70+
private final ChunkSearcherCoordinator coordinator =
71+
new ChunkSearcherCoordinator(query, area);
72+
private final ArrayList<AABB> boxes = new ArrayList<>();
73+
private boolean boxesUpToDate;
74+
private ChunkAreaSetting.ChunkArea lastAreaSelection;
75+
private ChunkPos lastPlayerChunk;
76+
private int lastMatchesVersion;
77+
private RenderMode lastRenderMode;
78+
private boolean espEventsRegistered;
79+
1780
public BarrierEspHack()
1881
{
1982
super("BarrierESP");
2083
setCategory(Category.RENDER);
84+
addSetting(renderMode);
85+
addSetting(style);
86+
addSetting(color);
87+
addSetting(fillBoxes);
88+
addSetting(tracerFlash);
89+
addSetting(area);
90+
addSetting(stickyArea);
91+
addSetting(onlyAboveGround);
92+
addSetting(aboveGroundY);
93+
}
94+
95+
@Override
96+
protected void onEnable()
97+
{
98+
boxesUpToDate = false;
99+
lastRenderMode = renderMode.getSelected();
100+
lastAreaSelection = area.getSelected();
101+
lastPlayerChunk = ChunkPos.containing(MC.player.blockPosition());
102+
lastMatchesVersion = coordinator.getMatchesVersion();
103+
EVENTS.add(UpdateListener.class, this);
104+
if(lastRenderMode.usesEsp())
105+
addEspEvents();
106+
}
107+
108+
@Override
109+
protected void onDisable()
110+
{
111+
EVENTS.remove(UpdateListener.class, this);
112+
removeEspEvents();
113+
coordinator.reset();
114+
lastMatchesVersion = coordinator.getMatchesVersion();
115+
boxes.clear();
116+
}
117+
118+
@Override
119+
public void onUpdate()
120+
{
121+
RenderMode currentMode = renderMode.getSelected();
122+
if(currentMode != lastRenderMode)
123+
{
124+
lastRenderMode = currentMode;
125+
boxes.clear();
126+
boxesUpToDate = false;
127+
coordinator.reset();
128+
lastMatchesVersion = coordinator.getMatchesVersion();
129+
lastAreaSelection = area.getSelected();
130+
lastPlayerChunk = ChunkPos.containing(MC.player.blockPosition());
131+
132+
if(currentMode.usesEsp())
133+
addEspEvents();
134+
else
135+
removeEspEvents();
136+
}
137+
138+
if(!currentMode.usesEsp())
139+
return;
140+
141+
ChunkAreaSetting.ChunkArea currentArea = area.getSelected();
142+
if(currentArea != lastAreaSelection)
143+
{
144+
lastAreaSelection = currentArea;
145+
coordinator.reset();
146+
boxesUpToDate = false;
147+
}
148+
149+
ChunkPos currentChunk = ChunkPos.containing(MC.player.blockPosition());
150+
if(!stickyArea.isChecked() && !currentChunk.equals(lastPlayerChunk))
151+
{
152+
lastPlayerChunk = currentChunk;
153+
coordinator.reset();
154+
boxesUpToDate = false;
155+
}
156+
157+
boolean searchersChanged = coordinator.update();
158+
if(searchersChanged)
159+
boxesUpToDate = false;
160+
161+
int matchesVersion = coordinator.getMatchesVersion();
162+
if(matchesVersion != lastMatchesVersion)
163+
{
164+
lastMatchesVersion = matchesVersion;
165+
boxesUpToDate = false;
166+
}
167+
168+
boolean partialScan =
169+
WURST.getHax().globalToggleHack.usePartialChunkScan();
170+
if(!boxesUpToDate && (partialScan ? coordinator.hasReadyMatches()
171+
: coordinator.isDone()))
172+
updateBoxes();
173+
}
174+
175+
@Override
176+
public void onCameraTransformViewBobbing(
177+
CameraTransformViewBobbingEvent event)
178+
{
179+
if(!renderMode.getSelected().usesEsp())
180+
return;
181+
if(style.hasLines())
182+
event.cancel();
21183
}
22184

23-
// See ClientLevelMixin
185+
@Override
186+
public void onRender(PoseStack matrixStack, float partialTicks)
187+
{
188+
if(!renderMode.getSelected().usesEsp())
189+
return;
190+
191+
if(style.hasBoxes())
192+
renderBoxes(matrixStack);
193+
if(style.hasLines())
194+
renderTracers(matrixStack, partialTicks);
195+
}
196+
197+
private void renderBoxes(PoseStack matrixStack)
198+
{
199+
int quadsColor = color.getColorI(0x40);
200+
int linesColor = color.getColorI(0x80);
201+
if(fillBoxes.isChecked())
202+
RenderUtils.drawSolidBoxes(matrixStack, boxes, quadsColor, false);
203+
RenderUtils.drawOutlinedBoxes(matrixStack, boxes, linesColor, false);
204+
}
205+
206+
private void renderTracers(PoseStack matrixStack, float partialTicks)
207+
{
208+
List<Vec3> ends = boxes.stream().map(AABB::getCenter).toList();
209+
int tracerColor = color.getColorI(0x80);
210+
if(tracerFlash.isChecked())
211+
tracerColor = RenderUtils.flashColor(tracerColor);
212+
RenderUtils.drawTracers(matrixStack, partialTicks, ends, tracerColor,
213+
false);
214+
}
215+
216+
private void updateBoxes()
217+
{
218+
boxes.clear();
219+
int globalLimit = getEffectiveGlobalEspLimit();
220+
if(globalLimit > 0)
221+
{
222+
for(Result result : getNearestReadyMatches(globalLimit))
223+
addBarrierBox(result.pos());
224+
}else
225+
coordinator.getReadyMatches().forEach(this::addBarrierBox);
226+
227+
boxesUpToDate = true;
228+
}
229+
230+
private int getEffectiveGlobalEspLimit()
231+
{
232+
return WURST.getHax().globalToggleHack
233+
.getEffectiveGlobalEspRenderLimit();
234+
}
235+
236+
private List<Result> getNearestReadyMatches(int limit)
237+
{
238+
var eyesPos = RotationUtils.getEyesPos();
239+
return EspLimitUtils.collectNearest(coordinator.getReadyMatches(),
240+
limit, result -> result.pos().distToCenterSqr(eyesPos),
241+
this::shouldRenderResult);
242+
}
243+
244+
private boolean shouldRenderResult(Result result)
245+
{
246+
return !onlyAboveGround.isChecked()
247+
|| result.pos().getY() >= aboveGroundY.getValue();
248+
}
249+
250+
private void addBarrierBox(Result result)
251+
{
252+
addBarrierBox(result.pos());
253+
}
254+
255+
private void addBarrierBox(BlockPos pos)
256+
{
257+
if(onlyAboveGround.isChecked() && pos.getY() < aboveGroundY.getValue())
258+
return;
259+
if(!BlockUtils.canBeClicked(pos))
260+
return;
261+
AABB box = BlockUtils.getBoundingBox(pos);
262+
if(box.getSize() == 0)
263+
return;
264+
boxes.add(box);
265+
}
266+
267+
public boolean shouldRenderVanillaIcons()
268+
{
269+
return renderMode.getSelected().usesIcons();
270+
}
271+
272+
private void addEspEvents()
273+
{
274+
if(espEventsRegistered)
275+
return;
276+
277+
espEventsRegistered = true;
278+
EVENTS.add(CameraTransformViewBobbingListener.class, this);
279+
EVENTS.add(RenderListener.class, this);
280+
EVENTS.add(net.wurstclient.events.PacketInputListener.class,
281+
coordinator);
282+
}
283+
284+
private void removeEspEvents()
285+
{
286+
if(!espEventsRegistered)
287+
return;
288+
289+
espEventsRegistered = false;
290+
EVENTS.remove(CameraTransformViewBobbingListener.class, this);
291+
EVENTS.remove(RenderListener.class, this);
292+
EVENTS.remove(net.wurstclient.events.PacketInputListener.class,
293+
coordinator);
294+
}
295+
296+
private enum RenderMode
297+
{
298+
ICONS_ONLY("Icons only", false, true),
299+
ESP_ONLY("ESP only", true, false),
300+
ESP_AND_ICONS("ESP + icons", true, true);
301+
302+
private final String name;
303+
private final boolean esp;
304+
private final boolean icons;
305+
306+
private RenderMode(String name, boolean esp, boolean icons)
307+
{
308+
this.name = name;
309+
this.esp = esp;
310+
this.icons = icons;
311+
}
312+
313+
public boolean usesEsp()
314+
{
315+
return esp;
316+
}
317+
318+
public boolean usesIcons()
319+
{
320+
return icons;
321+
}
322+
323+
@Override
324+
public String toString()
325+
{
326+
return name;
327+
}
328+
}
24329
}

src/main/java/net/wurstclient/mixin/ClientLevelMixin.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ private void onGetBlockParticle(CallbackInfoReturnable<Block> cir)
3939
{
4040
if(!WurstClient.INSTANCE.getHax().barrierEspHack.isEnabled())
4141
return;
42+
if(!WurstClient.INSTANCE.getHax().barrierEspHack
43+
.shouldRenderVanillaIcons())
44+
return;
4245

4346
// Pause BarrierESP when holding a light in Creative Mode, since it
4447
// would otherwise prevent the player from seeing light blocks.

src/main/resources/assets/wurst/translations/en_us.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,16 @@
6363
"description.wurst.hack.autototem": "Automatically moves totems of undying to your off-hand.",
6464
"description.wurst.hack.autotrader": "Automatically sells selected items to villagers and merchants. Detects matching trades and performs purchases while moving results into your inventory to avoid cursor-stalls.",
6565
"description.wurst.hack.autowalk": "Makes you walk automatically.",
66+
"hack.wurst.barrieresp": "BarrierESP",
6667
"description.wurst.hack.barrieresp": "Allows you to see nearby barrier blocks.",
68+
"description.wurst.setting.barrieresp.render_mode": "Icons only: Use vanilla barrier icons with no custom ESP rendering.\nESP only: Render custom ESP without vanilla icons.\nESP + icons: Use both.",
69+
"description.wurst.setting.barrieresp.sticky_area": "Off: Re-centers every chunk to match ESP drop-off.\nOn: Keeps results anchored so you can path back to them.",
70+
"description.wurst.setting.barrieresp.barrier_color": "Barrier blocks will be highlighted in this color.",
71+
"description.wurst.setting.barrieresp.fill_boxes": "Fill barrier ESP boxes. Disable for wireframe-only rendering.",
72+
"description.wurst.setting.barrieresp.tracer_flash": "Make tracers pulse with a smooth fade.",
73+
"description.wurst.setting.barrieresp.area": "The area around the player to search in.\nHigher values require a faster computer.",
74+
"description.wurst.setting.barrieresp.above_ground_only": "Only show barriers at or above the configured Y level.",
75+
"description.wurst.setting.barrieresp.set_esp_y_limit": "Set the Y-level threshold for BarrierESP when above-ground filtering is enabled.",
6776
"description.wurst.hack.basefinder": "Finds player bases by searching for man-made blocks.\nThe blocks that it finds will be highlighted in the selected color.\nGood for finding faction bases.",
6877
"description.wurst.hack.beaconexploit": "Intercepts beacon packets and spoofs your chosen primary and secondary effects so you can request buffs like Regen II even without upgrading the beacon properly.",
6978
"description.wurst.hack.bedbreakaura": "Automatically finds and breaks nearby beds through walls, optionally switching to your best tool and switching back afterward.",

0 commit comments

Comments
 (0)