Last active
July 30, 2023 07:01
-
-
Save Doogie13/aa04c6a8eb496c1afdb9c675e2ebd91c to your computer and use it in GitHub Desktop.
A basic packetfly
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
found this on internet :D