package com.sijobe.spc.overwrite; import com.sijobe.spc.command.Noclip; import com.sijobe.spc.util.ForgeHelper; import com.sijobe.spc.util.Mappings; import com.sijobe.spc.util.ReflectionHelper; import java.lang.reflect.Field; import java.util.HashMap; import net.minecraft.server.MinecraftServer; import net.minecraft.src.AxisAlignedBB; import net.minecraft.src.EntityPlayerMP; import net.minecraft.src.INetworkManager; import net.minecraft.src.NetServerHandler; import net.minecraft.src.Packet10Flying; import net.minecraft.src.WorldServer; /** * Custom server handler to allow noclip * Note: use of reflection is neccessary, * otherwise player cannot interact with world * * @author q3hardcore * @version 1.4 */ public final class ONetServerHandler extends NetServerHandler { private final NetServerHandler oldInstance; private final MinecraftServer mcServer; private int ticksForFloatKick; private double lastPosX; private double lastPosY; private double lastPosZ; private boolean hasMoved = true; private static final HashMap<String, String[]> fieldMappings; // mappings valid as of: Minecraft 1.5.2 (no changes) static { fieldMappings = new Mappings(); fieldMappings.put("lastPosX", new String[]{"n", "field_72579_o"}); fieldMappings.put("lastPosY", new String[]{"o", "field_72589_p"}); fieldMappings.put("lastPosZ", new String[]{"p", "field_72588_q"}); fieldMappings.put("hasMoved", new String[]{"q", "field_72587_r"}); } public ONetServerHandler(MinecraftServer par1, INetworkManager par2, EntityPlayerMP par3, NetServerHandler instance) { super(par1, par2, par3); if(instance instanceof ONetServerHandler) { throw new RuntimeException("SPC: Critical error encountered!"); } oldInstance = instance; mcServer = par1; connectionClosed = oldInstance.connectionClosed; } public NetServerHandler getOldInstance() { return oldInstance; } private void updateHasMoved() { Field field = ReflectionHelper.getField(oldInstance, fieldMappings.get("hasMoved")); this.hasMoved = ReflectionHelper.getBoolean(field, oldInstance); } private void updatePosition() { Field field; field = ReflectionHelper.getField(oldInstance, fieldMappings.get("lastPosX")); this.lastPosX = ReflectionHelper.getDouble(field, oldInstance); field = ReflectionHelper.getField(oldInstance, fieldMappings.get("lastPosY")); this.lastPosY = ReflectionHelper.getDouble(field, oldInstance); field = ReflectionHelper.getField(oldInstance, fieldMappings.get("lastPosZ")); this.lastPosZ = ReflectionHelper.getDouble(field, oldInstance); } private void setHasMoved(boolean bool) { Field field = ReflectionHelper.getField(oldInstance, fieldMappings.get("hasMoved")); ReflectionHelper.setField(field, oldInstance, bool); } private void setPosition(double x, double y, double z) { Field field; field = ReflectionHelper.getField(oldInstance, fieldMappings.get("lastPosX")); ReflectionHelper.setField(field, oldInstance, x); field = ReflectionHelper.getField(oldInstance, fieldMappings.get("lastPosY")); ReflectionHelper.setField(field, oldInstance, y); field = ReflectionHelper.getField(oldInstance, fieldMappings.get("lastPosZ")); ReflectionHelper.setField(field, oldInstance, z); } @Override public void handleFlying(Packet10Flying par1Packet10Flying) { // we use Forge's handleFlying method if(!ForgeHelper.HAS_FORGE) { updateHasMoved(); updatePosition(); } Noclip.checkSafe(this.playerEntity); // Forge has Noclip support if(ForgeHelper.HAS_FORGE) { super.handleFlying(par1Packet10Flying); return; } WorldServer var2 = this.mcServer.worldServerForDimension(oldInstance.playerEntity.dimension); if (!oldInstance.playerEntity.playerConqueredTheEnd) { double var3; if (!hasMoved) { var3 = par1Packet10Flying.yPosition - lastPosY; if (par1Packet10Flying.xPosition == lastPosX && var3 * var3 < 0.01D && par1Packet10Flying.zPosition == lastPosZ) { setHasMoved(true); hasMoved = true; } } if (hasMoved) { double var5; double var7; double var9; double var13; if (oldInstance.playerEntity.ridingEntity != null) { float var34 = oldInstance.playerEntity.rotationYaw; float var4 = oldInstance.playerEntity.rotationPitch; oldInstance.playerEntity.ridingEntity.updateRiderPosition(); var5 = oldInstance.playerEntity.posX; var7 = oldInstance.playerEntity.posY; var9 = oldInstance.playerEntity.posZ; double var35 = 0.0D; var13 = 0.0D; if (par1Packet10Flying.rotating) { var34 = par1Packet10Flying.yaw; var4 = par1Packet10Flying.pitch; } if (par1Packet10Flying.moving && par1Packet10Flying.yPosition == -999.0D && par1Packet10Flying.stance == -999.0D) { if (Math.abs(par1Packet10Flying.xPosition) > 1.0D || Math.abs(par1Packet10Flying.zPosition) > 1.0D) { System.err.println(oldInstance.playerEntity.getUsername() + " was caught trying to crash the server with an invalid position."); this.kickPlayerFromServer("Nope!"); return; } var35 = par1Packet10Flying.xPosition; var13 = par1Packet10Flying.zPosition; } this.playerEntity.onGround = par1Packet10Flying.onGround; this.playerEntity.onUpdateEntity(); this.playerEntity.moveEntity(var35, 0.0D, var13); this.playerEntity.setPositionAndRotation(var5, var7, var9, var34, var4); this.playerEntity.motionX = var35; this.playerEntity.motionZ = var13; /*TODO if (this.playerEntity.ridingEntity != null) { var2.uncheckedUpdateEntity(this.playerEntity.ridingEntity, true); }*/ if (this.playerEntity.ridingEntity != null) { this.playerEntity.ridingEntity.updateRiderPosition(); } this.mcServer.getConfigurationManager().serverUpdateMountedMovingPlayer(this.playerEntity); lastPosX = this.playerEntity.posX; lastPosY = this.playerEntity.posY; lastPosZ = this.playerEntity.posZ; setPosition(lastPosX, lastPosY, lastPosZ); var2.updateEntity(this.playerEntity); return; } if (this.playerEntity.isPlayerSleeping()) { this.playerEntity.onUpdateEntity(); this.playerEntity.setPositionAndRotation(lastPosX, lastPosY, lastPosZ, this.playerEntity.rotationYaw, this.playerEntity.rotationPitch); var2.updateEntity(this.playerEntity); return; } var3 = this.playerEntity.posY; lastPosX = this.playerEntity.posX; lastPosY = this.playerEntity.posY; lastPosZ = this.playerEntity.posZ; setPosition(lastPosX, lastPosY, lastPosZ); var5 = this.playerEntity.posX; var7 = this.playerEntity.posY; var9 = this.playerEntity.posZ; float var11 = this.playerEntity.rotationYaw; float var12 = this.playerEntity.rotationPitch; if (par1Packet10Flying.moving && par1Packet10Flying.yPosition == -999.0D && par1Packet10Flying.stance == -999.0D) { par1Packet10Flying.moving = false; } if (par1Packet10Flying.moving) { var5 = par1Packet10Flying.xPosition; var7 = par1Packet10Flying.yPosition; var9 = par1Packet10Flying.zPosition; var13 = par1Packet10Flying.stance - par1Packet10Flying.yPosition; if (!this.playerEntity.isPlayerSleeping() && (var13 > 1.65D || var13 < 0.1D)) { this.kickPlayerFromServer("Illegal stance"); this.mcServer.getLogAgent().logWarning(this.playerEntity.getUsername() + " had an illegal stance: " + var13); return; } if (Math.abs(par1Packet10Flying.xPosition) > 3.2E7D || Math.abs(par1Packet10Flying.zPosition) > 3.2E7D) { this.kickPlayerFromServer("Illegal position"); return; } } if (par1Packet10Flying.rotating) { var11 = par1Packet10Flying.yaw; var12 = par1Packet10Flying.pitch; } this.playerEntity.onUpdateEntity(); this.playerEntity.ySize = 0.0F; this.playerEntity.setPositionAndRotation(lastPosX, lastPosY, lastPosZ, var11, var12); if (!hasMoved) { return; } var13 = var5 - this.playerEntity.posX; double var15 = var7 - this.playerEntity.posY; double var17 = var9 - this.playerEntity.posZ; double var19 = Math.min(Math.abs(var13), Math.abs(this.playerEntity.motionX)); double var21 = Math.min(Math.abs(var15), Math.abs(this.playerEntity.motionY)); double var23 = Math.min(Math.abs(var17), Math.abs(this.playerEntity.motionZ)); double var25 = var19 * var19 + var21 * var21 + var23 * var23; if (var25 > 100.0D && (!this.mcServer.isSinglePlayer() || !this.mcServer.getServerOwner().equals(this.playerEntity.getUsername()))) { this.mcServer.getLogAgent().logWarning(this.playerEntity.getUsername() + " moved too quickly! " + var13 + "," + var15 + "," + var17 + " (" + var19 + ", " + var21 + ", " + var23 + ")"); this.setPlayerLocation(lastPosX, lastPosY, lastPosZ, this.playerEntity.rotationYaw, this.playerEntity.rotationPitch); return; } float var27 = 0.0625F; boolean var28 = var2.getCollidingBoundingBoxes(this.playerEntity, this.playerEntity.boundingBox.copy().contract(var27, var27, var27)).isEmpty(); if (this.playerEntity.onGround && !par1Packet10Flying.onGround && var15 > 0.0D) { this.playerEntity.addExhaustion(0.2F); } this.playerEntity.moveEntity(var13, var15, var17); this.playerEntity.onGround = par1Packet10Flying.onGround; this.playerEntity.addMovementStat(var13, var15, var17); double var29 = var15; var13 = var5 - this.playerEntity.posX; var15 = var7 - this.playerEntity.posY; if (var15 > -0.5D || var15 < 0.5D) { var15 = 0.0D; } var17 = var9 - this.playerEntity.posZ; var25 = var13 * var13 + var15 * var15 + var17 * var17; boolean var31 = false; if (var25 > 0.0625D && !this.playerEntity.isPlayerSleeping() && !this.playerEntity.theItemInWorldManager.isCreative()) { var31 = true; this.mcServer.getLogAgent().logWarning(this.playerEntity.getUsername() + " moved wrongly!"); } this.playerEntity.setPositionAndRotation(var5, var7, var9, var11, var12); boolean var32 = var2.getCollidingBoundingBoxes(this.playerEntity, this.playerEntity.boundingBox.copy().contract(var27, var27, var27)).isEmpty(); if(this.playerEntity.noClip) { // do nothing } else if (var28 && (var31 || !var32) && !this.playerEntity.isPlayerSleeping()) { this.setPlayerLocation(lastPosX, lastPosY, lastPosZ, var11, var12); return; } AxisAlignedBB var33 = this.playerEntity.boundingBox.copy().expand(var27, var27, var27).addCoord(0.0D, -0.55D, 0.0D); if (!this.mcServer.isFlightAllowed() && !this.playerEntity.theItemInWorldManager.isCreative() && !var2.checkBlockCollision(var33)) { if (var29 >= -0.03125D) { ticksForFloatKick++; if (ticksForFloatKick > 80) { this.mcServer.getLogAgent().logWarning(this.playerEntity.getUsername() + " was kicked for floating too long!"); this.kickPlayerFromServer("Flying is not enabled on this server"); return; } } } else { ticksForFloatKick = 0; } this.playerEntity.onGround = par1Packet10Flying.onGround; this.mcServer.getConfigurationManager().serverUpdateMountedMovingPlayer(this.playerEntity); this.playerEntity.updateFlyingState(this.playerEntity.posY - var3, par1Packet10Flying.onGround); } } } }