Skip to content

Commit fc186b8

Browse files
committed
Added SilkOnly, Upgraded DamageDetect
1 parent 5ffe939 commit fc186b8

7 files changed

Lines changed: 248 additions & 5 deletions

File tree

README.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -650,7 +650,8 @@ Credits to [Trouser-Streak](https://github.com/etianl/Trouser-Streak/blob/main/s
650650

651651
### DamageDetect
652652

653-
- Navigator only hack that simply tells you who or what caused you damage and where in chat
653+
- A simple hack that tells you in chat what damaged you (or who) and where.
654+
- Great for determining strange damage from unknown effects (unexpected fall damage etc).
654655

655656
### Teleport
656657

@@ -729,6 +730,10 @@ This hack is still undergoing development and has only been tested in the end. A
729730
- Sign + title + append count
730731
- File + word-wrap
731732

733+
### SilkOnly
734+
- Allows you to setup a list of blocks that can only be broken by the player using a tool that has Silk Touch.
735+
- Perfect for avoiding accidental breakage of Ender Chests and Amethyst Clusters.
736+
732737
## What's changed or improved in this fork?
733738

734739
### ChestESP

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,7 @@ public final class HackList implements UpdateListener
226226
new WorkstationEspHack();
227227
public final RedstoneEspHack redstoneEspHack = new RedstoneEspHack();
228228
public final SkinDerpHack skinDerpHack = new SkinDerpHack();
229+
public final SilkOnlyHack silkOnlyHack = new SilkOnlyHack();
229230
public final SneakHack sneakHack = new SneakHack();
230231
public final SnowShoeHack snowShoeHack = new SnowShoeHack();
231232
public final SpeedHackHack speedHackHack = new SpeedHackHack();

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import net.minecraft.network.chat.Component;
1212
import net.minecraft.world.damagesource.DamageSource;
1313
import net.minecraft.world.entity.Entity;
14+
import net.wurstclient.Category;
1415
import net.wurstclient.SearchTags;
1516
import net.wurstclient.events.UpdateListener;
1617
import net.wurstclient.hack.Hack;
@@ -23,7 +24,7 @@ public final class DamageDetectHack extends Hack implements UpdateListener
2324
public DamageDetectHack()
2425
{
2526
super("DamageDetect");
26-
// No category -> Navigator-only
27+
setCategory(Category.OTHER);
2728
}
2829

2930
@Override
Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
/*
2+
* Copyright (c) 2014-2026 Wurst-Imperium and contributors.
3+
*
4+
* This source code is subject to the terms of the GNU General Public
5+
* License, version 3. If a copy of the GPL was not distributed with this
6+
* file, You can obtain one at: https://www.gnu.org/licenses/gpl-3.0.txt
7+
*/
8+
package net.wurstclient.hacks;
9+
10+
import java.util.Optional;
11+
12+
import net.minecraft.core.Holder.Reference;
13+
import net.minecraft.core.Registry;
14+
import net.minecraft.core.RegistryAccess;
15+
import net.minecraft.core.registries.Registries;
16+
import net.minecraft.world.item.ItemStack;
17+
import net.minecraft.world.item.enchantment.Enchantment;
18+
import net.minecraft.world.item.enchantment.EnchantmentHelper;
19+
import net.minecraft.world.item.enchantment.Enchantments;
20+
import net.minecraft.world.level.block.Block;
21+
import net.minecraft.world.level.block.state.BlockState;
22+
import net.wurstclient.Category;
23+
import net.wurstclient.SearchTags;
24+
import net.wurstclient.hack.Hack;
25+
import net.wurstclient.settings.BlockListSetting;
26+
import net.wurstclient.settings.CheckboxSetting;
27+
import net.wurstclient.util.ChatUtils;
28+
29+
@SearchTags({"silkonly", "silk only", "silk touch only"})
30+
public final class SilkOnlyHack extends Hack
31+
{
32+
private final BlockListSetting blockList = new BlockListSetting(
33+
"Block List", "Blocks that can only be broken with Silk Touch enabled.",
34+
"minecraft:ender_chest", "minecraft:bookshelf",
35+
"minecraft:amethyst_cluster",
36+
37+
// Glass (any kind)
38+
"minecraft:glass", "minecraft:tinted_glass", "minecraft:glass_pane",
39+
"minecraft:white_stained_glass", "minecraft:orange_stained_glass",
40+
"minecraft:magenta_stained_glass", "minecraft:light_blue_stained_glass",
41+
"minecraft:yellow_stained_glass", "minecraft:lime_stained_glass",
42+
"minecraft:pink_stained_glass", "minecraft:gray_stained_glass",
43+
"minecraft:light_gray_stained_glass", "minecraft:cyan_stained_glass",
44+
"minecraft:purple_stained_glass", "minecraft:blue_stained_glass",
45+
"minecraft:brown_stained_glass", "minecraft:green_stained_glass",
46+
"minecraft:red_stained_glass", "minecraft:black_stained_glass",
47+
"minecraft:white_stained_glass_pane",
48+
"minecraft:orange_stained_glass_pane",
49+
"minecraft:magenta_stained_glass_pane",
50+
"minecraft:light_blue_stained_glass_pane",
51+
"minecraft:yellow_stained_glass_pane",
52+
"minecraft:lime_stained_glass_pane",
53+
"minecraft:pink_stained_glass_pane",
54+
"minecraft:gray_stained_glass_pane",
55+
"minecraft:light_gray_stained_glass_pane",
56+
"minecraft:cyan_stained_glass_pane",
57+
"minecraft:purple_stained_glass_pane",
58+
"minecraft:blue_stained_glass_pane",
59+
"minecraft:brown_stained_glass_pane",
60+
"minecraft:green_stained_glass_pane",
61+
"minecraft:red_stained_glass_pane",
62+
"minecraft:black_stained_glass_pane",
63+
64+
// Light blocks people often want to preserve
65+
"minecraft:glowstone", "minecraft:sea_lantern",
66+
67+
// Silverfish
68+
"minecraft:infested_stone");
69+
70+
private final CheckboxSetting chatMessage = new CheckboxSetting(
71+
"Chat message",
72+
"Print a chat message when refusing to break a listed block.", true);
73+
74+
private net.minecraft.core.BlockPos lastRefusePos;
75+
private long lastRefuseMs;
76+
77+
public SilkOnlyHack()
78+
{
79+
super("SilkOnly");
80+
setCategory(Category.BLOCKS);
81+
addSetting(blockList);
82+
addSetting(chatMessage);
83+
}
84+
85+
/**
86+
* Returns true if the hack should refuse to break the given block state
87+
* with the given tool.
88+
*/
89+
public boolean shouldRefuseBreak(net.minecraft.core.BlockPos pos,
90+
BlockState state, ItemStack tool)
91+
{
92+
if(!isEnabled() || pos == null || state == null)
93+
return false;
94+
if(MC.player == null || MC.level == null)
95+
return false;
96+
if(MC.player.getAbilities().instabuild)
97+
return false;
98+
99+
Block block = state.getBlock();
100+
if(block == null || !blockList.contains(block))
101+
return false;
102+
103+
if(hasSilkTouch(tool))
104+
return false;
105+
106+
maybeMessage(pos, block);
107+
return true;
108+
}
109+
110+
private void maybeMessage(net.minecraft.core.BlockPos pos, Block block)
111+
{
112+
if(!chatMessage.isChecked())
113+
return;
114+
115+
long now = System.currentTimeMillis();
116+
if(lastRefusePos != null && lastRefusePos.equals(pos)
117+
&& now - lastRefuseMs < 1000L)
118+
return;
119+
120+
lastRefusePos = pos;
121+
lastRefuseMs = now;
122+
123+
String name = getBlockDisplayName(block);
124+
ChatUtils.message("Refusing To Break " + name + ". Use Silk Touch!");
125+
}
126+
127+
private static String getBlockDisplayName(Block block)
128+
{
129+
if(block == null)
130+
return "block";
131+
132+
try
133+
{
134+
ItemStack asItem = new ItemStack(block.asItem());
135+
if(!asItem.isEmpty())
136+
{
137+
String s = asItem.getHoverName().getString();
138+
if(s != null && !s.isBlank())
139+
return s;
140+
}
141+
}catch(Throwable ignored)
142+
{}
143+
144+
try
145+
{
146+
return net.minecraft.core.registries.BuiltInRegistries.BLOCK
147+
.getKey(block).toString();
148+
}catch(Throwable ignored)
149+
{
150+
return "block";
151+
}
152+
}
153+
154+
private static boolean hasSilkTouch(ItemStack stack)
155+
{
156+
if(stack == null || stack.isEmpty())
157+
return false;
158+
159+
if(MC.level == null)
160+
return false;
161+
162+
try
163+
{
164+
RegistryAccess access = MC.level.registryAccess();
165+
Registry<Enchantment> registry =
166+
access.lookupOrThrow(Registries.ENCHANTMENT);
167+
Optional<Reference<Enchantment>> silk =
168+
registry.get(Enchantments.SILK_TOUCH);
169+
170+
int lvl = silk.map(
171+
ref -> EnchantmentHelper.getItemEnchantmentLevel(ref, stack))
172+
.orElse(0);
173+
return lvl > 0;
174+
175+
}catch(Throwable t)
176+
{
177+
return false;
178+
}
179+
}
180+
}

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

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import net.wurstclient.events.PlayerAttacksEntityListener.PlayerAttacksEntityEvent;
4141
import net.wurstclient.events.StopUsingItemListener.StopUsingItemEvent;
4242
import net.wurstclient.hacks.AntiDropHack;
43+
import net.wurstclient.hacks.SilkOnlyHack;
4344
import net.wurstclient.mixinterface.IClientPlayerInteractionManager;
4445

4546
@Mixin(MultiPlayerGameMode.class)
@@ -52,6 +53,56 @@ public abstract class ClientPlayerInteractionManagerMixin
5253

5354
private boolean antiDropBypassingPlacement;
5455

56+
@Inject(at = @At("HEAD"),
57+
method = "startDestroyBlock(Lnet/minecraft/core/BlockPos;Lnet/minecraft/core/Direction;)Z",
58+
cancellable = true)
59+
private void wurst$silkOnly_startDestroyBlock(BlockPos pos,
60+
Direction direction, CallbackInfoReturnable<Boolean> cir)
61+
{
62+
if(pos == null || minecraft.player == null || minecraft.level == null)
63+
return;
64+
65+
if(!WurstClient.INSTANCE.isEnabled())
66+
return;
67+
68+
SilkOnlyHack silkOnly = WurstClient.INSTANCE.getHax().silkOnlyHack;
69+
if(silkOnly == null || !silkOnly.isEnabled())
70+
return;
71+
72+
var state = minecraft.level.getBlockState(pos);
73+
var tool = minecraft.player.getMainHandItem();
74+
if(silkOnly.shouldRefuseBreak(pos, state, tool))
75+
{
76+
cir.setReturnValue(false);
77+
cir.cancel();
78+
}
79+
}
80+
81+
@Inject(at = @At("HEAD"),
82+
method = "continueDestroyBlock(Lnet/minecraft/core/BlockPos;Lnet/minecraft/core/Direction;)Z",
83+
cancellable = true)
84+
private void wurst$silkOnly_continueDestroyBlock(BlockPos pos,
85+
Direction direction, CallbackInfoReturnable<Boolean> cir)
86+
{
87+
if(pos == null || minecraft.player == null || minecraft.level == null)
88+
return;
89+
90+
if(!WurstClient.INSTANCE.isEnabled())
91+
return;
92+
93+
SilkOnlyHack silkOnly = WurstClient.INSTANCE.getHax().silkOnlyHack;
94+
if(silkOnly == null || !silkOnly.isEnabled())
95+
return;
96+
97+
var state = minecraft.level.getBlockState(pos);
98+
var tool = minecraft.player.getMainHandItem();
99+
if(silkOnly.shouldRefuseBreak(pos, state, tool))
100+
{
101+
cir.setReturnValue(false);
102+
cir.cancel();
103+
}
104+
}
105+
55106
@Inject(
56107
at = @At(value = "INVOKE",
57108
target = "Lnet/minecraft/client/player/LocalPlayer;getId()I",

src/main/java/net/wurstclient/nicewurst/NiceWurstModule.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public final class NiceWurstModule
5757
private static final EnumMap<Category, Set<String>> ALLOWED_HACKS =
5858
new EnumMap<>(Category.class);
5959
private static final Set<String> ALLOWED_NAME_ONLY = Set.of("ClickGUI",
60-
"Navigator", "ChorusFruit", "MeasurementESP", "Towny", "DamageDetect");
60+
"Navigator", "ChorusFruit", "MeasurementESP", "Towny");
6161

6262
private static final Set<String> HIDDEN_OTHER_FEATURES =
6363
Set.of("Anti-Fingerprint");
@@ -85,7 +85,7 @@ public final class NiceWurstModule
8585
ALLOWED_HACKS.put(Category.BLOCKS,
8686
Set.of("AutoBuild", "AutoSign", "AutoTool", "BuildRandom",
8787
"Excavator", "InstantBunker", "ScaffoldWalk", "TemplateTool",
88-
"TargetPlace"));
88+
"TargetPlace", "SilkOnly"));
8989

9090
ALLOWED_HACKS.put(Category.MOVEMENT, Set.of("BunnyHop", "AutoSprint",
9191
"AutoWalk", "AutoSwim", "Dolphin", "SafeWalk", "Sneak", "InvWalk"));
@@ -107,7 +107,8 @@ public final class NiceWurstModule
107107
"AutoLibrarian", "AutoReconnect", "AutoTrader", "CheatDetector",
108108
"ClickGUI", "FeedAura", "Navigator", "LivestreamDetector",
109109
"PacketRate", "Panic", "PortalGUI", "SafeTP", "UI-Utils",
110-
"SeedMapperHelper", "TooManyHax", "HideModMenu"));
110+
"SeedMapperHelper", "TooManyHax", "HideModMenu",
111+
"DamageDetect"));
111112

112113
ALLOWED_HACKS.put(Category.ITEMS,
113114
Set.of("AntiDrop", "AutoDisenchant", "AutoDrop", "AutoEat",

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@
8686
"description.wurst.hack.cavefinder": "Helps you to find caves by highlighting them in the selected color.",
8787
"description.wurst.hack.chattranslator": "Translates chat messages using Google Translate.",
8888
"description.wurst.hack.cheatdetector": "Monitors nearby players and reports suspicious movement or combat patterns in chat.",
89+
"hack.wurst.damagedetect": "DamageDetect",
90+
"description.wurst.hack.damagedetect": "Shows what damaged you (including attacker and location) when you take damage.",
8991
"description.wurst.hack.chorusfruit": "Consumes a chorus fruit item when the selected trigger happens and your health is low.",
9092
"hack.wurst.livestreamdetector": "LivestreamDetector",
9193
"description.wurst.hack.livestreamdetector": "Scans the tab list for live streamers on YouTube, Twitch, TikTok, and Kick and announces streams in chat.",
@@ -249,6 +251,8 @@
249251
"description.wurst.hack.seedmapperhelper": "Builds and runs SeedMapper sm:* commands from a button-based interface whenever the SeedMapper mod is installed, including highlight, locate, sample, and source helpers.",
250252
"description.wurst.hack.signesp": "Highlights nearby signs",
251253
"description.wurst.hack.signframept": "Right-clicking item frames (with items in them) or signs forwards the interaction to the block behind them. Use the hack settings to enable Frames, Signs, or both. Hold sneak to interact with the frame or sign normally.",
254+
"hack.wurst.silkonly": "SilkOnly",
255+
"description.wurst.hack.silkonly": "Prevents you from breaking selected blocks unless your held tool has Silk Touch.",
252256
"description.wurst.hack.skinderp": "Randomly toggles parts of your skin.",
253257
"description.wurst.hack.sneak": "Makes you sneak automatically.",
254258
"description.wurst.hack.snowshoe": "Allows you to walk on powder snow.",

0 commit comments

Comments
 (0)