Skip to content

Commit 9be353a

Browse files
committed
Added hacklist improvements, logout waypoints, co-ordinates on disconnect
1 parent d5907bb commit 9be353a

File tree

10 files changed

+358
-48
lines changed

10 files changed

+358
-48
lines changed

README.md

416 Bytes

Waypoints

  • Create and save waypoints, with optional automatic death waypoints for all players.
  • Manager UI (.waypoints or apostrophe key).
  • Compass overlay: Show a bar at the top of the screen that shows the waypoint icons in your field of view
    • Shows names of waypoints you're facing
    • Shows names of waypoints when you're directly facing them
    • Adjustable position and transparency
    • Moves out of the way of boss/town bars
    • Optional display of player co-ordinates
    • Shows death position
    • Optionally shows death position
    • Optionally shows logout locations
  • Coordinates overlay: Show your direction and current XYZ position above the compass overlay
  • Preset icons
  • Preset icons; skull, arrow, heart etc.
  • Features: name, co-ordinates, dimension, icon, visibility, lines, color, copy button, opposite co-ordinates (nether), death pruning.
  • Constant-size labels and optional tracers.
  • Stored per world/server under wurst/waypoints/<worldId>.json.
  • Xaero's Minimap integration, allows exporting and importing of waypoint data.
  • Xaero's Minimap integration, allows exporting and importing of waypoint data (disconnect & reconnect to update).
  • Adjustable Tri-state Beacon Mode on waypoints (On/Off/ESP) that matches the waypoint's color.

Breadcrumbs

  • Leaves a line trail behind you (toggle-able/pause-able).
  • Trail can be infinitely long
  • Settings: color, max sections, section length, thickness.

LogoutSpots

  • Records where players log out.
  • Removes spots when they rejoin.
  • Rendering: solid box + outline, optional tracers, name labels with adjustable scale.
  • Settings: side color, line color, name scale, tracers toggle, waypoint toggle.

AutoDisenchant

  • Feeds items from your inventory (and or hotbar) that can be disenchanted into the grindstone automatically.

ClickGUI Improvements

  • Accidentally typing in ClickGUI just continues what you typed in the Navigator typing in ClickGUI just continues what you typed in the Navigator
  • Accidentally typing in ClickGUI just continues what you typed in the Navigator.
  • Favorites category, middle click a hack for it to be added to Favorites. Middle click when within Favorites to remove it.
  • Hacklist has font scaler, transparency, X & Y position adjustments

Search Improvements

  • Keyword queries supported; falls back to picker when empty.
  • List mode with visual item list.
  • Multi-term queries: comma-separated (e.g., ore, ancient).
  • Rendering: Boxes, Lines, or Both. Tracers cancel view-bobbing.
  • Fixed/rainbow line colors.
  • New minimum search to 100 results.
  • Replaced full-sort approach to bounded max-heap (PriorityQueue) that keeps the closest N matches. This avoids sorting entire result and keeps search as fast as X-Ray.
  • Safer rescans and better crash handling.

Replace Taco with Neco

  • Replaced Taco icon with dancing Neco-Arc.

Location on Disconnect

  • Copyable XYZ co-ordinates on disconnect/kick (Works with AutoLeave)

Usability

  • Right-click Area setting resets it to default.

src/main/java/net/wurstclient/clickgui/components/FeatureButton.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import net.wurstclient.hacks.TooManyHaxHack;
2121
import net.wurstclient.util.ChatUtils;
2222
import net.wurstclient.util.RenderUtils;
23+
import net.wurstclient.ui.UiScale;
2324
import org.lwjgl.glfw.GLFW;
2425

2526
public final class FeatureButton extends Component
@@ -152,7 +153,10 @@ public void render(DrawContext context, int mouseX, int mouseY,
152153
String name = feature.getName();
153154
int tx = x1 + (x3 - x1 - TR.getWidth(name)) / 2;
154155
int ty = y1 + 2;
155-
context.drawText(TR, name, tx, ty, GUI.getTxtColor(), false);
156+
double scale = UiScale.OVERRIDE_SCALE != 1.0 ? UiScale.OVERRIDE_SCALE
157+
: UiScale.getScale();
158+
RenderUtils.drawScaledText(context, TR, name, tx, ty, GUI.getTxtColor(),
159+
false, scale);
156160

157161
context.state.goDownLayer();
158162
}

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

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
package net.wurstclient.hacks;
99

1010
import java.awt.Color;
11+
import java.util.ArrayList;
1112
import java.util.HashMap;
1213
import java.util.List;
1314
import java.util.Map;
@@ -27,6 +28,8 @@
2728
import net.wurstclient.settings.ColorSetting;
2829
import net.wurstclient.settings.SliderSetting;
2930
import net.wurstclient.util.RenderUtils;
31+
import net.wurstclient.waypoints.Waypoint;
32+
import net.wurstclient.waypoints.WaypointDimension;
3033

3134
@SearchTags({"logout spots", "logouts"})
3235
public final class LogoutSpotsHack extends Hack
@@ -55,10 +58,14 @@ private static final class Entry
5558
net.wurstclient.settings.SliderSetting.ValueDisplay.DECIMAL);
5659
private final net.wurstclient.settings.CheckboxSetting showTracers =
5760
new net.wurstclient.settings.CheckboxSetting("Show tracers", true);
61+
private final net.wurstclient.settings.CheckboxSetting addAsWaypoint =
62+
new net.wurstclient.settings.CheckboxSetting(
63+
"Add logout spot as waypoint", false);
5864

5965
private final Map<UUID, Entry> spots = new HashMap<>();
6066
private List<PlayerListEntry> lastList = List.of();
6167
private Map<UUID, PlayerEntity> lastPlayers = Map.of();
68+
private final Map<UUID, java.util.UUID> spotToWaypoint = new HashMap<>();
6269

6370
public LogoutSpotsHack()
6471
{
@@ -68,6 +75,7 @@ public LogoutSpotsHack()
6875
addSetting(lineColor);
6976
addSetting(scale);
7077
addSetting(showTracers);
78+
addSetting(addAsWaypoint);
7179
}
7280

7381
@Override
@@ -77,6 +85,7 @@ protected void onEnable()
7785
snapshot();
7886
EVENTS.add(UpdateListener.class, this);
7987
EVENTS.add(RenderListener.class, this);
88+
spotToWaypoint.clear();
8089
}
8190

8291
@Override
@@ -85,6 +94,13 @@ protected void onDisable()
8594
EVENTS.remove(UpdateListener.class, this);
8695
EVENTS.remove(RenderListener.class, this);
8796
spots.clear();
97+
// remove any temporary waypoints that we created
98+
if(WURST.getHax().waypointsHack != null)
99+
{
100+
for(java.util.UUID wp : new ArrayList<>(spotToWaypoint.values()))
101+
WURST.getHax().waypointsHack.removeTemporaryWaypoint(wp);
102+
}
103+
spotToWaypoint.clear();
88104
}
89105

90106
@Override
@@ -112,6 +128,31 @@ public void onUpdate()
112128
float h = p.getHealth();
113129
spots.put(id, new Entry(id, p.getName().getString(), b,
114130
h, currentDimKey()));
131+
// Optionally add a temporary waypoint for this logout
132+
// spot
133+
if(addAsWaypoint.isChecked()
134+
&& WURST.getHax().waypointsHack != null
135+
&& WURST.getHax().waypointsHack.isEnabled())
136+
{
137+
Waypoint w =
138+
new Waypoint(java.util.UUID.randomUUID(),
139+
System.currentTimeMillis());
140+
w.setName("Logout: " + p.getName().getString());
141+
w.setIcon("skull");
142+
w.setColor(0xFF88CCFF);
143+
w.setPos(new net.minecraft.util.math.BlockPos(
144+
(int)p.getX(), (int)p.getY(), (int)p.getZ()));
145+
// set waypoint dimension based on current world
146+
w.setDimension(
147+
mapDimKeyToWaypointDim(currentDimKey()));
148+
w.setActionWhenNear(Waypoint.ActionWhenNear.DELETE);
149+
w.setActionWhenNearDistance(4);
150+
w.setLines(showTracers.isChecked());
151+
// add as temporary waypoint via WaypointsHack API
152+
java.util.UUID wpUuid = WURST.getHax().waypointsHack
153+
.addTemporaryWaypoint(w);
154+
spotToWaypoint.put(id, wpUuid);
155+
}
115156
}
116157
}
117158
snapshot();
@@ -120,7 +161,13 @@ public void onUpdate()
120161
if(MC.world != null)
121162
{
122163
for(PlayerEntity p : MC.world.getPlayers())
164+
{
123165
spots.remove(p.getUuid());
166+
// remove any temporary waypoint associated with this spot
167+
java.util.UUID wp = spotToWaypoint.remove(p.getUuid());
168+
if(wp != null && WURST.getHax().waypointsHack != null)
169+
WURST.getHax().waypointsHack.removeTemporaryWaypoint(wp);
170+
}
124171
}
125172
}
126173

@@ -198,4 +245,15 @@ private void drawWorldLabel(MatrixStack matrices, String text, double x,
198245
vcp.draw();
199246
matrices.pop();
200247
}
248+
249+
private WaypointDimension mapDimKeyToWaypointDim(String dimKey)
250+
{
251+
return switch(dimKey == null ? "overworld" : dimKey)
252+
{
253+
case "overworld" -> WaypointDimension.OVERWORLD;
254+
case "nether" -> WaypointDimension.NETHER;
255+
case "end" -> WaypointDimension.END;
256+
default -> WaypointDimension.OVERWORLD;
257+
};
258+
}
201259
}

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

Lines changed: 60 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import net.minecraft.client.font.TextRenderer;
2121
import net.minecraft.client.gui.DrawContext;
2222
import net.minecraft.client.gui.hud.BossBarHud;
23-
import net.minecraft.client.gui.hud.ClientBossBar;
2423
import net.minecraft.client.network.ServerInfo;
2524
import net.minecraft.client.render.VertexConsumerProvider;
2625
import net.minecraft.client.util.math.MatrixStack;
@@ -106,6 +105,8 @@ public final class WaypointsHack extends Hack
106105
private final CheckboxSetting showPlayerCoordsAboveCompass =
107106
new CheckboxSetting("Show player XYZ above compass", false);
108107

108+
private final Set<java.util.UUID> tempWaypoints = new HashSet<>();
109+
109110
public WaypointsHack()
110111
{
111112
super("Waypoints");
@@ -151,7 +152,7 @@ protected void onEnable()
151152
@Override
152153
protected void onDisable()
153154
{
154-
manager.save(worldId);
155+
saveExcludingTemporaries();
155156
EVENTS.remove(RenderListener.class, this);
156157
EVENTS.remove(net.wurstclient.events.UpdateListener.class, this);
157158
EVENTS.remove(DeathListener.class, this);
@@ -161,13 +162,65 @@ protected void onDisable()
161162
knownDead.clear();
162163
}
163164

165+
// Add a temporary waypoint that should not be persisted. Returns the
166+
// created waypoint UUID.
167+
public java.util.UUID addTemporaryWaypoint(Waypoint w)
168+
{
169+
manager.addOrUpdate(w);
170+
tempWaypoints.add(w.getUuid());
171+
// Do not persist permanently; but update file without temporaries
172+
saveExcludingTemporaries();
173+
return w.getUuid();
174+
}
175+
176+
public void removeTemporaryWaypoint(java.util.UUID uuid)
177+
{
178+
// remove from manager and from temp tracking
179+
// find waypoint by uuid
180+
Waypoint toRemove = null;
181+
for(Waypoint wp : new ArrayList<>(manager.all()))
182+
if(wp.getUuid().equals(uuid))
183+
{
184+
toRemove = wp;
185+
break;
186+
}
187+
if(toRemove != null)
188+
{
189+
manager.remove(toRemove);
190+
tempWaypoints.remove(uuid);
191+
saveExcludingTemporaries();
192+
}
193+
}
194+
195+
private void saveExcludingTemporaries()
196+
{
197+
if(tempWaypoints.isEmpty())
198+
{
199+
manager.save(worldId);
200+
return;
201+
}
202+
// Backup temporary waypoints
203+
ArrayList<Waypoint> backups = new ArrayList<>();
204+
for(Waypoint w : new ArrayList<>(manager.all()))
205+
if(tempWaypoints.contains(w.getUuid()))
206+
backups.add(w);
207+
// Remove temporaries from manager
208+
for(Waypoint w : backups)
209+
manager.remove(w);
210+
// Save without temporaries
211+
manager.save(worldId);
212+
// Re-add temporaries
213+
for(Waypoint w : backups)
214+
manager.addOrUpdate(w);
215+
}
216+
164217
@Override
165218
public void onUpdate()
166219
{
167220
String wid = resolveWorldId();
168221
if(!wid.equals(worldId))
169222
{
170-
manager.save(worldId);
223+
saveExcludingTemporaries();
171224
worldId = wid;
172225
manager.load(worldId);
173226
}
@@ -204,7 +257,7 @@ public void onUpdate()
204257
// Always save and prune
205258
manager.addOrUpdate(w);
206259
pruneDeaths();
207-
manager.save(worldId);
260+
saveExcludingTemporaries();
208261
// Announce in chat if enabled (guard recursion)
209262
if(chatOnDeath.isChecked())
210263
{
@@ -290,7 +343,7 @@ public void onReceivedMessage(ChatInputEvent event)
290343
// Always save and prune
291344
manager.addOrUpdate(w);
292345
pruneDeaths();
293-
manager.save(worldId);
346+
saveExcludingTemporaries();
294347
otherDeathCooldown.put(id, now);
295348

296349
// If chat is enabled, append coordinates to the incoming line
@@ -464,7 +517,7 @@ public void onDeath()
464517
w.setLines(deathWaypointLines.isChecked());
465518
manager.addOrUpdate(w);
466519
pruneDeaths();
467-
manager.save(worldId);
520+
saveExcludingTemporaries();
468521
}
469522

470523
lastDeathAt = at;
@@ -853,7 +906,7 @@ private int getBossBarBottom(DrawContext context)
853906
int maxY = screenHeight / 3;
854907
// Vanilla boss bars start at y=12 and advance by 19px per entry.
855908
int y = 12;
856-
for(ClientBossBar bar : bossBarHud.bossBars.values())
909+
for(int i = 0; i < bossBarHud.bossBars.size(); i++)
857910
{
858911
if(y >= maxY)
859912
return maxY;

0 commit comments

Comments
 (0)