Paper/src/main/java/net/minecraft/server/NetServerHandler.java

1002 Zeilen
40 KiB
Java

package net.minecraft.server;
2011-01-29 22:50:29 +01:00
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;
// CraftBukkit start
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.command.CommandException;
import org.bukkit.craftbukkit.block.CraftBlock;
import org.bukkit.craftbukkit.entity.CraftPlayer;
import org.bukkit.craftbukkit.event.CraftEventFactory;
import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.craftbukkit.TextWrapper;
import org.bukkit.entity.Player;
2011-03-24 23:27:40 +01:00
import org.bukkit.event.Event;
import org.bukkit.event.block.Action;
import org.bukkit.event.block.SignChangeEvent;
import org.bukkit.event.player.PlayerAnimationEvent;
import org.bukkit.event.player.PlayerChatEvent;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerItemHeldEvent;
import org.bukkit.event.player.PlayerKickEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.event.player.PlayerToggleSneakEvent;
// CraftBukkit end
public class NetServerHandler extends NetHandler implements ICommandListener {
public static Logger a = Logger.getLogger("Minecraft");
public NetworkManager networkManager;
public boolean disconnected = false;
private MinecraftServer minecraftServer;
2011-05-14 16:29:42 +02:00
public EntityPlayer player; // CraftBukkit - private -> public
2011-02-23 03:37:56 +01:00
private int f;
private int g;
2011-04-20 22:47:26 +02:00
private int h;
private boolean i;
private double x;
private double y;
private double z;
private boolean checkMovement = true;
2011-04-20 22:47:26 +02:00
private Map n = new HashMap();
2011-01-29 22:50:29 +01:00
public NetServerHandler(MinecraftServer minecraftserver, NetworkManager networkmanager, EntityPlayer entityplayer) {
this.minecraftServer = minecraftserver;
this.networkManager = networkmanager;
2011-01-29 22:50:29 +01:00
networkmanager.a((NetHandler) this);
this.player = entityplayer;
entityplayer.netServerHandler = this;
2011-01-29 22:50:29 +01:00
// CraftBukkit start
this.server = minecraftserver.server;
2011-01-29 22:50:29 +01:00
}
private final CraftServer server;
2011-05-14 16:29:42 +02:00
private int lastTick = MinecraftServer.currentTick;
private static final int PLACE_DISTANCE_SQUARED = 6 * 6;
2011-01-29 22:50:29 +01:00
// Get position of last block hit for BlockDamageLevel.STOPPED
private double lastPosX = Double.MAX_VALUE;
private double lastPosY = Double.MAX_VALUE;
private double lastPosZ = Double.MAX_VALUE;
private float lastPitch = Float.MAX_VALUE;
private float lastYaw = Float.MAX_VALUE;
// For the packet15 hack :(
Long lastPacket;
2011-01-29 22:50:29 +01:00
// Store the last block right clicked and what type it was
private int lastMaterial;
public CraftPlayer getPlayer() {
return (this.player == null) ? null : (CraftPlayer) this.player.getBukkitEntity();
}
// CraftBukkit end
public void a() {
2011-04-20 22:47:26 +02:00
this.i = false;
2011-05-26 14:48:22 +02:00
this.networkManager.b();
2011-02-23 03:37:56 +01:00
if (this.f - this.g > 20) {
this.sendPacket(new Packet0KeepAlive());
}
}
public void disconnect(String s) {
// CraftBukkit start
String leaveMessage = "\u00A7e" + this.player.name + " left the game.";
PlayerKickEvent event = new PlayerKickEvent(this.server.getPlayer(this.player), s, leaveMessage);
this.server.getPluginManager().callEvent(event);
2011-02-23 13:56:36 +01:00
if (event.isCancelled()) {
// Do not kick the player
return;
}
// Send the possibly modified leave message
2011-05-26 14:48:22 +02:00
s = event.getReason();
2011-05-28 22:50:08 +02:00
// CraftBukkit end
this.player.A();
2011-05-26 14:48:22 +02:00
this.sendPacket(new Packet255KickDisconnect(s));
this.networkManager.d();
2011-05-28 22:50:08 +02:00
2011-06-12 00:02:58 +02:00
// CraftBukkit start
leaveMessage = event.getLeaveMessage();
if (leaveMessage != null) {
this.minecraftServer.serverConfigurationManager.sendAll(new Packet3Chat(leaveMessage));
}
2011-02-23 03:37:56 +01:00
// CraftBukkit end
this.minecraftServer.serverConfigurationManager.disconnect(this.player);
this.disconnected = true;
}
2011-02-23 03:37:56 +01:00
public void a(Packet27 packet27) {
this.player.a(packet27.c(), packet27.e(), packet27.g(), packet27.h(), packet27.d(), packet27.f());
2011-02-23 03:37:56 +01:00
}
public void a(Packet10Flying packet10flying) {
WorldServer worldserver = this.minecraftServer.getWorldServer(this.player.dimension);
2011-05-26 14:48:22 +02:00
2011-04-20 22:47:26 +02:00
this.i = true;
2011-01-29 22:50:29 +01:00
double d0;
if (!this.checkMovement) {
d0 = packet10flying.y - this.y;
if (packet10flying.x == this.x && d0 * d0 < 0.01D && packet10flying.z == this.z) {
this.checkMovement = true;
}
}
// CraftBukkit start
Player player = this.getPlayer();
Location from = new Location(player.getWorld(), this.lastPosX, this.lastPosY, this.lastPosZ, this.lastYaw, this.lastPitch);
Location to = player.getLocation();
// Prevent 40 event-calls for less than a single pixel of movement >.>
2011-05-14 16:29:42 +02:00
double delta = Math.pow(this.lastPosX - this.x, 2) + Math.pow(this.lastPosY - this.y, 2) + Math.pow(this.lastPosZ - this.z, 2);
2011-06-12 00:02:58 +02:00
float deltaAngle = Math.abs(this.lastYaw - this.player.yaw) + Math.abs(this.lastPitch - this.player.pitch);
2011-06-12 00:02:58 +02:00
if (delta > 1f / 256 || deltaAngle > 10f) {
// Skip the first time we do this
if (this.lastPosX != Double.MAX_VALUE) {
PlayerMoveEvent event = new PlayerMoveEvent(player, from, to);
this.server.getPluginManager().callEvent(event);
2011-03-27 00:34:33 +01:00
// If the event is cancelled we move the player back to their old location.
if (event.isCancelled()) {
this.player.netServerHandler.sendPacket(new Packet13PlayerLookMove(from.getX(), from.getY() + 1.6200000047683716D, from.getY(), from.getZ(), from.getYaw(), from.getPitch(), false));
return;
}
/* If a Plugin has changed the To destination then we teleport the Player
there to avoid any 'Moved wrongly' or 'Moved too quickly' errors.
We only do this if the Event was not cancelled. */
if (!to.equals(event.getTo()) && !event.isCancelled()) {
((CraftPlayer) this.player.getBukkitEntity()).teleport(event.getTo());
return;
}
this.player.locX = to.getX();
this.player.locY = to.getY();
this.player.locZ = to.getZ();
this.player.yaw = to.getYaw();
this.player.pitch = to.getPitch();
}
this.lastPosX = this.player.locX;
this.lastPosY = this.player.locY;
this.lastPosZ = this.player.locZ;
this.lastYaw = this.player.yaw;
this.lastPitch = this.player.pitch;
}
if (Math.abs(packet10flying.x) > 32000000 || Math.abs(packet10flying.z) > 32000000) {
2011-04-29 08:08:46 +02:00
player.teleport(player.getWorld().getSpawnLocation());
System.err.println(player.getName() + " was caught trying to crash the server with an invalid position.");
player.kickPlayer("Nope!");
return;
}
if (Double.isNaN(packet10flying.x) || packet10flying.x == Double.POSITIVE_INFINITY || packet10flying.x == Double.NEGATIVE_INFINITY) {
2011-04-29 08:08:46 +02:00
player.teleport(player.getWorld().getSpawnLocation());
System.err.println(player.getName() + " was caught trying to set an invalid position.");
player.kickPlayer("Nope!");
return;
}
if (Double.isNaN(packet10flying.y) || packet10flying.y == Double.POSITIVE_INFINITY || packet10flying.y == Double.NEGATIVE_INFINITY) {
2011-04-29 08:08:46 +02:00
player.teleport(player.getWorld().getSpawnLocation());
System.err.println(player.getName() + " was caught trying to set an invalid position.");
player.kickPlayer("Nope!");
return;
}
if (Double.isNaN(packet10flying.z) || packet10flying.z == Double.POSITIVE_INFINITY || packet10flying.z == Double.NEGATIVE_INFINITY) {
2011-04-29 08:08:46 +02:00
player.teleport(player.getWorld().getSpawnLocation());
System.err.println(player.getName() + " was caught trying to set an invalid position.");
player.kickPlayer("Nope!");
return;
}
if (Double.isNaN(packet10flying.stance) || packet10flying.stance == Double.POSITIVE_INFINITY || packet10flying.stance == Double.NEGATIVE_INFINITY) {
2011-04-29 08:08:46 +02:00
player.teleport(player.getWorld().getSpawnLocation());
System.err.println(player.getName() + " was caught trying to set an invalid position.");
player.kickPlayer("Nope!");
return;
}
if (this.checkMovement && !this.player.dead) {
2011-06-12 00:02:58 +02:00
// CraftBukkit end
2011-01-29 22:50:29 +01:00
double d1;
double d2;
double d3;
double d4;
if (this.player.vehicle != null) {
float f = this.player.yaw;
float f1 = this.player.pitch;
2011-04-20 22:47:26 +02:00
this.player.vehicle.f();
d1 = this.player.locX;
d2 = this.player.locY;
d3 = this.player.locZ;
2011-01-29 22:50:29 +01:00
double d5 = 0.0D;
d4 = 0.0D;
if (packet10flying.hasLook) {
f = packet10flying.yaw;
f1 = packet10flying.pitch;
}
2011-01-29 22:50:29 +01:00
if (packet10flying.h && packet10flying.y == -999.0D && packet10flying.stance == -999.0D) {
d5 = packet10flying.x;
d4 = packet10flying.z;
}
2011-01-29 22:50:29 +01:00
2011-04-29 10:55:04 +02:00
this.player.onGround = packet10flying.g;
2011-06-09 20:24:21 +02:00
this.player.a(true);
this.player.move(d5, 0.0D, d4);
this.player.setLocation(d1, d2, d3, f, f1);
this.player.motX = d5;
this.player.motZ = d4;
if (this.player.vehicle != null) {
2011-05-26 14:48:22 +02:00
worldserver.vehicleEnteredWorld(this.player.vehicle, true);
}
2011-01-29 22:50:29 +01:00
if (this.player.vehicle != null) {
2011-04-20 22:47:26 +02:00
this.player.vehicle.f();
}
2011-01-29 22:50:29 +01:00
2011-05-26 14:48:22 +02:00
this.minecraftServer.serverConfigurationManager.d(this.player);
this.x = this.player.locX;
this.y = this.player.locY;
this.z = this.player.locZ;
2011-05-26 14:48:22 +02:00
worldserver.playerJoinedWorld(this.player);
2011-05-31 15:55:45 +02:00
return;
}
if (this.player.isSleeping()) {
this.player.a(true);
this.player.setLocation(this.x, this.y, this.z, this.player.yaw, this.player.pitch);
worldserver.playerJoinedWorld(this.player);
return;
}
d0 = this.player.locY;
this.x = this.player.locX;
this.y = this.player.locY;
this.z = this.player.locZ;
d1 = this.player.locX;
d2 = this.player.locY;
d3 = this.player.locZ;
float f2 = this.player.yaw;
float f3 = this.player.pitch;
2011-01-29 22:50:29 +01:00
if (packet10flying.h && packet10flying.y == -999.0D && packet10flying.stance == -999.0D) {
packet10flying.h = false;
}
2011-01-29 22:50:29 +01:00
if (packet10flying.h) {
d1 = packet10flying.x;
d2 = packet10flying.y;
d3 = packet10flying.z;
d4 = packet10flying.stance - packet10flying.y;
2011-04-20 22:47:26 +02:00
if (!this.player.isSleeping() && (d4 > 1.65D || d4 < 0.1D)) {
this.disconnect("Illegal stance");
a.warning(this.player.name + " had an illegal stance: " + d4);
2011-04-20 22:47:26 +02:00
return;
}
if (Math.abs(packet10flying.x) > 3.2E7D || Math.abs(packet10flying.z) > 3.2E7D) {
this.disconnect("Illegal position");
return;
}
}
2011-01-29 22:50:29 +01:00
2011-04-20 22:47:26 +02:00
if (packet10flying.hasLook) {
f2 = packet10flying.yaw;
f3 = packet10flying.pitch;
}
this.player.a(true);
2011-05-28 22:50:08 +02:00
this.player.br = 0.0F;
2011-04-20 22:47:26 +02:00
this.player.setLocation(this.x, this.y, this.z, f2, f3);
if (!this.checkMovement) {
2011-05-26 14:48:22 +02:00
return;
}
d4 = d1 - this.player.locX;
double d6 = d2 - this.player.locY;
double d7 = d3 - this.player.locZ;
double d8 = d4 * d4 + d6 * d6 + d7 * d7;
// CraftBukkit start - make the movement speed check behave properly under tick degradation.
int elapsedTicks = MinecraftServer.currentTick - this.lastTick;
2011-06-12 00:02:58 +02:00
// Added this.m condition to solve this check being triggered by teleports
if (d8 > 100.0D * (elapsedTicks <= 0 ? 1 : elapsedTicks) && this.checkMovement) {
2011-06-12 00:02:58 +02:00
a.warning(this.player.name + " moved too quickly! Elapsed ticks: " + (elapsedTicks == 0 ? 1 : elapsedTicks) + ", Distance change: " + d8);
2011-04-20 22:47:26 +02:00
this.disconnect("You moved too quickly :( (Hacking?)");
return;
}
this.lastTick = MinecraftServer.currentTick;
// CraftBukkit end
2011-01-29 22:50:29 +01:00
2011-04-20 22:47:26 +02:00
float f4 = 0.0625F;
2011-05-26 14:48:22 +02:00
boolean flag = worldserver.getEntities(this.player, this.player.boundingBox.clone().shrink((double) f4, (double) f4, (double) f4)).size() == 0;
2011-04-20 22:47:26 +02:00
this.player.move(d4, d6, d7);
d4 = d1 - this.player.locX;
d6 = d2 - this.player.locY;
2011-01-29 22:50:29 +01:00
if (d6 > -0.5D || d6 < 0.5D) {
d6 = 0.0D;
}
d7 = d3 - this.player.locZ;
2011-04-20 22:47:26 +02:00
d8 = d4 * d4 + d6 * d6 + d7 * d7;
boolean flag1 = false;
2011-04-20 22:47:26 +02:00
if (d8 > 0.0625D && !this.player.isSleeping()) {
flag1 = true;
a.warning(this.player.name + " moved wrongly!");
System.out.println("Got position " + d1 + ", " + d2 + ", " + d3);
System.out.println("Expected " + this.player.locX + ", " + this.player.locY + ", " + this.player.locZ);
}
2011-01-29 22:50:29 +01:00
this.player.setLocation(d1, d2, d3, f2, f3);
2011-05-26 14:48:22 +02:00
boolean flag2 = worldserver.getEntities(this.player, this.player.boundingBox.clone().shrink((double) f4, (double) f4, (double) f4)).size() == 0;
if (flag && (flag1 || !flag2) && !this.player.isSleeping()) {
this.a(this.x, this.y, this.z, f2, f3);
return;
}
2011-01-29 22:50:29 +01:00
2011-04-20 22:47:26 +02:00
AxisAlignedBB axisalignedbb = this.player.boundingBox.clone().b((double) f4, (double) f4, (double) f4).a(0.0D, -0.55D, 0.0D);
if (!this.minecraftServer.allowFlight && !worldserver.b(axisalignedbb)) {
2011-04-20 22:47:26 +02:00
if (d6 >= -0.03125D) {
++this.h;
if (this.h > 80) {
a.warning(this.player.name + " was kicked for floating too long!");
this.disconnect("Flying is not enabled on this server");
return;
}
}
} else {
this.h = 0;
}
2011-04-29 10:55:04 +02:00
this.player.onGround = packet10flying.g;
2011-05-26 14:48:22 +02:00
this.minecraftServer.serverConfigurationManager.d(this.player);
2011-04-29 10:55:04 +02:00
this.player.b(this.player.locY - d0, packet10flying.g);
}
}
2011-03-23 18:42:36 +01:00
public void a(double d0, double d1, double d2, float f, float f1) {
2011-05-14 16:29:42 +02:00
// CraftBukkit start - Delegate to teleport(Location)
Player player = this.getPlayer();
Location from = player.getLocation();
Location to = new Location(this.getPlayer().getWorld(), d0, d1, d2, f, f1);
2011-03-27 00:34:33 +01:00
PlayerTeleportEvent event = new PlayerTeleportEvent(player, from, to);
this.server.getPluginManager().callEvent(event);
from = event.getFrom();
to = event.isCancelled() ? from : event.getTo();
this.teleport(to);
}
public void teleport(Location dest) {
double d0, d1, d2;
float f, f1;
d0 = dest.getX();
d1 = dest.getY();
d2 = dest.getZ();
f = dest.getYaw();
f1 = dest.getPitch();
// TODO: make sure this is the best way to address this.
if (Float.isNaN(f)) {
f = 0;
}
if (Float.isNaN(f1)) {
f1 = 0;
}
2011-03-23 18:42:36 +01:00
// CraftBukkit end
this.checkMovement = false;
this.x = d0;
this.y = d1;
this.z = d2;
this.player.setLocation(d0, d1, d2, f, f1);
this.player.netServerHandler.sendPacket(new Packet13PlayerLookMove(d0, d1 + 1.6200000047683716D, d1, d2, f, f1, false));
}
public void a(Packet14BlockDig packet14blockdig) {
if (this.player.dead) return; // CraftBukkit
2011-05-12 16:22:52 +02:00
WorldServer worldserver = this.minecraftServer.getWorldServer(this.player.dimension);
2011-05-26 14:48:22 +02:00
if (packet14blockdig.e == 4) {
2011-05-28 22:50:08 +02:00
this.player.E();
2011-01-29 22:50:29 +01:00
} else {
2011-06-12 00:02:58 +02:00
boolean flag = worldserver.weirdIsOpCache = worldserver.dimension != 0 || this.minecraftServer.serverConfigurationManager.isOp(this.player.name); // CraftBukkit
2011-01-29 22:50:29 +01:00
boolean flag1 = false;
2011-01-29 22:50:29 +01:00
if (packet14blockdig.e == 0) {
flag1 = true;
}
2011-02-23 03:37:56 +01:00
if (packet14blockdig.e == 2) {
2011-01-29 22:50:29 +01:00
flag1 = true;
}
2011-01-29 22:50:29 +01:00
int i = packet14blockdig.a;
int j = packet14blockdig.b;
int k = packet14blockdig.c;
if (flag1) {
double d0 = this.player.locX - ((double) i + 0.5D);
double d1 = this.player.locY - ((double) j + 0.5D);
double d2 = this.player.locZ - ((double) k + 0.5D);
2011-01-29 22:50:29 +01:00
double d3 = d0 * d0 + d1 * d1 + d2 * d2;
if (d3 > 36.0D) {
return;
}
}
2011-05-26 14:48:22 +02:00
ChunkCoordinates chunkcoordinates = worldserver.getSpawn();
int l = (int) MathHelper.abs((float) (i - chunkcoordinates.x));
int i1 = (int) MathHelper.abs((float) (k - chunkcoordinates.z));
2011-02-23 03:37:56 +01:00
if (l > i1) {
i1 = l;
2011-01-29 22:50:29 +01:00
}
2011-01-10 02:36:19 +01:00
2011-01-29 22:50:29 +01:00
if (packet14blockdig.e == 0) {
2011-03-23 16:38:42 +01:00
// CraftBukkit
if (i1 < this.server.getSpawnRadius() && !flag) {
2011-05-26 14:48:22 +02:00
this.player.netServerHandler.sendPacket(new Packet53BlockChange(i, j, k, worldserver));
} else {
2011-05-14 16:29:42 +02:00
// CraftBukkit - add face argument
this.player.itemInWorldManager.dig(i, j, k, packet14blockdig.face);
2011-01-29 22:50:29 +01:00
}
} else if (packet14blockdig.e == 2) {
2011-05-26 14:48:22 +02:00
this.player.itemInWorldManager.a(i, j, k);
if (worldserver.getTypeId(i, j, k) != 0) {
this.player.netServerHandler.sendPacket(new Packet53BlockChange(i, j, k, worldserver));
}
2011-01-29 22:50:29 +01:00
} else if (packet14blockdig.e == 3) {
double d4 = this.player.locX - ((double) i + 0.5D);
double d5 = this.player.locY - ((double) j + 0.5D);
double d6 = this.player.locZ - ((double) k + 0.5D);
2011-02-23 03:37:56 +01:00
double d7 = d4 * d4 + d5 * d5 + d6 * d6;
2011-01-29 22:50:29 +01:00
2011-02-23 03:37:56 +01:00
if (d7 < 256.0D) {
2011-05-26 14:48:22 +02:00
this.player.netServerHandler.sendPacket(new Packet53BlockChange(i, j, k, worldserver));
2011-01-10 02:36:19 +01:00
}
}
2011-05-26 14:48:22 +02:00
worldserver.weirdIsOpCache = false;
2011-01-29 22:50:29 +01:00
}
}
public void a(Packet15Place packet15place) {
WorldServer worldserver = this.minecraftServer.getWorldServer(this.player.dimension);
2011-05-26 14:48:22 +02:00
2011-03-24 12:11:28 +01:00
// CraftBukkit start
if (this.player.dead) return;
2011-05-12 16:22:52 +02:00
// This is a horrible hack needed because the client sends 2 packets on 'right mouse click'
// aimed at a block. We shouldn't need to get the second packet if the data is handled
// but we cannot know what the client will do, so we might still get it
//
// If the time between packets is small enough, and the 'signature' similar, we discard the
// second one. This sadly has to remain until Mojang makes their packets saner. :(
// -- Grum
2011-01-10 02:36:19 +01:00
if (packet15place.face == 255) {
if (packet15place.itemstack != null && packet15place.itemstack.id == this.lastMaterial && this.lastPacket != null && packet15place.timestamp - this.lastPacket < 100) {
this.lastPacket = null;
return;
}
} else {
this.lastMaterial = packet15place.itemstack == null ? -1 : packet15place.itemstack.id;
this.lastPacket = packet15place.timestamp;
}
2011-01-10 02:36:19 +01:00
2011-05-14 16:29:42 +02:00
// CraftBukkit - if rightclick decremented the item, always send the update packet.
// this is not here for CraftBukkit's own functionality; rather it is to fix
// a notch bug where the item doesn't update correctly.
boolean always = false;
// CraftBukkit end
2011-01-10 02:36:19 +01:00
ItemStack itemstack = this.player.inventory.getItemInHand();
2011-06-12 00:02:58 +02:00
boolean flag = worldserver.weirdIsOpCache = worldserver.dimension != 0 || this.minecraftServer.serverConfigurationManager.isOp(this.player.name); // CraftBukkit
if (packet15place.face == 255) {
if (itemstack == null) {
return;
}
2011-01-10 02:36:19 +01:00
2011-03-24 12:11:28 +01:00
// CraftBukkit start
2011-03-24 23:27:40 +01:00
int itemstackAmount = itemstack.count;
PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(this.player, Action.RIGHT_CLICK_AIR, itemstack);
if (event.useItemInHand() != Event.Result.DENY) {
this.player.itemInWorldManager.useItem(this.player, this.player.world, itemstack);
}
2011-05-14 16:29:42 +02:00
// CraftBukkit - notch decrements the counter by 1 in the above method with food,
// snowballs and so forth, but he does it in a place that doesn't cause the
2011-03-24 23:27:40 +01:00
// inventory update packet to get sent
always = (itemstack.count != itemstackAmount);
// CraftBukkit end
} else {
2011-01-29 22:50:29 +01:00
int i = packet15place.a;
int j = packet15place.b;
int k = packet15place.c;
int l = packet15place.face;
2011-05-26 14:48:22 +02:00
ChunkCoordinates chunkcoordinates = worldserver.getSpawn();
int i1 = (int) MathHelper.abs((float) (i - chunkcoordinates.x));
int j1 = (int) MathHelper.abs((float) (k - chunkcoordinates.z));
2011-01-29 22:50:29 +01:00
if (i1 > j1) {
j1 = i1;
}
2011-01-29 22:50:29 +01:00
2011-05-26 14:48:22 +02:00
// CraftBukkit start - Check if we can actually do something over this large a distance
Location eyeLoc = this.getPlayer().getEyeLocation();
if (Math.pow(eyeLoc.getX() - i, 2) + Math.pow(eyeLoc.getY() - j, 2) + Math.pow(eyeLoc.getZ() - k, 2) > PLACE_DISTANCE_SQUARED) {
return;
}
2011-05-26 14:48:22 +02:00
flag = true; // spawn protection moved to ItemBlock!!!
// CraftBukkit end
2011-05-26 14:48:22 +02:00
if (j1 > 16 || flag) {
this.player.itemInWorldManager.interact(this.player, worldserver, itemstack, i, j, k, l);
}
this.player.netServerHandler.sendPacket(new Packet53BlockChange(i, j, k, worldserver));
2011-01-29 22:50:29 +01:00
if (l == 0) {
--j;
}
2011-01-29 22:50:29 +01:00
if (l == 1) {
++j;
}
2011-01-29 22:50:29 +01:00
if (l == 2) {
--k;
}
2011-01-29 22:50:29 +01:00
if (l == 3) {
++k;
}
2011-01-29 22:50:29 +01:00
if (l == 4) {
--i;
}
2011-01-29 22:50:29 +01:00
if (l == 5) {
++i;
}
2011-01-29 22:50:29 +01:00
2011-05-26 14:48:22 +02:00
this.player.netServerHandler.sendPacket(new Packet53BlockChange(i, j, k, worldserver));
}
2011-01-29 22:50:29 +01:00
2011-05-26 14:48:22 +02:00
itemstack = this.player.inventory.getItemInHand();
2011-01-29 22:50:29 +01:00
if (itemstack != null && itemstack.count == 0) {
this.player.inventory.items[this.player.inventory.itemInHandIndex] = null;
}
this.player.h = true;
this.player.inventory.items[this.player.inventory.itemInHandIndex] = ItemStack.b(this.player.inventory.items[this.player.inventory.itemInHandIndex]);
Slot slot = this.player.activeContainer.a(this.player.inventory, this.player.inventory.itemInHandIndex);
2011-01-29 22:50:29 +01:00
this.player.activeContainer.a();
this.player.h = false;
2011-05-14 16:29:42 +02:00
// CraftBukkit
if (!ItemStack.equals(this.player.inventory.getItemInHand(), packet15place.itemstack) || always) {
this.sendPacket(new Packet103SetSlot(this.player.activeContainer.windowId, slot.a, this.player.inventory.getItemInHand()));
}
2011-01-29 22:50:29 +01:00
2011-05-26 14:48:22 +02:00
worldserver.weirdIsOpCache = false;
}
2011-01-10 02:36:19 +01:00
2011-01-29 22:50:29 +01:00
public void a(String s, Object[] aobject) {
if (this.disconnected) return; // CraftBukkit - rarely it would send a disconnect line twice
a.info(this.player.name + " lost connection: " + s);
2011-04-26 04:36:55 +02:00
// CraftBukkit start - we need to handle custom quit messages
String quitMessage = this.minecraftServer.serverConfigurationManager.disconnect(this.player);
if (quitMessage != null) {
this.minecraftServer.serverConfigurationManager.sendAll(new Packet3Chat(quitMessage));
}
// CraftBukkit end
this.disconnected = true;
}
public void a(Packet packet) {
2011-01-29 22:50:29 +01:00
a.warning(this.getClass() + " wasn\'t prepared to deal with a " + packet.getClass());
this.disconnect("Protocol error, unexpected packet");
}
public void sendPacket(Packet packet) {
2011-05-14 16:29:42 +02:00
// CraftBukkit start
2011-03-25 21:22:03 +01:00
if (packet instanceof Packet6SpawnPosition) {
Packet6SpawnPosition packet6 = (Packet6SpawnPosition) packet;
this.player.compassTarget = new Location(this.getPlayer().getWorld(), packet6.x, packet6.y, packet6.z);
} else if (packet instanceof Packet3Chat) {
String message = ((Packet3Chat) packet).message;
for (final String line: TextWrapper.wrapText(message)) {
this.networkManager.queue(new Packet3Chat(line));
}
packet = null;
2011-03-25 21:22:03 +01:00
}
if (packet != null) this.networkManager.queue(packet);
2011-05-14 16:29:42 +02:00
// CraftBukkit end
2011-02-23 03:37:56 +01:00
this.g = this.f;
}
public void a(Packet16BlockItemSwitch packet16blockitemswitch) {
if (this.player.dead) return; // CraftBukkit
2011-05-12 16:22:52 +02:00
if (packet16blockitemswitch.itemInHandIndex >= 0 && packet16blockitemswitch.itemInHandIndex <= InventoryPlayer.e()) {
// CraftBukkit start
PlayerItemHeldEvent event = new PlayerItemHeldEvent(this.getPlayer(), this.player.inventory.itemInHandIndex, packet16blockitemswitch.itemInHandIndex);
this.server.getPluginManager().callEvent(event);
// CraftBukkit end
2011-05-14 16:29:42 +02:00
this.player.inventory.itemInHandIndex = packet16blockitemswitch.itemInHandIndex;
} else {
a.warning(this.player.name + " tried to set an invalid carried item");
}
}
public void a(Packet3Chat packet3chat) {
String s = packet3chat.message;
if (s.length() > 100) {
this.disconnect("Chat message too long");
} else {
2011-01-29 22:50:29 +01:00
s = s.trim();
for (int i = 0; i < s.length(); ++i) {
if (FontAllowedCharacters.allowedCharacters.indexOf(s.charAt(i)) < 0) {
this.disconnect("Illegal characters in chat");
2011-01-29 22:50:29 +01:00
return;
}
2011-01-10 02:36:19 +01:00
}
2011-02-23 13:56:36 +01:00
// CraftBukkit start
this.chat(s);
2011-02-17 06:46:01 +01:00
}
}
2011-05-26 14:48:22 +02:00
public boolean chat(String s) {
if (!this.player.dead) {
if (s.startsWith("/")) {
this.handleCommand(s);
2011-02-17 06:46:01 +01:00
return true;
2011-05-26 14:48:22 +02:00
} else {
Player player = this.getPlayer();
2011-05-26 14:48:22 +02:00
PlayerChatEvent event = new PlayerChatEvent(player, s);
this.server.getPluginManager().callEvent(event);
2011-05-26 14:48:22 +02:00
if (event.isCancelled()) {
return true;
}
2011-02-17 06:46:01 +01:00
2011-05-26 14:48:22 +02:00
s = String.format(event.getFormat(), event.getPlayer().getDisplayName(), event.getMessage());
a.info(s);
for (Player recipient : event.getRecipients()) {
recipient.sendMessage(s);
}
}
}
2011-02-17 06:46:01 +01:00
return false;
2011-05-14 16:29:42 +02:00
// CraftBukkit end
}
private void handleCommand(String s) {
// CraftBukkit start
CraftPlayer player = this.getPlayer();
2011-01-29 22:50:29 +01:00
2011-03-27 00:34:33 +01:00
PlayerCommandPreprocessEvent event = new PlayerCommandPreprocessEvent(player, s);
this.server.getPluginManager().callEvent(event);
2011-01-10 02:36:19 +01:00
if (event.isCancelled()) {
return;
}
try {
if (this.server.dispatchCommand(player, s.substring(1))) {
return;
}
} catch (CommandException ex) {
2011-05-14 16:29:42 +02:00
player.sendMessage(ChatColor.RED + "An internal error occurred while attempting to perform this command");
Logger.getLogger(NetServerHandler.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
return;
}
2011-05-14 16:29:42 +02:00
// CraftBukkit end
if (s.toLowerCase().startsWith("/me ")) {
s = "* " + this.player.name + " " + s.substring(s.indexOf(" ")).trim();
a.info(s);
this.minecraftServer.serverConfigurationManager.sendAll(new Packet3Chat(s));
} else if (s.toLowerCase().startsWith("/kill")) {
this.player.damageEntity((Entity) null, 1000);
} else if (s.toLowerCase().startsWith("/tell ")) {
2011-01-29 22:50:29 +01:00
String[] astring = s.split(" ");
2011-01-29 22:50:29 +01:00
if (astring.length >= 3) {
s = s.substring(s.indexOf(" ")).trim();
s = s.substring(s.indexOf(" ")).trim();
s = "\u00A77" + this.player.name + " whispers " + s;
2011-01-29 22:50:29 +01:00
a.info(s + " to " + astring[1]);
if (!this.minecraftServer.serverConfigurationManager.a(astring[1], (Packet) (new Packet3Chat(s)))) {
this.sendPacket(new Packet3Chat("\u00A7cThere\'s no player by that name online."));
}
}
2011-05-26 14:48:22 +02:00
/* CraftBukkit start - No longer neaded av we have already handled it server.dispatchCommand above.
} else {
2011-01-29 22:50:29 +01:00
String s1;
2011-05-26 14:48:22 +02:00
if (this.minecraftServer.serverConfigurationManager.isOp(this.player.name)) {
2011-01-29 22:50:29 +01:00
s1 = s.substring(1);
a.info(this.player.name + " issued server command: " + s1);
this.minecraftServer.issueCommand(s1, this);
2011-01-29 22:50:29 +01:00
} else {
s1 = s.substring(1);
a.info(this.player.name + " tried command: " + s1);
2011-01-29 22:50:29 +01:00
}
2011-06-12 00:02:58 +02:00
// CraftBukkit end */
}
}
public void a(Packet18ArmAnimation packet18armanimation) {
if (this.player.dead) return; // CraftBukkit
2011-05-12 16:22:52 +02:00
if (packet18armanimation.b == 1) {
2011-05-14 16:29:42 +02:00
// CraftBukkit start - raytrace to look for 'rogue armswings'
float f = 1.0F;
float f1 = this.player.lastPitch + (this.player.pitch - this.player.lastPitch) * f;
float f2 = this.player.lastYaw + (this.player.yaw - this.player.lastYaw) * f;
double d0 = this.player.lastX + (this.player.locX - this.player.lastX) * (double) f;
double d1 = this.player.lastY + (this.player.locY - this.player.lastY) * (double) f + 1.62D - (double) this.player.height;
double d2 = this.player.lastZ + (this.player.locZ - this.player.lastZ) * (double) f;
Vec3D vec3d = Vec3D.create(d0, d1, d2);
float f3 = MathHelper.cos(-f2 * 0.017453292F - 3.1415927F);
float f4 = MathHelper.sin(-f2 * 0.017453292F - 3.1415927F);
float f5 = -MathHelper.cos(-f1 * 0.017453292F);
float f6 = MathHelper.sin(-f1 * 0.017453292F);
float f7 = f4 * f5;
float f8 = f3 * f5;
double d3 = 5.0D;
Vec3D vec3d1 = vec3d.add((double) f7 * d3, (double) f6 * d3, (double) f8 * d3);
MovingObjectPosition movingobjectposition = this.player.world.rayTrace(vec3d, vec3d1, true);
if (movingobjectposition == null || movingobjectposition.type != EnumMovingObjectType.TILE) {
CraftEventFactory.callPlayerInteractEvent(this.player, Action.LEFT_CLICK_AIR, this.player.inventory.getItemInHand());
}
// Arm swing animation
PlayerAnimationEvent event = new PlayerAnimationEvent(this.getPlayer());
this.server.getPluginManager().callEvent(event);
2011-01-29 22:50:29 +01:00
// CraftBukkit end
2011-04-20 22:47:26 +02:00
this.player.k_();
2011-01-14 14:31:10 +01:00
}
}
2011-01-29 22:50:29 +01:00
public void a(Packet19EntityAction packet19entityaction) {
// CraftBukkit start
if (this.player.dead) return;
2011-05-12 16:22:52 +02:00
if (packet19entityaction.animation == 1 || packet19entityaction.animation == 2) {
PlayerToggleSneakEvent event = new PlayerToggleSneakEvent(this.getPlayer(), packet19entityaction.animation == 1);
this.server.getPluginManager().callEvent(event);
2011-01-25 19:08:54 +01:00
if (event.isCancelled()) {
return;
}
}
// CraftBukkit end
2011-01-25 19:08:54 +01:00
if (packet19entityaction.animation == 1) {
this.player.setSneak(true);
} else if (packet19entityaction.animation == 2) {
this.player.setSneak(false);
} else if (packet19entityaction.animation == 3) {
this.player.a(false, true, true);
this.checkMovement = false;
}
}
public void a(Packet255KickDisconnect packet255kickdisconnect) {
this.networkManager.a("disconnect.quitting", new Object[0]);
}
public int b() {
2011-05-26 14:48:22 +02:00
return this.networkManager.e();
}
public void sendMessage(String s) {
this.sendPacket(new Packet3Chat("\u00A77" + s));
}
public String getName() {
return this.player.name;
}
2011-01-29 22:50:29 +01:00
public void a(Packet7UseEntity packet7useentity) {
if (this.player.dead) return; // CraftBukkit
2011-05-12 16:22:52 +02:00
WorldServer worldserver = this.minecraftServer.getWorldServer(this.player.dimension);
2011-05-26 14:48:22 +02:00
Entity entity = worldserver.getEntity(packet7useentity.target);
2011-06-19 19:58:38 +02:00
ItemStack itemInHand = this.player.inventory.getItemInHand();
2011-05-26 14:48:22 +02:00
if (entity != null && this.player.e(entity) && this.player.g(entity) < 36.0D) {
2011-01-29 22:50:29 +01:00
if (packet7useentity.c == 0) {
// CraftBukkit start
PlayerInteractEntityEvent event = new PlayerInteractEntityEvent((Player) this.getPlayer(), entity.getBukkitEntity());
this.server.getPluginManager().callEvent(event);
if (event.isCancelled()) {
return;
}
// CraftBukkit end
this.player.c(entity);
// CraftBukkit start - update the client if the item is an infinite one
2011-06-19 19:58:38 +02:00
if (itemInHand != null && itemInHand.count <= -1) {
this.player.updateInventory(this.player.activeContainer);
}
// CraftBukkit end
2011-01-29 22:50:29 +01:00
} else if (packet7useentity.c == 1) {
this.player.d(entity);
// CraftBukkit start - update the client if the item is an infinite one
2011-06-19 19:58:38 +02:00
if (itemInHand != null && itemInHand.count <= -1) {
this.player.updateInventory(this.player.activeContainer);
}
// CraftBukkit end
}
}
}
2011-01-29 22:50:29 +01:00
public void a(Packet9Respawn packet9respawn) {
if (this.player.health <= 0) {
this.player = this.minecraftServer.serverConfigurationManager.moveToWorld(this.player, 0);
2011-01-29 22:50:29 +01:00
this.getPlayer().setHandle(this.player); // CraftBukkit
}
}
2011-01-29 22:50:29 +01:00
public void a(Packet101CloseWindow packet101closewindow) {
if (this.player.dead) return; // CraftBukkit
2011-05-12 16:22:52 +02:00
2011-04-20 22:47:26 +02:00
this.player.z();
}
2011-01-29 22:50:29 +01:00
public void a(Packet102WindowClick packet102windowclick) {
if (this.player.dead) return; // CraftBukkit
2011-05-12 16:22:52 +02:00
if (this.player.activeContainer.windowId == packet102windowclick.a && this.player.activeContainer.c(this.player)) {
2011-04-20 22:47:26 +02:00
ItemStack itemstack = this.player.activeContainer.a(packet102windowclick.b, packet102windowclick.c, packet102windowclick.f, this.player);
2011-05-14 16:29:42 +02:00
if (ItemStack.equals(packet102windowclick.e, itemstack)) {
this.player.netServerHandler.sendPacket(new Packet106Transaction(packet102windowclick.a, packet102windowclick.d, true));
this.player.h = true;
this.player.activeContainer.a();
2011-04-20 22:47:26 +02:00
this.player.y();
this.player.h = false;
} else {
this.n.put(Integer.valueOf(this.player.activeContainer.windowId), Short.valueOf(packet102windowclick.d));
this.player.netServerHandler.sendPacket(new Packet106Transaction(packet102windowclick.a, packet102windowclick.d, false));
this.player.activeContainer.a(this.player, false);
ArrayList arraylist = new ArrayList();
for (int i = 0; i < this.player.activeContainer.e.size(); ++i) {
arraylist.add(((Slot) this.player.activeContainer.e.get(i)).getItem());
}
this.player.a(this.player.activeContainer, arraylist);
}
}
}
2011-01-29 22:50:29 +01:00
public void a(Packet106Transaction packet106transaction) {
if (this.player.dead) return; // CraftBukkit
2011-05-12 16:22:52 +02:00
Short oshort = (Short) this.n.get(Integer.valueOf(this.player.activeContainer.windowId));
if (oshort != null && packet106transaction.b == oshort.shortValue() && this.player.activeContainer.windowId == packet106transaction.a && !this.player.activeContainer.c(this.player)) {
this.player.activeContainer.a(this.player, true);
}
}
2011-01-29 22:50:29 +01:00
public void a(Packet130UpdateSign packet130updatesign) {
if (this.player.dead) return; // CraftBukkit
WorldServer worldserver = this.minecraftServer.getWorldServer(this.player.dimension);
2011-05-12 16:22:52 +02:00
2011-05-26 14:48:22 +02:00
if (worldserver.isLoaded(packet130updatesign.x, packet130updatesign.y, packet130updatesign.z)) {
TileEntity tileentity = worldserver.getTileEntity(packet130updatesign.x, packet130updatesign.y, packet130updatesign.z);
2011-03-09 00:18:14 +01:00
if (tileentity instanceof TileEntitySign) {
TileEntitySign tileentitysign = (TileEntitySign) tileentity;
2011-03-31 22:40:00 +02:00
if (!tileentitysign.a()) {
this.minecraftServer.c("Player " + this.player.name + " just tried to change non-editable sign");
2011-05-14 16:29:42 +02:00
// CraftBukkit
2011-04-28 07:29:36 +02:00
this.sendPacket(new Packet130UpdateSign(packet130updatesign.x, packet130updatesign.y, packet130updatesign.z, tileentitysign.lines));
2011-03-09 00:18:14 +01:00
return;
}
2011-05-14 16:29:42 +02:00
}
2011-01-29 22:50:29 +01:00
2011-05-14 16:29:42 +02:00
int i;
int j;
2011-05-14 16:29:42 +02:00
for (j = 0; j < 4; ++j) {
boolean flag = true;
2011-05-14 16:29:42 +02:00
if (packet130updatesign.lines[j].length() > 15) {
flag = false;
} else {
for (i = 0; i < packet130updatesign.lines[j].length(); ++i) {
if (FontAllowedCharacters.allowedCharacters.indexOf(packet130updatesign.lines[j].charAt(i)) < 0) {
2011-05-14 16:29:42 +02:00
flag = false;
}
}
2011-05-14 16:29:42 +02:00
}
2011-01-29 22:50:29 +01:00
2011-05-14 16:29:42 +02:00
if (!flag) {
packet130updatesign.lines[j] = "!?";
}
2011-05-14 16:29:42 +02:00
}
2011-01-29 22:50:29 +01:00
2011-05-14 16:29:42 +02:00
if (tileentity instanceof TileEntitySign) {
j = packet130updatesign.x;
int k = packet130updatesign.y;
2011-05-14 16:29:42 +02:00
i = packet130updatesign.z;
TileEntitySign tileentitysign1 = (TileEntitySign) tileentity;
2011-02-23 13:56:36 +01:00
2011-05-14 16:29:42 +02:00
// CraftBukkit start
Player player = this.server.getPlayer(this.player);
SignChangeEvent event = new SignChangeEvent((CraftBlock) player.getWorld().getBlockAt(j, k, i), this.server.getPlayer(this.player), packet130updatesign.lines);
this.server.getPluginManager().callEvent(event);
2011-02-11 03:15:59 +01:00
2011-05-14 16:29:42 +02:00
if (!event.isCancelled()) {
for (int l = 0; l < 4; ++l) {
tileentitysign1.lines[l] = event.getLine(l);
}
tileentitysign1.setEditable(false);
}
2011-05-14 16:29:42 +02:00
// CraftBukkit end
tileentitysign1.update();
2011-05-26 14:48:22 +02:00
worldserver.notify(j, k, i);
}
}
}
2011-04-20 22:47:26 +02:00
public boolean c() {
return true;
}
}