Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -25,68 +25,106 @@
import net.minecraft.util.math.ChunkPos;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.dimension.DimensionType;
import net.minecraft.block.BlockState;
import net.minecraft.state.property.Property;

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.HashMap;
import java.util.Optional;

public class BlockESP extends Module {
private final SettingGroup sgGeneral = settings.getDefaultGroup();

// General

private final Setting<List<Block>> blocks = sgGeneral.add(new BlockListSetting.Builder()
.name("blocks")
.description("Blocks to search for.")
.onChanged(blocks1 -> {
if (isActive() && Utils.canUpdate()) onActivate();
})
.build()
private final Setting<List<Block>> blocks = sgGeneral.add(
new BlockListSetting.Builder()
.name("blocks")
.description("Blocks to search for.")
.onChanged(blocks1 -> {
if (isActive() && Utils.canUpdate()) onActivate();
})
.build()
);

private final Setting<ESPBlockData> defaultBlockConfig = sgGeneral.add(new GenericSetting.Builder<ESPBlockData>()
.name("default-block-config")
.description("Default block config.")
.defaultValue(
new ESPBlockData(
ShapeMode.Lines,
new SettingColor(0, 255, 200),
new SettingColor(0, 255, 200, 25),
true,
new SettingColor(0, 255, 200, 125)

// uncomment if NBT-Data should apply to all blocks !!! UNTESTED !!!

/*
private final Setting<List<String>> customFilters = sgGeneral.add(
new StringListSetting.Builder()
.name("NTB-Data")
.description(
"Filters with ntbdata (e.g. 'waterlogged=true')."
)
)
.build()
.defaultValue(new ArrayList<>())
.onChanged(this::parseFilters)
.build()
);

private final Setting<Map<Block, ESPBlockData>> blockConfigs = sgGeneral.add(new BlockDataSetting.Builder<ESPBlockData>()
.name("block-configs")
.description("Config for each block.")
.defaultData(defaultBlockConfig)
.build()
*/

private final Setting<ESPBlockData> defaultBlockConfig = sgGeneral.add(
new GenericSetting.Builder<ESPBlockData>()
.name("default-block-config")
.description("Default block config.")
.defaultValue(
new ESPBlockData(
ShapeMode.Lines,
new SettingColor(0, 255, 200),
new SettingColor(0, 255, 200, 25),
true,
new SettingColor(0, 255, 200, 125)
)
)
.build()
);

private final Setting<Boolean> tracers = sgGeneral.add(new BoolSetting.Builder()
.name("tracers")
.description("Render tracer lines.")
.defaultValue(false)
.build()
private final Setting<Map<Block, ESPBlockData>> blockConfigs =
sgGeneral.add(
new BlockDataSetting.Builder<ESPBlockData>()
.name("block-configs")
.description("Config for each block.")
.defaultData(defaultBlockConfig)
.onChanged(configs -> {
if (isActive() && Utils.canUpdate()) onActivate();
})
.build()
);

private final Setting<Boolean> tracers = sgGeneral.add(
new BoolSetting.Builder()
.name("tracers")
.description("Render tracer lines.")
.defaultValue(false)
.build()
);

private final BlockPos.Mutable blockPos = new BlockPos.Mutable();

private final Long2ObjectMap<ESPChunk> chunks = new Long2ObjectOpenHashMap<>();
private final Map<
Block,
Map<Property<?>, Comparable<?>>
> activeFilterCache = new HashMap<>();
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this map is always empty


private final Long2ObjectMap<ESPChunk> chunks =
new Long2ObjectOpenHashMap<>();
private final Set<ESPGroup> groups = new ReferenceOpenHashSet<>();
private final ExecutorService workerThread = Executors.newSingleThreadExecutor();
private final ExecutorService workerThread =
Executors.newSingleThreadExecutor();

private DimensionType lastDimension;

public BlockESP() {
super(Categories.Render, "block-esp", "Renders specified blocks through walls.", "search");

super(
Categories.Render,
"block-esp",
"Renders specified blocks through walls.",
"search"
);
RainbowColors.register(this::onTickRainbow);
}

Expand Down Expand Up @@ -161,8 +199,7 @@ private void onChunkData(ChunkDataEvent event) {
private void searchChunk(Chunk chunk) {
workerThread.submit(() -> {
if (!isActive()) return;
ESPChunk schunk = ESPChunk.searchChunk(chunk, blocks.get());

ESPChunk schunk = ESPChunk.searchChunk(chunk, this);
if (schunk.size() > 0) {
synchronized (chunks) {
chunks.put(chunk.getPos().toLong(), schunk);
Expand All @@ -189,8 +226,8 @@ private void onBlockUpdate(BlockUpdateEvent event) {
int chunkZ = bz >> 4;
long key = ChunkPos.toLong(chunkX, chunkZ);

boolean added = blocks.get().contains(event.newState.getBlock()) && !blocks.get().contains(event.oldState.getBlock());
boolean removed = !added && !blocks.get().contains(event.newState.getBlock()) && blocks.get().contains(event.oldState.getBlock());
boolean added = shouldRender(event.newState) && !shouldRender(event.oldState);
boolean removed = !added && !shouldRender(event.newState) && shouldRender(event.oldState);

if (added || removed) {
workerThread.submit(() -> {
Expand Down Expand Up @@ -263,4 +300,56 @@ private void onRender(Render3DEvent event) {
public String getInfoString() {
return "%s groups".formatted(groups.size());
}


public boolean shouldRender(BlockState state) {
Block block = state.getBlock();

if (blocks.get().contains(block)) {
ESPBlockData blockData = blockConfigs.get().get(block);
if (blockData != null && !blockData.stateFilters.isEmpty()) {
return matchesStateFilters(state, block, blockData.stateFilters);
}
return true;
}

// Check global state filters
if (activeFilterCache.containsKey(block)) {
Map<Property<?>, Comparable<?>> requiredProps = activeFilterCache.get(block);
for (Map.Entry<Property<?>,Comparable<?>> entry : requiredProps.entrySet()) {
if (!state.get(entry.getKey()).equals(entry.getValue())) {
return false;
}
}
return true;
}
return false;
}

private boolean matchesStateFilters(BlockState state, Block block, List<String> filters) {
for (String filter : filters) {
try {
// Parse "key=value" format
String[] kv = filter.split("=");
if (kv.length != 2) continue;

String propertyName = kv[0].trim();
String expectedValue = kv[1].trim();

Property<?> property = block.getStateManager().getProperty(propertyName);
if (property == null) continue;

Optional<?> parsedValue = property.parse(expectedValue);
if (parsedValue.isEmpty()) continue;

if (!state.get(property).equals(parsedValue.get())) {
return false;
}
} catch (Exception e) {
// Invalid filter format
}
}

return true;
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a hot method, parsing should be done ahead of time

}
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@ private boolean isNeighbour(Direction dir) {

if (neighbourState.getBlock() != state.getBlock()) return false;

if (!blockEsp.shouldRender(neighbourState)) return false;

VoxelShape cube = VoxelShapes.fullCube();
VoxelShape shape = state.getOutlineShape(mc.world, blockPos);
VoxelShape neighbourShape = neighbourState.getOutlineShape(mc.world, blockPos);
Expand Down Expand Up @@ -165,7 +167,8 @@ private boolean isNeighbour(Direction dir) {

private boolean isNeighbourDiagonal(double x, double y, double z) {
blockPos.set(this.x + x, this.y + y, this.z + z);
return state.getBlock() == mc.world.getBlockState(blockPos).getBlock();
BlockState neighbourState = mc.world.getBlockState(blockPos);
return state.getBlock() == neighbourState.getBlock() && blockEsp.shouldRender(neighbourState);
}

public void render(Render3DEvent event) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@

package meteordevelopment.meteorclient.systems.modules.render.blockesp;

import java.util.ArrayList;
import java.util.List;


import meteordevelopment.meteorclient.gui.GuiTheme;
import meteordevelopment.meteorclient.gui.WidgetScreen;
import meteordevelopment.meteorclient.renderer.ShapeMode;
Expand All @@ -16,6 +20,8 @@
import meteordevelopment.meteorclient.utils.render.color.SettingColor;
import net.minecraft.block.Block;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtList;
import net.minecraft.nbt.NbtString;

public class ESPBlockData implements IGeneric<ESPBlockData>, IChangeable, IBlockData<ESPBlockData> {
public ShapeMode shapeMode;
Expand All @@ -25,6 +31,8 @@ public class ESPBlockData implements IGeneric<ESPBlockData>, IChangeable, IBlock
public boolean tracer;
public SettingColor tracerColor;

public List<String> stateFilters = new ArrayList<>();
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be final


private boolean changed;

public ESPBlockData(ShapeMode shapeMode, SettingColor lineColor, SettingColor sideColor, boolean tracer, SettingColor tracerColor) {
Expand Down Expand Up @@ -70,14 +78,19 @@ public ESPBlockData set(ESPBlockData value) {
tracer = value.tracer;
tracerColor.set(value.tracerColor);

stateFilters.clear();
stateFilters.addAll(value.stateFilters);

changed = value.changed;

return this;
}

@Override
public ESPBlockData copy() {
return new ESPBlockData(shapeMode, new SettingColor(lineColor), new SettingColor(sideColor), tracer, new SettingColor(tracerColor));
ESPBlockData copy = new ESPBlockData(shapeMode, new SettingColor(lineColor), new SettingColor(sideColor), tracer, new SettingColor(tracerColor));
copy.stateFilters.addAll(stateFilters);
return copy;
}

@Override
Expand All @@ -91,6 +104,12 @@ public NbtCompound toTag() {
tag.putBoolean("tracer", tracer);
tag.put("tracerColor", tracerColor.toTag());

NbtList filtersList = new NbtList();
for (String filter : stateFilters) {
filtersList.add(NbtString.of(filter));
}
tag.put("NBT-Data", filtersList);

tag.putBoolean("changed", changed);

return tag;
Expand All @@ -105,6 +124,14 @@ public ESPBlockData fromTag(NbtCompound tag) {
tracer = tag.getBoolean("tracer", false);
tracerColor.fromTag(tag.getCompoundOrEmpty("tracerColor"));

stateFilters.clear();
tag.getList("NBT-Data").ifPresent(filtersList -> {
for (int i = 0; i < filtersList.size(); i++) {
filtersList.getString(i).ifPresent(stateFilters::add);
}
});


changed = tag.getBoolean("changed", false);

return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
import net.minecraft.block.Block;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;

public class ESPBlockDataScreen extends WindowScreen {
private final ESPBlockData blockData;
private final Setting<?> setting;
Expand All @@ -39,6 +41,7 @@ public void initWidgets() {
Settings settings = new Settings();
SettingGroup sgGeneral = settings.getDefaultGroup();
SettingGroup sgTracer = settings.createGroup("Tracer");
SettingGroup sgFilters = settings.createGroup("NBT-Data");

sgGeneral.add(new EnumSetting.Builder<ShapeMode>()
.name("shape-mode")
Expand Down Expand Up @@ -110,6 +113,20 @@ public void initWidgets() {
.build()
);

// Add state filters setting
sgFilters.add(new StringListSetting.Builder()
.name("NBT-Data")
.description("Filters with states (e.g. 'waterlogged=false', 'facing=north', 'ominous=true'). Only blocks matching ALL filters will be shown.")
.defaultValue(new ArrayList<>())
.onModuleActivated(stringSetting -> stringSetting.set(blockData.stateFilters))
.onChanged(filters -> {
blockData.stateFilters.clear();
blockData.stateFilters.addAll(filters);
onChanged();
})
.build()
);
Comment on lines +117 to +128
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

imho using a string list for this is super unintuitive, it should be a separate setting type


settings.onActivated();
add(theme.settings(settings)).expandX();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public void render(Render3DEvent event) {
}


public static ESPChunk searchChunk(Chunk chunk, List<Block> blocks) {
public static ESPChunk searchChunk(Chunk chunk, BlockESP module) {
ESPChunk schunk = new ESPChunk(chunk.getPos().x, chunk.getPos().z);
if (schunk.shouldBeDeleted()) return schunk;

Expand All @@ -100,7 +100,7 @@ public static ESPChunk searchChunk(Chunk chunk, List<Block> blocks) {
blockPos.set(x, y, z);
BlockState bs = chunk.getBlockState(blockPos);

if (blocks.contains(bs.getBlock())) schunk.add(blockPos, false);
if (module.shouldRender(bs)) schunk.add(blockPos, false);
}
}
}
Expand Down