Skip to content

Instantly share code, notes, and snippets.

@Zane2b2t
Forked from Doogie13/PacketFly.java
Created December 16, 2022 22:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Zane2b2t/07ff16c08e7d5c5efe822b93ad80edf9 to your computer and use it in GitHub Desktop.
Save Zane2b2t/07ff16c08e7d5c5efe822b93ad80edf9 to your computer and use it in GitHub Desktop.
A basic packetfly
package demo.knight.twelvemod.module.modules.movement;
import demo.knight.twelvemod.event.MovePlayerEvent;
import demo.knight.twelvemod.event.PacketEvent;
import demo.knight.twelvemod.mixin.mixins.ISPacketPlayerPosLook;
import demo.knight.twelvemod.module.Category;
import demo.knight.twelvemod.module.Module;
import demo.knight.twelvemod.setting.settings.FloatSetting;
import net.minecraft.network.play.client.CPacketConfirmTeleport;
import net.minecraft.network.play.client.CPacketPlayer;
import net.minecraft.network.play.server.SPacketPlayerPosLook;
import net.minecraft.util.math.Vec3d;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
/**
* @author Doogie13
* @since 26/06/2022
*/
@Module.Register(name = "PacketFly", description = "Allows you to fly with a 1.9+ packet exploit", category = Category.MOVEMENT)
public class PacketFly extends Module {
// setting for Factor with bounds 0.1 to 5.0 and a precision of 0.1
// for 2b2tpvp.net, default value of 1.3 is recommended when using this for flying
// when phasing, you may wish to use something closer to 2 or 3
final FloatSetting factor = register(new FloatSetting("Factor", 1.3f, 0.1, 5, 0.1));
// current teleport ID
int tpID = -1;
// set of packets we allow
Set<CPacketPlayer> allowedCPacketPlayers = new HashSet<>();
// map of IDs and positions where we can ignore server rubberbands
HashMap<Integer, Vec3d> allowedPositionsAndIDs = new HashMap<>();
@Override
public void onDisable() {
// clear these so they don't take up memory
allowedCPacketPlayers.clear();
allowedPositionsAndIDs.clear();
}
@Override
public void onEnable() {
// we will not have been tracking tpID so we must reset it
tpID = -1;
}
// this can be any event which will let us set player motion
@SubscribeEvent
public void onMotion(MovePlayerEvent event) {
// first we must get motion
double motionX, motionY = 0, motionZ;
// store whether we are anti-kicking
boolean antiKicking = false;
// Handle motion Y
// check if we need to do anti-kick
// we do not need to anti-kick when inside blocks
if (mc.player.ticksExisted % 10 == 0 && !mc.world.collidesWithAnyBlock(mc.player.getEntityBoundingBox())) {
// 0.04 is the distance we must fall before being kicked for flying
// net.minecraft.network.NetHandlerPlayServer line 182
motionY = -.04;
antiKicking = true;
} else {
// we MUST allow the player to prioritise going up as it allows us to manipulate our bounding box with sneaking
// NCP will flag SurvivalFly for anything larger than 0.0625 so we use 0.0624 to be on the safe side
// I believe this to be because the server doesn't process movement slower than 0.0625 in the same way but I can't find evidence for this
if (mc.gameSettings.keyBindJump.isKeyDown())
motionY = .0624;
else if (mc.gameSettings.keyBindSneak.isKeyDown())
motionY = -.0624;
}
// Handle Motion X, Z
// we will handle them as one speed and split them into X and Z based on rotation and keys pressed
double motionH;
// If we are inside blocks, we must use speed slower than 0.0625 so vanilla doesn't set us back
// net.minecraft.network.NetHandlerPlayServer line 560
boolean walls = mc.world.collidesWithAnyBlock(mc.player.getEntityBoundingBox());
if (walls) {
motionH = .0624;
if (motionY != 0) {
// this means the hypotenuse of our position is always under .625;
double multiply = 1 / Math.sqrt(2);
motionY *= multiply;
motionH *= multiply;
}
} else {
// base air move speed
motionH = .2873;
// we cannot move up if we are moving horizontally since NCP will notice
boolean movingHorizontally = mc.player.moveForward != 0 || mc.player.moveStrafing != 0;
if (movingHorizontally)
motionY = Math.min(0, motionY);
}
// we now split motionH into motionX and motionZ
// this should really be in a util
// we use dir because tradition
double[] dir = new double[]{0,0};
// if we aren't moving we can just use 0 motion
if (!(mc.player.moveForward == 0 && mc.player.moveStrafing == 0)) {
int strafing = 0;
int forward = 0;
// make moveForward and moveStrafing rounded to the nearest 1
if (mc.player.moveStrafing < 0)
strafing = -1;
else if (mc.player.moveStrafing > 0)
strafing = 1;
if (mc.player.moveForward < 0)
forward = -1;
else if (mc.player.moveForward > 0)
forward = 1;
float strafe = 90 * strafing;
strafe *= (forward != 0F) ? forward * 0.5F : 1;
float yaw = mc.player.rotationYaw - strafe;
yaw -= (mc.player.moveForward < 0F) ? 180 : 0;
// to radians
yaw *= 1 / (180 / Math.PI);
// get X and Z split
double x = (-Math.sin(yaw) * motionH);
double z = (Math.cos(yaw) * motionH);
dir = new double[]{x, z};
}
motionX = dir[0];
motionZ = dir[1];
// get the lowest possible factor
int factorInt = (int) Math.floor(factor.getValue());
// check if we should send more packets
// decimal place is how much we should factorise more
if (mc.player.ticksExisted % 10 < 10 * (factor.getValue() - factorInt))
factorInt++;
// send packets
Vec3d motion = send(motionX, motionY, motionZ, antiKicking, factorInt);
event.setX(motion.x);
event.setY(motion.y);
event.setZ(motion.z);
// allows us to phase
mc.player.noClip = true;
}
// this can be repeated multiple times to move faster
Vec3d send(double motionX, double motionY, double motionZ, boolean antiKick, int factor) {
for (int i = 1; i < factor + 1; i++) {
// only anti-kick once per loop as doing it multiple times is a waste of height
if (antiKick && factor != 1)
motionY = 0;
// get the absolute position
Vec3d pos = mc.player.getPositionVector().add(motionX * i, motionY * i, motionZ * i);
// create a movement packet
// we use onGround true to prevent fall damage on some servers
CPacketPlayer.Position packet = new CPacketPlayer.Position(pos.x, pos.y, pos.z, true);
// create a "bounds" packet
// this is just any packet over 100 blocks away from current position or 300 when elytra is open
// net.minecraft.network.NetHandlerPlayServer line 529
CPacketPlayer.Position bounds = new CPacketPlayer.Position(pos.x, pos.y + 512, pos.z, true);
// allow normal packet and "bounds" packet to be sent (handled later)
allowedCPacketPlayers.add(packet);
allowedCPacketPlayers.add(bounds);
// send packets
mc.player.connection.sendPacket(packet);
mc.player.connection.sendPacket(bounds);
// we must have a correct teleport ID to save, we use the "bounds" packet to get one anyways if not
if (tpID < 0)
break;
// iterate tpID as bounds will have caused rubberband
tpID++;
// send a tpID packet confirming the bounds packet
mc.player.connection.sendPacket(new CPacketConfirmTeleport(tpID));
// add move vector and tpID to the map
allowedPositionsAndIDs.put(tpID, pos);
}
// return a vec of our motion
return new Vec3d(motionX * factor, motionY * (antiKick ? 1 : factor), motionZ * factor);
}
@SubscribeEvent
public void onPacketSend(PacketEvent.Send event) {
// we only cancel CPacketPlayers
if (event.getPacket() instanceof CPacketPlayer)
// check if we are allowing the packet through
// cancel if not
if (!allowedCPacketPlayers.contains((CPacketPlayer) event.getPacket()))
event.setCanceled(true);
}
@SubscribeEvent
public void onPacketReceive(PacketEvent.Receive event) {
// check if the packet is a player pos look
if (event.getPacket() instanceof SPacketPlayerPosLook) {
SPacketPlayerPosLook packet = (SPacketPlayerPosLook) event.getPacket();
int id = packet.getTeleportId();
// check if saved history contains the packet ID
if (allowedPositionsAndIDs.containsKey(id)) {
// check if saved packet with that ID has the corresponding position
// this would mean the packet lines up and we can ignore the packet
if (allowedPositionsAndIDs.get(id).equals(new Vec3d(packet.getX(), packet.getY(), packet.getZ()))) {
// remove the entry
allowedPositionsAndIDs.remove(id);
// confirm the packet
mc.player.connection.sendPacket(new CPacketConfirmTeleport(id));
// cancel the event
event.setCanceled(true);
return;
}
}
// update our teleport ID
tpID = id;
// prevent jittery rotation
((ISPacketPlayerPosLook) packet).setYaw(mc.player.rotationYaw);
((ISPacketPlayerPosLook) packet).setPitch(mc.player.rotationPitch);
// we MUST confirm this packet
mc.player.connection.sendPacket(new CPacketConfirmTeleport(id));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment