Skip to content

Commit e10f464

Browse files
committed
ClientChatOverlay Updates, TAB List Options, Improved Hack Toggles, PlayerESP Coloring Change, Player Muting & More
1 parent 0127442 commit e10f464

38 files changed

Lines changed: 1684 additions & 45 deletions
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
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.clickgui.components;
9+
10+
import java.util.Objects;
11+
12+
import net.wurstclient.clickgui.screens.EditPlayerMuteScreen;
13+
import net.wurstclient.settings.PlayerMuteListSetting;
14+
import net.wurstclient.settings.Setting;
15+
16+
public final class PlayerMuteListEditButton extends AbstractListEditButton
17+
{
18+
private final PlayerMuteListSetting setting;
19+
20+
public PlayerMuteListEditButton(PlayerMuteListSetting setting)
21+
{
22+
this.setting = Objects.requireNonNull(setting);
23+
setWidth(getDefaultWidth());
24+
setHeight(getDefaultHeight());
25+
}
26+
27+
@Override
28+
protected void openScreen()
29+
{
30+
MC.gui.setScreen(new EditPlayerMuteScreen(MC.gui.screen(), setting));
31+
}
32+
33+
@Override
34+
protected String getText()
35+
{
36+
return setting.getName() + ": "
37+
+ setting.getHack().getMutedNames().size();
38+
}
39+
40+
@Override
41+
protected Setting getSetting()
42+
{
43+
return setting;
44+
}
45+
}
Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
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.clickgui.screens;
9+
10+
import java.util.List;
11+
import java.util.LinkedHashSet;
12+
import java.util.Objects;
13+
import java.util.Set;
14+
15+
import org.lwjgl.glfw.GLFW;
16+
17+
import net.minecraft.client.Minecraft;
18+
import net.minecraft.client.gui.GuiGraphicsExtractor;
19+
import net.minecraft.client.gui.components.Button;
20+
import net.minecraft.client.gui.components.Renderable;
21+
import net.minecraft.client.gui.screens.Screen;
22+
import net.minecraft.client.input.KeyEvent;
23+
import net.minecraft.network.chat.Component;
24+
import net.minecraft.util.CommonColors;
25+
import net.minecraft.client.multiplayer.PlayerInfo;
26+
import net.wurstclient.clickgui.widgets.MultiSelectEntryListWidget;
27+
import net.wurstclient.settings.PlayerMuteListSetting;
28+
29+
public final class EditPlayerMuteScreen extends Screen
30+
{
31+
private final Screen previous;
32+
private final PlayerMuteListSetting setting;
33+
private final Set<String> pendingMutedIds = new LinkedHashSet<>();
34+
private PlayerList playerList;
35+
private Button toggleButton;
36+
37+
public EditPlayerMuteScreen(Screen previous, PlayerMuteListSetting setting)
38+
{
39+
super(Component.literal(""));
40+
this.previous = previous;
41+
this.setting = setting;
42+
}
43+
44+
@Override
45+
public void init()
46+
{
47+
List<PlayerInfo> players = setting.getHack().getOnlinePlayers();
48+
pendingMutedIds.clear();
49+
setting.getHack().getMutedOnlineIds()
50+
.forEach(id -> pendingMutedIds.add(id.toString()));
51+
playerList = new PlayerList(minecraft, this, players);
52+
addWidget(playerList);
53+
playerList.setSelectionListener(() -> {
54+
if(toggleButton != null)
55+
toggleButton.setMessage(Component.literal(toggleButtonText()));
56+
});
57+
if(!players.isEmpty())
58+
playerList.setSelection(
59+
List.of(players.get(0).getProfile().id().toString()), 0);
60+
61+
int x = width / 2 - 155;
62+
addRenderableWidget(toggleButton = Button
63+
.builder(Component.literal(toggleButtonText()),
64+
button -> toggleSelected())
65+
.bounds(x, height - 28, 100, 20).build());
66+
addRenderableWidget(
67+
Button.builder(Component.literal("Apply"), button -> apply())
68+
.bounds(x + 105, height - 28, 65, 20).build());
69+
addRenderableWidget(
70+
Button.builder(Component.literal("Done"), button -> {
71+
apply();
72+
minecraft.gui.setScreen(previous);
73+
}).bounds(x + 175, height - 28, 65, 20).build());
74+
addRenderableWidget(Button
75+
.builder(Component.literal("Cancel"),
76+
button -> minecraft.gui.setScreen(previous))
77+
.bounds(x + 245, height - 28, 65, 20).build());
78+
}
79+
80+
private void apply()
81+
{
82+
setting.getHack()
83+
.applyOnlineMuteSelection(List.copyOf(pendingMutedIds));
84+
}
85+
86+
private void toggleSelected()
87+
{
88+
Entry selected = playerList.getSelected();
89+
if(selected == null)
90+
return;
91+
92+
String id = selected.selectionKey();
93+
if(!pendingMutedIds.add(id))
94+
pendingMutedIds.remove(id);
95+
toggleButton.setMessage(Component.literal(toggleButtonText()));
96+
}
97+
98+
private String toggleButtonText()
99+
{
100+
Entry selected = playerList == null ? null : playerList.getSelected();
101+
return selected != null
102+
&& pendingMutedIds.contains(selected.selectionKey())
103+
? "Unmute player" : "Mute player";
104+
}
105+
106+
@Override
107+
public void extractRenderState(GuiGraphicsExtractor context, int mouseX,
108+
int mouseY, float partialTicks)
109+
{
110+
playerList.extractRenderState(context, mouseX, mouseY, partialTicks);
111+
context.centeredText(minecraft.font,
112+
"Select a player, then Mute/Unmute and Apply", width / 2, 12,
113+
CommonColors.WHITE);
114+
for(Renderable drawable : renderables)
115+
drawable.extractRenderState(context, mouseX, mouseY, partialTicks);
116+
}
117+
118+
@Override
119+
public boolean keyPressed(KeyEvent context)
120+
{
121+
if(context.key() == GLFW.GLFW_KEY_ESCAPE)
122+
{
123+
minecraft.gui.setScreen(previous);
124+
return true;
125+
}
126+
return super.keyPressed(context);
127+
}
128+
129+
private final class Entry
130+
extends MultiSelectEntryListWidget.Entry<EditPlayerMuteScreen.Entry>
131+
{
132+
private final PlayerInfo info;
133+
134+
private Entry(PlayerList parent, PlayerInfo info)
135+
{
136+
super(parent);
137+
this.info = Objects.requireNonNull(info);
138+
}
139+
140+
@Override
141+
public Component getNarration()
142+
{
143+
return Component.translatable("narrator.select",
144+
info.getProfile().name());
145+
}
146+
147+
@Override
148+
public void extractContent(GuiGraphicsExtractor context, int mouseX,
149+
int mouseY, boolean hovered, float tickDelta)
150+
{
151+
int x = getContentX();
152+
int y = getContentY();
153+
boolean muted = playerList.isMuted(this);
154+
context.text(minecraft.font, muted ? "[x]" : "[ ]", x + 4, y + 4,
155+
muted ? CommonColors.GREEN : CommonColors.LIGHT_GRAY, false);
156+
context.text(minecraft.font, info.getProfile().name(), x + 28,
157+
y + 4, CommonColors.WHITE, false);
158+
context.text(minecraft.font, muted ? "Muted" : "Not muted", x + 28,
159+
y + 16, CommonColors.LIGHT_GRAY, false);
160+
}
161+
162+
@Override
163+
public String selectionKey()
164+
{
165+
return info.getProfile().id().toString();
166+
}
167+
}
168+
169+
private final class PlayerList
170+
extends MultiSelectEntryListWidget<EditPlayerMuteScreen.Entry>
171+
{
172+
private PlayerList(Minecraft minecraft, EditPlayerMuteScreen screen,
173+
List<PlayerInfo> players)
174+
{
175+
super(minecraft, screen.width, screen.height - 72, 30, 28);
176+
for(PlayerInfo info : players)
177+
addEntry(EditPlayerMuteScreen.this.new Entry(this, info));
178+
}
179+
180+
private boolean isMuted(Entry entry)
181+
{
182+
return pendingMutedIds.contains(entry.selectionKey());
183+
}
184+
185+
@Override
186+
protected String getSelectionKey(EditPlayerMuteScreen.Entry entry)
187+
{
188+
return entry.selectionKey();
189+
}
190+
}
191+
}

src/main/java/net/wurstclient/command/CmdList.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ public final class CmdList
3939
public final FeaturesCmd featuresCmd = new FeaturesCmd();
4040
public final FollowCmd followCmd = new FollowCmd();
4141
public final FriendsCmd friendsCmd = new FriendsCmd();
42+
public final PlayerMuteCmd playerMuteCmd = new PlayerMuteCmd();
4243
public final GetPosCmd getPosCmd = new GetPosCmd();
4344
public final GiveCmd giveCmd = new GiveCmd();
4445
public final GmCmd gmCmd = new GmCmd();
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
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.commands;
9+
10+
import net.wurstclient.Category;
11+
import net.wurstclient.command.CmdException;
12+
import net.wurstclient.command.CmdSyntaxError;
13+
import net.wurstclient.command.Command;
14+
import net.wurstclient.hacks.PlayerMuteHack;
15+
import net.wurstclient.util.ChatUtils;
16+
17+
public final class PlayerMuteCmd extends Command
18+
{
19+
public PlayerMuteCmd()
20+
{
21+
super("mute", "Mutes or unmutes a player's chat messages.",
22+
".mute <player>", ".mute unmute <player>", ".mute list");
23+
setCategory(Category.CHAT);
24+
}
25+
26+
@Override
27+
public void call(String[] args) throws CmdException
28+
{
29+
if(args.length < 1 || args.length > 2)
30+
throw new CmdSyntaxError();
31+
32+
PlayerMuteHack hack = WURST.getHax().playerMuteHack;
33+
if(!hack.isEnabled())
34+
hack.setEnabled(true);
35+
36+
if(args[0].equalsIgnoreCase("list"))
37+
{
38+
if(args.length != 1)
39+
throw new CmdSyntaxError();
40+
ChatUtils.message(
41+
"Muted players: " + String.join(", ", hack.getMutedNames()));
42+
return;
43+
}
44+
45+
boolean unmute = args[0].equalsIgnoreCase("unmute");
46+
String name = unmute ? args.length == 2 ? args[1] : null : args[0];
47+
if(name == null)
48+
throw new CmdSyntaxError();
49+
50+
var info = hack.findOnlinePlayer(name);
51+
if(info == null)
52+
{
53+
if(unmute)
54+
{
55+
hack.unmuteName(name);
56+
ChatUtils.message("Unmuted " + name + ".");
57+
}else
58+
{
59+
hack.muteName(name);
60+
ChatUtils.message("Muted " + name + ".");
61+
}
62+
return;
63+
}
64+
65+
if(unmute)
66+
{
67+
hack.unmute(info);
68+
ChatUtils.message("Unmuted " + info.getProfile().name() + ".");
69+
}else
70+
ChatUtils.message(hack.toggle(info));
71+
}
72+
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ public final class HackList implements UpdateListener
5757
public final AutoBuildHack autoBuildHack = new AutoBuildHack();
5858
public final AutoChatHack autoChatHack = new AutoChatHack();
5959
public final ChatSpamHack chatSpamHack = new ChatSpamHack();
60+
public final PlayerMuteHack playerMuteHack = new PlayerMuteHack();
6061
public final CommandSpamHack commandSpamHack = new CommandSpamHack();
6162
public final CommandScannerHack commandScannerHack =
6263
new CommandScannerHack();

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ protected void onEnable()
156156
WURST.getHax().clickAuraHack.setEnabled(false);
157157
WURST.getHax().crystalAuraHack.setEnabled(false);
158158
WURST.getHax().fightBotHack.setEnabled(false);
159-
WURST.getHax().killauraHack.setEnabled(false);
159+
WURST.getHax().killauraHack.disableByConflict(this);
160160
WURST.getHax().killauraLegitHack.setEnabled(false);
161161
WURST.getHax().multiAuraHack.setEnabled(false);
162162
WURST.getHax().protectHack.setEnabled(false);
@@ -170,6 +170,7 @@ protected void onEnable()
170170
@Override
171171
protected void onDisable()
172172
{
173+
WURST.getHax().killauraHack.releaseConflict(this);
173174
EVENTS.remove(UpdateListener.class, this);
174175
EVENTS.remove(MouseUpdateListener.class, this);
175176
target = null;

0 commit comments

Comments
 (0)