2525import net .minecraft .util .math .ChunkPos ;
2626import net .minecraft .world .chunk .Chunk ;
2727import net .minecraft .world .dimension .DimensionType ;
28+ import net .minecraft .block .BlockState ;
29+ import net .minecraft .state .property .Property ;
2830
2931import java .util .Iterator ;
3032import java .util .List ;
3133import java .util .Map ;
3234import java .util .Set ;
3335import java .util .concurrent .ExecutorService ;
3436import java .util .concurrent .Executors ;
37+ import java .util .HashMap ;
38+ import java .util .Optional ;
3539
3640public class BlockESP extends Module {
3741 private final SettingGroup sgGeneral = settings .getDefaultGroup ();
3842
3943 // General
4044
41- private final Setting <List <Block >> blocks = sgGeneral .add (new BlockListSetting .Builder ()
42- .name ("blocks" )
43- .description ("Blocks to search for." )
44- .onChanged (blocks1 -> {
45- if (isActive () && Utils .canUpdate ()) onActivate ();
46- })
47- .build ()
45+ private final Setting <List <Block >> blocks = sgGeneral .add (
46+ new BlockListSetting .Builder ()
47+ .name ("blocks" )
48+ .description ("Blocks to search for." )
49+ .onChanged (blocks1 -> {
50+ if (isActive () && Utils .canUpdate ()) onActivate ();
51+ })
52+ .build ()
4853 );
49-
50- private final Setting <ESPBlockData > defaultBlockConfig = sgGeneral .add (new GenericSetting .Builder <ESPBlockData >()
51- .name ("default-block-config" )
52- .description ("Default block config." )
53- .defaultValue (
54- new ESPBlockData (
55- ShapeMode .Lines ,
56- new SettingColor (0 , 255 , 200 ),
57- new SettingColor (0 , 255 , 200 , 25 ),
58- true ,
59- new SettingColor (0 , 255 , 200 , 125 )
54+
55+
56+ private final Setting <ESPBlockData > defaultBlockConfig = sgGeneral .add (
57+ new GenericSetting .Builder <ESPBlockData >()
58+ .name ("default-block-config" )
59+ .description ("Default block config." )
60+ .defaultValue (
61+ new ESPBlockData (
62+ ShapeMode .Lines ,
63+ new SettingColor (0 , 255 , 200 ),
64+ new SettingColor (0 , 255 , 200 , 25 ),
65+ true ,
66+ new SettingColor (0 , 255 , 200 , 125 )
67+ )
6068 )
61- )
62- .build ()
63- );
64-
65- private final Setting <Map <Block , ESPBlockData >> blockConfigs = sgGeneral .add (new BlockDataSetting .Builder <ESPBlockData >()
66- .name ("block-configs" )
67- .description ("Config for each block." )
68- .defaultData (defaultBlockConfig )
69- .build ()
69+ .build ()
7070 );
7171
72- private final Setting <Boolean > tracers = sgGeneral .add (new BoolSetting .Builder ()
73- .name ("tracers" )
74- .description ("Render tracer lines." )
75- .defaultValue (false )
76- .build ()
72+ private final Setting <Map <Block , ESPBlockData >> blockConfigs =
73+ sgGeneral .add (
74+ new BlockDataSetting .Builder <ESPBlockData >()
75+ .name ("block-configs" )
76+ .description ("Config for each block." )
77+ .defaultData (defaultBlockConfig )
78+ .onChanged (configs -> {
79+ if (isActive () && Utils .canUpdate ()) onActivate ();
80+ })
81+ .build ()
82+ );
83+
84+ private final Setting <Boolean > tracers = sgGeneral .add (
85+ new BoolSetting .Builder ()
86+ .name ("tracers" )
87+ .description ("Render tracer lines." )
88+ .defaultValue (false )
89+ .build ()
7790 );
7891
7992 private final BlockPos .Mutable blockPos = new BlockPos .Mutable ();
8093
8194 private final Long2ObjectMap <ESPChunk > chunks = new Long2ObjectOpenHashMap <>();
8295 private final Set <ESPGroup > groups = new ReferenceOpenHashSet <>();
83- private final ExecutorService workerThread = Executors .newSingleThreadExecutor ();
96+ private final ExecutorService workerThread =
97+ Executors .newSingleThreadExecutor ();
8498
8599 private DimensionType lastDimension ;
86100
87101 public BlockESP () {
88- super (Categories .Render , "block-esp" , "Renders specified blocks through walls." , "search" );
89-
102+ super (
103+ Categories .Render ,
104+ "block-esp" ,
105+ "Renders specified blocks through walls." ,
106+ "search"
107+ );
90108 RainbowColors .register (this ::onTickRainbow );
91109 }
92110
@@ -161,8 +179,7 @@ private void onChunkData(ChunkDataEvent event) {
161179 private void searchChunk (Chunk chunk ) {
162180 workerThread .submit (() -> {
163181 if (!isActive ()) return ;
164- ESPChunk schunk = ESPChunk .searchChunk (chunk , blocks .get ());
165-
182+ ESPChunk schunk = ESPChunk .searchChunk (chunk , this );
166183 if (schunk .size () > 0 ) {
167184 synchronized (chunks ) {
168185 chunks .put (chunk .getPos ().toLong (), schunk );
@@ -189,8 +206,8 @@ private void onBlockUpdate(BlockUpdateEvent event) {
189206 int chunkZ = bz >> 4 ;
190207 long key = ChunkPos .toLong (chunkX , chunkZ );
191208
192- boolean added = blocks . get (). contains ( event .newState . getBlock ()) && !blocks . get (). contains ( event .oldState . getBlock () );
193- boolean removed = !added && !blocks . get (). contains ( event .newState . getBlock ()) && blocks . get (). contains ( event .oldState . getBlock () );
209+ boolean added = shouldRender ( event .newState ) && !shouldRender ( event .oldState );
210+ boolean removed = !added && !shouldRender ( event .newState ) && shouldRender ( event .oldState );
194211
195212 if (added || removed ) {
196213 workerThread .submit (() -> {
@@ -263,4 +280,28 @@ private void onRender(Render3DEvent event) {
263280 public String getInfoString () {
264281 return "%s groups" .formatted (groups .size ());
265282 }
283+
284+
285+ public boolean shouldRender (BlockState state ) {
286+ Block block = state .getBlock ();
287+ if (!blocks .get ().contains (block )) return false ;
288+
289+ ESPBlockData data = getBlockData (block );
290+ for (String filter : data .stateFilters ) {
291+ String [] kv = filter .split ("=" );
292+ if (kv .length != 2 ) return false ;
293+
294+ Property <?> property = block .getStateManager ().getProperty (kv [0 ].trim ());
295+ if (property == null ) return false ;
296+
297+ Optional <?> parsed = property .parse (kv [1 ].trim ());
298+ if (parsed .isEmpty ()) return false ;
299+
300+ if (!state .get (property ).equals (parsed .get ())) return false ;
301+ }
302+
303+ return true ;
304+ }
305+
306+
266307}
0 commit comments