Skip to content

Commit a0a5b3b

Browse files
committed
Updated SpearAssist ESP
1 parent a9b4349 commit a0a5b3b

File tree

3 files changed

+140
-46
lines changed

3 files changed

+140
-46
lines changed

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

Lines changed: 40 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -121,53 +121,50 @@ public void onUpdate()
121121
if(MC.getConnection() == null || MC.level == null)
122122
return;
123123
var nowList = MC.getConnection().getOnlinePlayers();
124-
if(nowList.size() != lastList.size())
125-
{
126-
// find missing
127-
var lastMap = new HashMap<UUID, PlayerInfo>();
128-
for(var e : lastList)
129-
lastMap.put(e.getProfile().id(), e);
130-
var nowMap = new HashMap<UUID, PlayerInfo>();
131-
for(var e : nowList)
132-
nowMap.put(e.getProfile().id(), e);
133-
for(var id : lastMap.keySet())
134-
if(!nowMap.containsKey(id))
124+
// Compare previous and current tab lists so we still catch logouts
125+
// when someone else joins during the same tick.
126+
var lastMap = new HashMap<UUID, PlayerInfo>();
127+
for(var e : lastList)
128+
lastMap.put(e.getProfile().id(), e);
129+
var nowMap = new HashMap<UUID, PlayerInfo>();
130+
for(var e : nowList)
131+
nowMap.put(e.getProfile().id(), e);
132+
133+
for(var id : lastMap.keySet())
134+
if(!nowMap.containsKey(id))
135+
{
136+
Player p = lastPlayers.get(id);
137+
if(p != null)
135138
{
136-
Player p = lastPlayers.get(id);
137-
if(p != null)
139+
AABB b = p.getBoundingBox();
140+
long now = System.currentTimeMillis();
141+
spots.put(id, new Entry(p.getName().getString(), b,
142+
currentDimKey(), now));
143+
// Optionally add a temporary waypoint for this logout spot
144+
if(addAsWaypoint.isChecked()
145+
&& WURST.getHax().waypointsHack != null)
138146
{
139-
AABB b = p.getBoundingBox();
140-
long now = System.currentTimeMillis();
141-
spots.put(id, new Entry(p.getName().getString(), b,
142-
currentDimKey(), now));
143-
// Optionally add a temporary waypoint for this logout
144-
// spot
145-
if(addAsWaypoint.isChecked()
146-
&& WURST.getHax().waypointsHack != null
147-
&& WURST.getHax().waypointsHack.isEnabled())
148-
{
149-
Waypoint w =
150-
new Waypoint(java.util.UUID.randomUUID(), now);
151-
w.setName("Logout: " + p.getName().getString());
152-
w.setIcon("skull");
153-
w.setColor(0xFF88CCFF);
154-
w.setPos(new net.minecraft.core.BlockPos(
155-
(int)p.getX(), (int)p.getY(), (int)p.getZ()));
156-
// set waypoint dimension based on current world
157-
w.setDimension(
158-
mapDimKeyToWaypointDim(currentDimKey()));
159-
w.setActionWhenNear(Waypoint.ActionWhenNear.DELETE);
160-
w.setActionWhenNearDistance(4);
161-
w.setLines(showTracers.isChecked());
162-
// add as temporary waypoint via WaypointsHack API
163-
java.util.UUID wpUuid = WURST.getHax().waypointsHack
164-
.addTemporaryWaypoint(w);
165-
spotToWaypoint.put(id, wpUuid);
166-
}
147+
Waypoint w =
148+
new Waypoint(java.util.UUID.randomUUID(), now);
149+
w.setName("Logout: " + p.getName().getString());
150+
w.setIcon("skull");
151+
w.setColor(0xFF88CCFF);
152+
w.setPos(new net.minecraft.core.BlockPos((int)p.getX(),
153+
(int)p.getY(), (int)p.getZ()));
154+
// set waypoint dimension based on current world
155+
w.setDimension(mapDimKeyToWaypointDim(currentDimKey()));
156+
w.setActionWhenNear(Waypoint.ActionWhenNear.DELETE);
157+
w.setActionWhenNearDistance(4);
158+
w.setLines(showTracers.isChecked());
159+
// add as temporary waypoint via WaypointsHack API
160+
java.util.UUID wpUuid = WURST.getHax().waypointsHack
161+
.addTemporaryWaypoint(w);
162+
spotToWaypoint.put(id, wpUuid);
167163
}
168164
}
169-
snapshot();
170-
}
165+
}
166+
167+
snapshot();
171168
// cull rejoined players
172169
if(MC.level != null)
173170
{

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

Lines changed: 92 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,24 @@
99

1010
import java.util.Comparator;
1111
import java.util.stream.Stream;
12+
import net.minecraft.network.protocol.game.ServerboundMovePlayerPacket.PosRot;
1213
import net.minecraft.world.InteractionHand;
1314
import net.minecraft.world.entity.Entity;
1415
import net.minecraft.world.phys.EntityHitResult;
16+
import net.minecraft.world.phys.Vec3;
1517
import net.wurstclient.Category;
1618
import net.wurstclient.SearchTags;
1719
import net.wurstclient.events.UpdateListener;
1820
import net.wurstclient.hack.Hack;
1921
import net.wurstclient.settings.AttackSpeedSliderSetting;
22+
import net.wurstclient.settings.CheckboxSetting;
2023
import net.wurstclient.settings.SliderSetting;
2124
import net.wurstclient.settings.SliderSetting.ValueDisplay;
2225
import net.wurstclient.settings.SwingHandSetting;
2326
import net.wurstclient.settings.SwingHandSetting.SwingHand;
2427
import net.wurstclient.settings.filterlists.EntityFilterList;
2528
import net.wurstclient.util.EntityUtils;
29+
import net.wurstclient.util.Rotation;
2630
import net.wurstclient.util.RotationUtils;
2731

2832
@SearchTags({"outreach", "wall hit", "wall attack"})
@@ -42,6 +46,10 @@ public final class OutreachHack extends Hack implements UpdateListener
4246
private final SwingHandSetting swingHand =
4347
new SwingHandSetting(this, SwingHand.CLIENT);
4448

49+
private final CheckboxSetting spoofBehind =
50+
new CheckboxSetting("Spoof from behind",
51+
"Pretends to attack from the opposite side of your target.", false);
52+
4553
private final EntityFilterList entityFilters =
4654
EntityFilterList.genericCombat();
4755

@@ -55,6 +63,7 @@ public OutreachHack()
5563
addSetting(range);
5664
addSetting(fov);
5765
addSetting(swingHand);
66+
addSetting(spoofBehind);
5867
entityFilters.forEach(this::addSetting);
5968
}
6069

@@ -119,9 +128,89 @@ public void onUpdate()
119128
return;
120129

121130
WURST.getHax().autoSwordHack.setSlot(target);
122-
MC.gameMode.attack(MC.player, target);
123-
swingHand.swing(InteractionHand.MAIN_HAND);
124-
swingSpeed.resetTimer();
131+
boolean attacked = false;
132+
if(spoofBehind.isChecked())
133+
attacked = attackWithBehindSpoof(target);
134+
135+
if(!attacked)
136+
attacked = attackNormally(target);
137+
138+
if(attacked)
139+
swingSpeed.resetTimer();
125140
}
126141
}
142+
143+
private boolean attackNormally(Entity target)
144+
{
145+
MC.gameMode.attack(MC.player, target);
146+
swingHand.swing(InteractionHand.MAIN_HAND);
147+
return true;
148+
}
149+
150+
private boolean attackWithBehindSpoof(Entity target)
151+
{
152+
if(MC.player == null || MC.player.connection == null)
153+
return false;
154+
155+
Vec3 spoofPos = calculateSpoofPosition(target);
156+
if(spoofPos == null)
157+
return false;
158+
159+
Vec3 spoofEyes =
160+
spoofPos.add(0, MC.player.getEyeHeight(MC.player.getPose()), 0);
161+
Vec3 targetCenter = target.getBoundingBox().getCenter();
162+
Rotation spoofRot = rotationFrom(spoofEyes, targetCenter);
163+
164+
Vec3 originalPos = MC.player.position();
165+
Rotation originalRot =
166+
new Rotation(MC.player.getYRot(), MC.player.getXRot());
167+
168+
sendSpoofedPosRot(spoofPos, spoofRot);
169+
MC.gameMode.attack(MC.player, target);
170+
swingHand.swing(InteractionHand.MAIN_HAND);
171+
sendSpoofedPosRot(originalPos, originalRot);
172+
return true;
173+
}
174+
175+
private Vec3 calculateSpoofPosition(Entity target)
176+
{
177+
if(MC.player == null)
178+
return null;
179+
180+
Vec3 center = target.getBoundingBox().getCenter();
181+
Vec3 eyes = RotationUtils.getEyesPos();
182+
Vec3 direction = center.subtract(eyes);
183+
double lenSq = direction.lengthSqr();
184+
if(lenSq < 1.0e-6)
185+
return null;
186+
187+
Vec3 normalized = direction.normalize();
188+
double extra = Math.max(0.75, target.getBbWidth() + 0.75);
189+
Vec3 behind = center.add(normalized.scale(extra));
190+
return new Vec3(behind.x, MC.player.getY(), behind.z);
191+
}
192+
193+
private Rotation rotationFrom(Vec3 start, Vec3 end)
194+
{
195+
double diffX = end.x - start.x;
196+
double diffZ = end.z - start.z;
197+
double yaw = Math.toDegrees(Math.atan2(diffZ, diffX)) - 90F;
198+
199+
double diffY = end.y - start.y;
200+
double diffXZ = Math.sqrt(diffX * diffX + diffZ * diffZ);
201+
double pitch = -Math.toDegrees(Math.atan2(diffY, diffXZ));
202+
203+
return Rotation.wrapped((float)yaw, (float)pitch);
204+
}
205+
206+
private void sendSpoofedPosRot(Vec3 pos, Rotation rotation)
207+
{
208+
if(MC.player == null || MC.player.connection == null)
209+
return;
210+
211+
boolean onGround = MC.player.onGround();
212+
boolean collision = MC.player.horizontalCollision;
213+
MC.player.connection.send(new PosRot(pos.x, pos.y, pos.z,
214+
rotation.yaw(), rotation.pitch(), onGround, collision));
215+
}
127216
}

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,14 @@ public Integer getGlowColor(LivingEntity entity)
523523
if(!players.contains(player))
524524
return null;
525525

526+
var spearAssist = WURST.getHax().spearAssistHack;
527+
if(spearAssist != null && spearAssist.isEnabled())
528+
{
529+
Integer spearColor = spearAssist.getGlowColor(player);
530+
if(spearColor != null)
531+
return spearColor;
532+
}
533+
526534
return makeOpaque(getBaseColor(player));
527535
}
528536

0 commit comments

Comments
 (0)