Skip to content

Commit bbf6698

Browse files
committed
Fixed ESP Filtering
1 parent 586b6e0 commit bbf6698

10 files changed

Lines changed: 404 additions & 179 deletions

File tree

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

Lines changed: 107 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,9 @@
1010
import com.mojang.blaze3d.vertex.PoseStack;
1111
import java.util.ArrayDeque;
1212
import java.util.ArrayList;
13-
import java.util.Comparator;
1413
import java.util.HashMap;
1514
import java.util.HashSet;
1615
import java.util.List;
17-
import java.util.PriorityQueue;
1816
import java.util.stream.Collectors;
1917
import net.minecraft.core.BlockPos;
2018
import net.minecraft.core.registries.BuiltInRegistries;
@@ -28,10 +26,14 @@
2826
import net.minecraft.world.entity.Entity;
2927
import net.minecraft.world.entity.animal.golem.IronGolem;
3028
import net.minecraft.world.entity.npc.villager.Villager;
29+
import net.minecraft.world.entity.vehicle.boat.AbstractChestBoat;
30+
import net.minecraft.world.entity.vehicle.minecart.MinecartChest;
31+
import net.minecraft.world.entity.vehicle.minecart.MinecartHopper;
3132
import net.minecraft.world.level.block.BarrelBlock;
3233
import net.minecraft.world.level.block.Block;
3334
import net.minecraft.world.level.block.Blocks;
3435
import net.minecraft.world.level.block.ChestBlock;
36+
import net.minecraft.world.level.block.DecoratedPotBlock;
3537
import net.minecraft.world.level.block.DoorBlock;
3638
import net.minecraft.world.level.block.HopperBlock;
3739
import net.minecraft.world.level.block.DispenserBlock;
@@ -41,6 +43,10 @@
4143
import net.minecraft.world.level.block.entity.BlockEntity;
4244
import net.minecraft.world.level.block.entity.ChestBlockEntity;
4345
import net.minecraft.world.level.block.entity.BarrelBlockEntity;
46+
import net.minecraft.world.level.block.entity.CrafterBlockEntity;
47+
import net.minecraft.world.level.block.entity.DecoratedPotBlockEntity;
48+
import net.minecraft.world.level.block.entity.DropperBlockEntity;
49+
import net.minecraft.world.level.block.entity.EnderChestBlockEntity;
4450
import net.minecraft.world.level.block.entity.HopperBlockEntity;
4551
import net.minecraft.world.level.block.entity.DispenserBlockEntity;
4652
import net.minecraft.world.level.block.entity.TrialSpawnerBlockEntity;
@@ -70,6 +76,8 @@
7076
import net.wurstclient.settings.SliderSetting;
7177
import net.wurstclient.util.BlockUtils;
7278
import net.wurstclient.util.ChatUtils;
79+
import net.wurstclient.util.EspLimitUtils;
80+
import net.wurstclient.util.LootrModCompat;
7381
import net.wurstclient.util.RenderUtils;
7482
import net.wurstclient.util.RotationUtils;
7583
import net.wurstclient.util.chunk.ChunkUtils;
@@ -407,44 +415,109 @@ private void refreshOpenedChestCacheIfNeeded()
407415
private List<BlockEntity> getNearestLoadedBlockEntities(int limit)
408416
{
409417
var eyesPos = RotationUtils.getEyesPos();
410-
PriorityQueue<BlockEntity> heap = new PriorityQueue<>(limit + 1,
411-
Comparator.comparingDouble(
412-
(BlockEntity be) -> be.getBlockPos().distToCenterSqr(eyesPos))
413-
.reversed());
414-
415-
ChunkUtils.getLoadedBlockEntities().forEach(be -> {
416-
if(heap.size() < limit)
417-
heap.offer(be);
418-
else if(be.getBlockPos().distToCenterSqr(eyesPos) < heap.peek()
419-
.getBlockPos().distToCenterSqr(eyesPos))
420-
{
421-
heap.poll();
422-
heap.offer(be);
423-
}
424-
});
425-
426-
return new ArrayList<>(heap);
418+
return EspLimitUtils.collectNearest(ChunkUtils.getLoadedBlockEntities(),
419+
limit, be -> be.getBlockPos().distToCenterSqr(eyesPos),
420+
this::isRelevantBlockEntityTarget);
427421
}
428422

429423
private List<Entity> getNearestEntitiesForRendering(int limit)
430424
{
431-
PriorityQueue<Entity> heap = new PriorityQueue<>(limit + 1,
432-
Comparator.comparingDouble((Entity e) -> e.distanceToSqr(MC.player))
433-
.reversed());
425+
return EspLimitUtils.collectNearest(MC.level.entitiesForRendering(),
426+
limit, e -> e.distanceToSqr(MC.player),
427+
this::isRelevantEntityTarget);
428+
}
429+
430+
private boolean isRelevantBlockEntityTarget(BlockEntity be)
431+
{
432+
if(be == null)
433+
return false;
434434

435-
for(Entity entity : MC.level.entitiesForRendering())
436-
{
437-
if(heap.size() < limit)
438-
heap.offer(entity);
439-
else if(entity.distanceToSqr(MC.player) < heap.peek()
440-
.distanceToSqr(MC.player))
441-
{
442-
heap.poll();
443-
heap.offer(entity);
444-
}
445-
}
435+
if(groups.pots.isEnabled() && be instanceof DecoratedPotBlockEntity)
436+
return true;
437+
438+
if(groups.furnaces.isEnabled()
439+
&& be instanceof net.minecraft.world.level.block.entity.AbstractFurnaceBlockEntity)
440+
return true;
441+
442+
if(groups.crafters.isEnabled() && be instanceof CrafterBlockEntity)
443+
return true;
444+
445+
if(groups.barrels.isEnabled() && LootrModCompat.isLootrBarrel(be))
446+
return true;
447+
if(groups.shulkerBoxes.isEnabled()
448+
&& LootrModCompat.isLootrShulkerBox(be))
449+
return true;
450+
if(groups.trapChests.isEnabled()
451+
&& LootrModCompat.isLootrTrappedChest(be))
452+
return true;
453+
454+
BlockState state = be.getBlockState();
455+
if(state == null)
456+
return false;
457+
458+
Block block = state.getBlock();
459+
if(block instanceof ChestBlock)
460+
return groups.normalChests.isEnabled()
461+
|| groups.trapChests.isEnabled();
446462

447-
return new ArrayList<>(heap);
463+
if(block == Blocks.ENDER_CHEST)
464+
return groups.enderChests.isEnabled();
465+
466+
if(block instanceof BarrelBlock)
467+
return groups.barrels.isEnabled();
468+
469+
if(block instanceof ShulkerBoxBlock)
470+
return groups.shulkerBoxes.isEnabled();
471+
472+
if(block instanceof HopperBlock)
473+
return groups.hoppers.isEnabled();
474+
475+
if(block == Blocks.DROPPER)
476+
return groups.droppers.isEnabled();
477+
478+
if(block instanceof DispenserBlock)
479+
return groups.dispensers.isEnabled();
480+
481+
if(block == Blocks.CRAFTER)
482+
return groups.crafters.isEnabled();
483+
484+
if(block == Blocks.FURNACE || block == Blocks.BLAST_FURNACE
485+
|| block == Blocks.SMOKER)
486+
return groups.furnaces.isEnabled();
487+
488+
if(block instanceof DecoratedPotBlock)
489+
return groups.pots.isEnabled();
490+
491+
// Fallbacks for odd states/modded cases.
492+
if(be instanceof EnderChestBlockEntity)
493+
return groups.enderChests.isEnabled();
494+
if(be instanceof BarrelBlockEntity)
495+
return groups.barrels.isEnabled();
496+
if(be instanceof HopperBlockEntity)
497+
return groups.hoppers.isEnabled();
498+
if(be instanceof DropperBlockEntity)
499+
return groups.droppers.isEnabled();
500+
if(be instanceof DispenserBlockEntity)
501+
return groups.dispensers.isEnabled();
502+
503+
return false;
504+
}
505+
506+
private boolean isRelevantEntityTarget(Entity entity)
507+
{
508+
if(entity == null)
509+
return false;
510+
511+
if(groups.chestCarts.isEnabled() && entity instanceof MinecartChest)
512+
return true;
513+
514+
if(groups.chestBoats.isEnabled() && entity instanceof AbstractChestBoat)
515+
return true;
516+
517+
if(groups.hopperCarts.isEnabled() && entity instanceof MinecartHopper)
518+
return true;
519+
520+
return false;
448521
}
449522

450523
@Override

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

Lines changed: 60 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,7 @@
1111
import java.awt.Color;
1212
import java.util.ArrayList;
1313
import java.util.Arrays;
14-
import java.util.Comparator;
1514
import java.util.Locale;
16-
import java.util.PriorityQueue;
1715
import net.minecraft.core.registries.BuiltInRegistries;
1816
import net.minecraft.resources.Identifier;
1917
import net.minecraft.world.InteractionHand;
@@ -45,6 +43,7 @@
4543
import net.wurstclient.settings.CheckboxSetting;
4644
import net.wurstclient.settings.SliderSetting;
4745
import net.wurstclient.util.EntityUtils;
46+
import net.wurstclient.util.EspLimitUtils;
4847
import net.wurstclient.util.RenderUtils;
4948

5049
@SearchTags({"item esp", "ItemTracers", "item tracers"})
@@ -278,11 +277,41 @@ private void ensureSpecialListCacheUpToDate()
278277
specialKeywords = kw.toArray(new String[0]);
279278
}
280279

280+
private void updateIgnoredListCacheIfNeeded()
281+
{
282+
if(!useIgnoredItems.isChecked())
283+
{
284+
ignoredExactIds = null;
285+
lastIgnoredListHash = 0;
286+
return;
287+
}
288+
289+
int h = ignoredList.getItemNames().hashCode();
290+
if(h == lastIgnoredListHash && ignoredExactIds != null)
291+
return;
292+
293+
lastIgnoredListHash = h;
294+
java.util.HashSet<String> exact = new java.util.HashSet<>();
295+
for(String s : ignoredList.getItemNames())
296+
{
297+
if(s == null)
298+
continue;
299+
String raw = s.trim();
300+
if(raw.isEmpty())
301+
continue;
302+
Identifier id = Identifier.tryParse(raw);
303+
if(id != null && BuiltInRegistries.ITEM.containsKey(id))
304+
exact.add(id.toString());
305+
}
306+
ignoredExactIds = exact;
307+
}
308+
281309
@Override
282310
public void onUpdate()
283311
{
284312
items.clear();
285313
xpOrbs.clear();
314+
updateIgnoredListCacheIfNeeded();
286315
int limit = getEffectiveGlobalEspLimit();
287316
if(limit <= 0)
288317
{
@@ -297,18 +326,11 @@ else if(entity instanceof ExperienceOrb xo)
297326
return;
298327
}
299328

300-
PriorityQueue<Entity> heap = new PriorityQueue<>(limit + 1,
301-
Comparator.comparingDouble((Entity e) -> e.distanceToSqr(MC.player))
302-
.reversed());
303-
for(Entity entity : MC.level.entitiesForRendering())
304-
{
305-
if(entity instanceof ItemEntity ie)
306-
addNearestEntity(heap, ie, limit);
307-
else if(entity instanceof ExperienceOrb xo)
308-
addNearestEntity(heap, xo, limit);
309-
}
329+
ArrayList<Entity> nearest = EspLimitUtils.collectNearest(
330+
MC.level.entitiesForRendering(), limit,
331+
e -> e.distanceToSqr(MC.player), this::isRenderableLimitedEntity);
310332

311-
for(Entity entity : heap)
333+
for(Entity entity : nearest)
312334
{
313335
if(entity instanceof ItemEntity ie)
314336
items.add(ie);
@@ -317,17 +339,33 @@ else if(entity instanceof ExperienceOrb xo)
317339
}
318340
}
319341

320-
private void addNearestEntity(PriorityQueue<Entity> heap, Entity entity,
321-
int limit)
342+
private boolean isRenderableLimitedEntity(Entity entity)
322343
{
323-
if(heap.size() < limit)
324-
heap.offer(entity);
325-
else if(entity.distanceToSqr(MC.player) < heap.peek()
326-
.distanceToSqr(MC.player))
344+
if(entity instanceof ItemEntity ie)
327345
{
328-
heap.poll();
329-
heap.offer(entity);
346+
if(onlyAboveGround.isChecked()
347+
&& ie.getY() < aboveGroundY.getValue())
348+
return false;
349+
350+
ItemStack stack = ie.getItem();
351+
return stack != null && !stack.isEmpty() && !isIgnored(stack);
352+
}
353+
354+
if(entity instanceof ExperienceOrb xo)
355+
{
356+
if(xpMode.getSelected() == XpMode.OFF)
357+
return false;
358+
359+
if(onlyAboveGround.isChecked()
360+
&& xo.getY() < aboveGroundY.getValue())
361+
return false;
362+
363+
ItemStack stack =
364+
net.wurstclient.util.ItemUtils.createSyntheticXpStack(xo);
365+
return !isIgnored(stack);
330366
}
367+
368+
return false;
331369
}
332370

333371
private int getEffectiveGlobalEspLimit()
@@ -356,31 +394,7 @@ public void onRender(PoseStack matrixStack, float partialTicks)
356394
ensureSpecialListCacheUpToDate();
357395

358396
// Update ignored list cache when needed
359-
if(useIgnoredItems.isChecked())
360-
{
361-
int h = ignoredList.getItemNames().hashCode();
362-
if(h != lastIgnoredListHash || ignoredExactIds == null)
363-
{
364-
lastIgnoredListHash = h;
365-
java.util.HashSet<String> exact = new java.util.HashSet<>();
366-
for(String s : ignoredList.getItemNames())
367-
{
368-
if(s == null)
369-
continue;
370-
String raw = s.trim();
371-
if(raw.isEmpty())
372-
continue;
373-
Identifier id = Identifier.tryParse(raw);
374-
if(id != null && BuiltInRegistries.ITEM.containsKey(id))
375-
exact.add(id.toString());
376-
}
377-
ignoredExactIds = exact;
378-
}
379-
}else
380-
{
381-
ignoredExactIds = null;
382-
lastIgnoredListHash = 0;
383-
}
397+
updateIgnoredListCacheIfNeeded();
384398

385399
// Partition items into normal vs special
386400
ArrayList<AABB> normalBoxes = new ArrayList<>();

0 commit comments

Comments
 (0)