Skip to content

Commit 64cc9fb

Browse files
committed
Updated AutoBuild, Added ChorusFruit Hack
1 parent c01be39 commit 64cc9fb

File tree

6 files changed

+582
-33
lines changed

6 files changed

+582
-33
lines changed

README.md

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -536,12 +536,21 @@ Credits to [Trouser-Streak](https://github.com/etianl/Trouser-Streak/blob/main/s
536536
![Warden](https://i.imgur.com/ZBYXxmH.png)
537537

538538
### MeasurementESP
539-
- Command-only ESP tool that draws a 1x1 box at a specified distance along your look direction
539+
- Navigator/Command-only ESP tool that draws a 1x1 box at a specified distance along your look direction
540540
- Box color shows air vs solid: green (air + above air), yellow (air), red (solid). Basically, can I fit in there?
541541
- Commands are: ```.measurementesp <distance>``` to enable and ```.measurementesp off``` to disable
542542
- You can also mark the target, so keep a fixed box by running the command ```.measurementesp mark```, which can then be cleared with ```.measurementesp clear```.
543543
- Usecase? Custom mods/datapacks that allow teleportation or weapons and tools that only work at a specific distance, or perhaps just literally measuring.
544544

545+
### ChorusFruit
546+
- Navigator only hack that allows you to consume chorus fruit when a selected trigger happens and or your health is low
547+
- On player enter
548+
- On damage from player
549+
- On damage from all
550+
- Packet spam to help aid in the speed of consumtion
551+
- Silent switching and returning to previous item upon consumption
552+
- This hack is mostly designed for a specific datapack that allows a much greater range/distance of teleportation with these fruits
553+
545554
## What's changed or improved in this fork?
546555

547556
### ChestESP
@@ -733,6 +742,14 @@ Examples:
733742
- Can now multi-select and delete alt accounts
734743
- Moved to multiplayer screen
735744

745+
### AutoBuild Improved
746+
- Air-start position support and continued air place for gaps in build
747+
- Template preview shows a ghost of the template which locks in position when freecam is activated
748+
- Placement validation, blocks are only considered done when the world has a non-replaceable block in that position
749+
- Stuck handling, if the strict build order fails it temporarily relaxes the order so it can resume easier
750+
- CTRL (Sprint) bypass, by holding it you can add your own blocks at any time, before during or after the build
751+
- Adjustable confirmation ticks
752+
736753
### Wurst Options
737754
- Added to home screen and put in the old spot of Alt Manager
738755
- Added reload settings button so you can modify the settings.json manually

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,22 @@ public void reloadSettings()
247247
public void reloadFromDisk()
248248
{
249249
reloadSettings();
250+
251+
if(hax != null)
252+
{
253+
hax.tooManyHaxHack.loadBlockedHacksFile();
254+
hax.reloadEnabledHax();
255+
hax.reloadFavoriteHax();
256+
}
257+
258+
if(keybinds != null)
259+
keybinds.reload();
260+
261+
if(navigator != null)
262+
navigator.reloadPreferences();
263+
264+
if(gui != null)
265+
gui.init();
250266
}
251267

252268
public ArrayList<Path> listSettingsProfiles()

src/main/java/net/wurstclient/hack/HackList.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ public final class HackList implements UpdateListener
9494
public final CameraNoClipHack cameraNoClipHack = new CameraNoClipHack();
9595
public final CaveFinderHack caveFinderHack = new CaveFinderHack();
9696
public final CheatDetectorHack cheatDetectorHack = new CheatDetectorHack();
97+
public final ChorusFruitHack chorusFruitHack = new ChorusFruitHack();
9798
public final LivestreamDetectorHack livestreamDetectorHack =
9899
new LivestreamDetectorHack();
99100
public final ChatTranslatorHack chatTranslatorHack =

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

Lines changed: 194 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,18 @@
1010
import com.mojang.blaze3d.vertex.PoseStack;
1111
import java.io.IOException;
1212
import java.nio.file.Path;
13+
import java.util.HashMap;
1314
import java.util.LinkedHashMap;
1415
import java.util.List;
1516
import java.util.Map;
1617
import net.minecraft.core.BlockPos;
1718
import net.minecraft.core.Direction;
1819
import net.minecraft.world.entity.player.Inventory;
20+
import net.minecraft.world.item.BlockItem;
1921
import net.minecraft.world.item.Item;
2022
import net.minecraft.world.item.ItemStack;
2123
import net.minecraft.world.item.Items;
24+
import net.minecraft.world.level.block.state.BlockState;
2225
import net.minecraft.world.phys.AABB;
2326
import net.minecraft.world.phys.BlockHitResult;
2427
import net.minecraft.world.phys.HitResult;
@@ -75,10 +78,27 @@ public final class AutoBuildHack extends Hack
7578
+ " template. This is slower, but provides more consistent results.",
7679
false);
7780

81+
private final CheckboxSetting previewTemplate =
82+
new CheckboxSetting("Preview template",
83+
"Shows a visual preview before starting the build.", true);
84+
85+
private final SliderSetting confirmTicks =
86+
new SliderSetting("Confirm ticks",
87+
"How many ticks a placed block must stay visible before it is"
88+
+ " removed from the remaining list.",
89+
2, 1, 10, 1, ValueDisplay.INTEGER.withSuffix(" ticks"));
90+
7891
private Status status = Status.NO_TEMPLATE;
7992
private AutoBuildTemplate template;
8093
private LinkedHashMap<BlockPos, Item> remainingBlocks =
8194
new LinkedHashMap<>();
95+
private LinkedHashMap<BlockPos, Item> previewBlocks = new LinkedHashMap<>();
96+
private BlockPos previewStartPos;
97+
private Direction previewDirection;
98+
private long lastProgressMs;
99+
private final Map<BlockPos, Integer> placedConfirmations = new HashMap<>();
100+
101+
private static final long STUCK_TIMEOUT_MS = 1250L;
82102

83103
public AutoBuildHack()
84104
{
@@ -90,6 +110,8 @@ public AutoBuildHack()
90110
addSetting(useSavedBlocks);
91111
addSetting(fastPlace);
92112
addSetting(strictBuildOrder);
113+
addSetting(previewTemplate);
114+
addSetting(confirmTicks);
93115
}
94116

95117
@Override
@@ -140,6 +162,8 @@ protected void onDisable()
140162
EVENTS.remove(RenderListener.class, this);
141163

142164
remainingBlocks.clear();
165+
previewBlocks.clear();
166+
placedConfirmations.clear();
143167

144168
if(template == null)
145169
status = Status.NO_TEMPLATE;
@@ -153,26 +177,29 @@ public void onRightClick(RightClickEvent event)
153177
if(status == Status.NO_TEMPLATE || status == Status.LOADING)
154178
return;
155179

156-
HitResult hitResult = MC.hitResult;
157-
if(hitResult == null || hitResult.getType() != HitResult.Type.BLOCK
158-
|| !(hitResult instanceof BlockHitResult blockHitResult))
180+
if(MC.options.keySprint.isDown())
159181
return;
160182

161-
BlockPos hitResultPos = blockHitResult.getBlockPos();
162-
boolean clickable = BlockUtils.canBeClicked(hitResultPos);
163-
if(clickable)
164-
event.cancel();
165-
166183
if(status != Status.IDLE)
167184
return;
168185

169-
if(!clickable)
186+
BlockHitResult blockHitResult = getStartHitResult();
187+
if(blockHitResult == null)
188+
return;
189+
190+
boolean airStart = blockHitResult.getType() == HitResult.Type.MISS;
191+
BlockPos hitResultPos = blockHitResult.getBlockPos();
192+
boolean clickable = BlockUtils.canBeClicked(hitResultPos);
193+
if(!airStart && !clickable)
170194
return;
171195

172-
BlockPos startPos =
173-
hitResultPos.relative(blockHitResult.getDirection());
196+
event.cancel();
197+
198+
BlockPos startPos = airStart ? hitResultPos
199+
: hitResultPos.relative(blockHitResult.getDirection());
174200
Direction direction = MC.player.getDirection();
175201
remainingBlocks = template.getBlocksToPlace(startPos, direction);
202+
lastProgressMs = System.currentTimeMillis();
176203

177204
status = Status.BUILDING;
178205
}
@@ -192,6 +219,7 @@ public void onUpdate()
192219
case IDLE:
193220
if(!template.isSelected(templateSetting))
194221
loadSelectedTemplate();
222+
updatePreview();
195223
break;
196224

197225
case BUILDING:
@@ -203,31 +231,43 @@ public void onUpdate()
203231
@Override
204232
public void onRender(PoseStack matrixStack, float partialTicks)
205233
{
206-
if(status != Status.BUILDING)
234+
if(status == Status.BUILDING)
235+
{
236+
renderBlocks(matrixStack, remainingBlocks, 0x2600FF00);
207237
return;
238+
}
208239

209-
List<BlockPos> blocksToDraw = remainingBlocks.keySet().stream()
210-
.filter(pos -> BlockUtils.getState(pos).canBeReplaced()).limit(1024)
211-
.toList();
212-
213-
int black = 0x80000000;
214-
List<AABB> outlineBoxes =
215-
blocksToDraw.stream().map(pos -> BLOCK_BOX.move(pos)).toList();
216-
RenderUtils.drawOutlinedBoxes(matrixStack, outlineBoxes, black, true);
217-
218-
int green = 0x2600FF00;
219-
Vec3 eyesPos = RotationUtils.getEyesPos();
220-
double rangeSq = range.getValueSq();
221-
List<AABB> greenBoxes = blocksToDraw.stream()
222-
.filter(pos -> pos.distToCenterSqr(eyesPos) <= rangeSq)
223-
.map(pos -> BLOCK_BOX.move(pos)).toList();
224-
RenderUtils.drawSolidBoxes(matrixStack, greenBoxes, green, true);
240+
if(status == Status.IDLE && previewTemplate.isChecked())
241+
renderBlocks(matrixStack, previewBlocks, 0x2600A0FF);
225242
}
226243

227244
private void buildNormally()
228245
{
229-
remainingBlocks.keySet()
230-
.removeIf(pos -> !BlockUtils.getState(pos).canBeReplaced());
246+
int beforeSize = remainingBlocks.size();
247+
remainingBlocks.entrySet().removeIf(entry -> {
248+
BlockPos pos = entry.getKey();
249+
if(!isBlockPlaced(pos, entry.getValue()))
250+
{
251+
placedConfirmations.remove(pos);
252+
return false;
253+
}
254+
255+
int count = placedConfirmations.getOrDefault(pos, 0) + 1;
256+
int required = Math.max(1, confirmTicks.getValueI());
257+
if(count < required)
258+
{
259+
placedConfirmations.put(pos, count);
260+
return false;
261+
}
262+
263+
placedConfirmations.remove(pos);
264+
return true;
265+
});
266+
if(remainingBlocks.size() != beforeSize)
267+
lastProgressMs = System.currentTimeMillis();
268+
269+
if(!placedConfirmations.isEmpty())
270+
return;
231271

232272
if(remainingBlocks.isEmpty())
233273
{
@@ -239,15 +279,16 @@ private void buildNormally()
239279
return;
240280

241281
double rangeSq = range.getValueSq();
282+
boolean stuck = isStuck();
242283
for(Map.Entry<BlockPos, Item> entry : remainingBlocks.entrySet())
243284
{
244285
BlockPos pos = entry.getKey();
245286
Item item = entry.getValue();
246287

247-
BlockPlacingParams params = BlockPlacer.getBlockPlacingParams(pos);
288+
BlockPlacingParams params = getPlacingParams(pos);
248289
if(params == null || params.distanceSq() > rangeSq
249290
|| checkLOS.isChecked() && !params.lineOfSight())
250-
if(strictBuildOrder.isChecked())
291+
if(strictBuildOrder.isChecked() && !stuck)
251292
return;
252293
else
253294
continue;
@@ -293,6 +334,11 @@ private void loadSelectedTemplate()
293334
{
294335
template = AutoBuildTemplate.load(path);
295336
status = Status.IDLE;
337+
previewBlocks.clear();
338+
previewStartPos = null;
339+
previewDirection = null;
340+
placedConfirmations.clear();
341+
lastProgressMs = System.currentTimeMillis();
296342

297343
}catch(IOException | JsonException e)
298344
{
@@ -313,6 +359,122 @@ public Path getFolder()
313359
return templateSetting.getFolder();
314360
}
315361

362+
private void updatePreview()
363+
{
364+
if(!previewTemplate.isChecked() || template == null)
365+
{
366+
previewBlocks.clear();
367+
return;
368+
}
369+
370+
if(WURST.getHax().freecamHack.isEnabled() && !previewBlocks.isEmpty())
371+
return;
372+
373+
BlockHitResult blockHitResult = getStartHitResult();
374+
if(blockHitResult == null)
375+
{
376+
if(!WURST.getHax().freecamHack.isEnabled())
377+
previewBlocks.clear();
378+
return;
379+
}
380+
381+
boolean airStart = blockHitResult.getType() == HitResult.Type.MISS;
382+
BlockPos hitResultPos = blockHitResult.getBlockPos();
383+
if(!airStart && !BlockUtils.canBeClicked(hitResultPos))
384+
{
385+
previewBlocks.clear();
386+
return;
387+
}
388+
389+
BlockPos startPos = airStart ? hitResultPos
390+
: hitResultPos.relative(blockHitResult.getDirection());
391+
Direction direction = MC.player.getDirection();
392+
393+
if(startPos.equals(previewStartPos) && direction == previewDirection
394+
&& !previewBlocks.isEmpty())
395+
return;
396+
397+
previewStartPos = startPos;
398+
previewDirection = direction;
399+
previewBlocks = template.getBlocksToPlace(startPos, direction);
400+
}
401+
402+
private void renderBlocks(PoseStack matrixStack,
403+
LinkedHashMap<BlockPos, Item> blocks, int solidColor)
404+
{
405+
if(blocks.isEmpty())
406+
return;
407+
408+
List<BlockPos> blocksToDraw = blocks.keySet().stream()
409+
.filter(pos -> BlockUtils.getState(pos).canBeReplaced()).limit(1024)
410+
.toList();
411+
412+
int black = 0x80000000;
413+
List<AABB> outlineBoxes =
414+
blocksToDraw.stream().map(pos -> BLOCK_BOX.move(pos)).toList();
415+
RenderUtils.drawOutlinedBoxes(matrixStack, outlineBoxes, black, true);
416+
417+
Vec3 eyesPos = RotationUtils.getEyesPos();
418+
double rangeSq = range.getValueSq();
419+
List<AABB> solidBoxes = blocksToDraw.stream()
420+
.filter(pos -> pos.distToCenterSqr(eyesPos) <= rangeSq)
421+
.map(pos -> BLOCK_BOX.move(pos)).toList();
422+
RenderUtils.drawSolidBoxes(matrixStack, solidBoxes, solidColor, true);
423+
}
424+
425+
private BlockPlacingParams getPlacingParams(BlockPos pos)
426+
{
427+
BlockPlacingParams params = BlockPlacer.getBlockPlacingParams(pos);
428+
if(params != null)
429+
return params;
430+
431+
Vec3 hitVec = Vec3.atCenterOf(pos);
432+
double distanceSq = RotationUtils.getEyesPos().distanceToSqr(hitVec);
433+
boolean lineOfSight =
434+
BlockUtils.hasLineOfSight(RotationUtils.getEyesPos(), hitVec);
435+
436+
return new BlockPlacingParams(pos, Direction.UP, hitVec, distanceSq,
437+
lineOfSight);
438+
}
439+
440+
private boolean isStuck()
441+
{
442+
if(lastProgressMs <= 0)
443+
return false;
444+
445+
return System.currentTimeMillis() - lastProgressMs > STUCK_TIMEOUT_MS;
446+
}
447+
448+
private BlockHitResult getStartHitResult()
449+
{
450+
HitResult hitResult = MC.hitResult;
451+
if(hitResult instanceof BlockHitResult blockHitResult
452+
&& hitResult.getType() == HitResult.Type.BLOCK)
453+
return blockHitResult;
454+
455+
HitResult airResult = MC.player.pick(range.getValue(), 0, false);
456+
if(airResult instanceof BlockHitResult airBlock
457+
&& airResult.getType() == HitResult.Type.MISS)
458+
return airBlock;
459+
460+
return null;
461+
}
462+
463+
private boolean isBlockPlaced(BlockPos pos, Item item)
464+
{
465+
BlockState state = BlockUtils.getState(pos);
466+
if(state.canBeReplaced())
467+
return false;
468+
469+
if(!useSavedBlocks.isChecked() || item == Items.AIR)
470+
return true;
471+
472+
if(!(item instanceof BlockItem blockItem))
473+
return true;
474+
475+
return state.is(blockItem.getBlock());
476+
}
477+
316478
private enum Status
317479
{
318480
NO_TEMPLATE,

0 commit comments

Comments
 (0)