Fork of Poseidon providing Bukkit #1060 to older Beta versions (b1.0-b1.7.3)
1package net.minecraft.server;
2
3import com.legacyminecraft.poseidon.Poseidon;
4import com.legacyminecraft.poseidon.event.PlayerSendPacketEvent;
5import com.projectposeidon.ConnectionType;
6import com.legacyminecraft.poseidon.PoseidonConfig;
7
8import java.util.ArrayList;
9import java.util.HashMap;
10import java.util.Map;
11import java.util.logging.Logger;
12
13import me.devcody.uberbukkit.patch.Patches;
14import org.bukkit.Bukkit;
15import org.bukkit.ChatColor;
16import org.bukkit.Location;
17import org.bukkit.command.CommandException;
18import org.bukkit.craftbukkit.ChunkCompressionThread;
19import org.bukkit.craftbukkit.CraftServer;
20import org.bukkit.craftbukkit.TextWrapper;
21import org.bukkit.craftbukkit.block.CraftBlock;
22import org.bukkit.craftbukkit.entity.CraftPlayer;
23import org.bukkit.craftbukkit.event.CraftEventFactory;
24import org.bukkit.craftbukkit.inventory.CraftItemStack;
25import org.bukkit.entity.Player;
26import org.bukkit.entity.StorageMinecart;
27import org.bukkit.event.Event;
28import org.bukkit.event.block.Action;
29import org.bukkit.event.block.BlockDamageEvent;
30import org.bukkit.event.block.BlockRedstoneEvent;
31import org.bukkit.event.block.SignChangeEvent;
32import org.bukkit.event.packet.*;
33import org.bukkit.event.player.*;
34
35import uk.betacraft.uberbukkit.UberbukkitConfig;
36import uk.betacraft.uberbukkit.packet.Packet62Sound;
37import uk.betacraft.uberbukkit.packet.Packet63Digging;
38import uk.betacraft.uberbukkit.protocol.Protocol;
39
40public class NetServerHandler extends NetHandler implements ICommandListener {
41
42 private static boolean isStaffExemptFromFlyKick = UberbukkitConfig.getInstance().getBoolean("settings.exempt-staff-from-flight-kick", false);
43 public static Logger a = Logger.getLogger("Minecraft");
44 public NetworkManager networkManager;
45 public boolean disconnected = false;
46 private MinecraftServer minecraftServer;
47 public EntityPlayer player; // CraftBukkit - private -> public
48 private int f;
49 private int g;
50 private int h;
51 private boolean i;
52 private double x;
53 private double y;
54 private double z;
55 private boolean checkMovement = true;
56 private Map n = new HashMap();
57 private boolean usingReleaseToBeta = false; //Project Poseidon - Create Variable
58 private ConnectionType connectionType = ConnectionType.NORMAL; //Project Poseidon - Create Variable
59 private int rawConnectionType = 0; //Project Poseidon - Create Variable
60 private boolean receivedKeepAlive = false;
61 private boolean firePacketEvents;
62
63 private final String msgPlayerLeave;
64
65 public boolean isReceivedKeepAlive() {
66 return receivedKeepAlive;
67 }
68
69 public void setReceivedKeepAlive(boolean receivedKeepAlive) {
70 this.receivedKeepAlive = receivedKeepAlive;
71 }
72
73 public NetServerHandler(MinecraftServer minecraftserver, NetworkManager networkmanager, EntityPlayer entityplayer) {
74 this.minecraftServer = minecraftserver;
75 this.networkManager = networkmanager;
76 networkmanager.a((NetHandler) this);
77 this.player = entityplayer;
78 entityplayer.netServerHandler = this;
79
80 // CraftBukkit start
81 this.server = minecraftserver.server;
82 this.firePacketEvents = PoseidonConfig.getInstance().getBoolean("settings.packet-events.enabled", false); //Poseidon
83 this.msgPlayerLeave = PoseidonConfig.getInstance().getConfigString("message.player.leave");
84 }
85
86 //Project Poseidon - Start
87 public boolean isUsingReleaseToBeta() {
88 return usingReleaseToBeta;
89 }
90
91 public void setUsingReleaseToBeta(boolean usingReleaseToBeta) {
92 this.usingReleaseToBeta = usingReleaseToBeta;
93 }
94
95 public ConnectionType getConnectionType() {
96 return this.connectionType;
97 }
98
99 public void setConnectionType(ConnectionType connectionType) {
100 this.connectionType = connectionType;
101 }
102
103 public void setRawConnectionType(int rawConnectionType) {
104 this.rawConnectionType = rawConnectionType;
105 }
106
107 public int getRawConnectionType() {
108 return this.rawConnectionType;
109 }
110
111 //Project Poseidon - End
112
113 private final CraftServer server;
114 private int lastTick = MinecraftServer.currentTick;
115 private int lastDropTick = MinecraftServer.currentTick;
116 private int dropCount = 0;
117 private static final int PLACE_DISTANCE_SQUARED = 6 * 6;
118
119 // Get position of last block hit for BlockDamageLevel.STOPPED
120 private double lastPosX = Double.MAX_VALUE;
121 private double lastPosY = Double.MAX_VALUE;
122 private double lastPosZ = Double.MAX_VALUE;
123 private float lastPitch = Float.MAX_VALUE;
124 private float lastYaw = Float.MAX_VALUE;
125 private boolean justTeleported = false;
126
127 // For the packet15 hack :(
128 Long lastPacket;
129
130 // Store the last block right clicked and what type it was
131 private int lastMaterial;
132
133 public CraftPlayer getPlayer() {
134 return (this.player == null) ? null : (CraftPlayer) this.player.getBukkitEntity();
135 }
136 // CraftBukkit end
137
138 // uberbukkit
139 public Integer lastDigX = null;
140 public Integer lastDigY = null;
141 public Integer lastDigZ = null;
142 public Integer lastDigFace = null;
143
144
145 public void a() {
146 this.i = false;
147 this.networkManager.b();
148
149 if (this.f - this.g > 20) {
150 this.sendPacket(new Packet0KeepAlive());
151 }
152
153 // uberbukkit - play breaking sound & animation for others
154 if (this.mineExpire >= System.currentTimeMillis()) {
155 if (this.lastMine + 200L < System.currentTimeMillis()) {
156 return;
157 }
158
159 if (this.networkManager.pvn < 9) return;
160
161 delaySound++;
162 if (delaySound % 4 != 0) return;
163
164 // prevent overflow (lol)
165 delaySound = 0;
166
167 int id = this.player.world.getTypeId(lastDigX, lastDigY, lastDigZ);
168 if (id == 0) return;
169
170 Block block = Block.byId[id];
171
172 float vol1 = (block.stepSound.getVolume1() + 1.0F) / 8.0F;
173 this.minecraftServer.serverConfigurationManager.sendPacketNearbyToScale(this.player, (double) lastDigX + 0.5D, (double) lastDigY + 0.5D, (double) lastDigZ + 0.5D, vol1, ((WorldServer) this.player.world).dimension, new Packet62Sound(block.stepSound.getName(), (double) lastDigX + 0.5D, (double) lastDigY + 0.5D, (double) lastDigZ + 0.5D, vol1, block.stepSound.getVolume2() * 0.5F));
174
175 if (lastDigFace != null) {
176 float progress = block.getDamage(this.player) * (float) (this.player.itemInWorldManager.getCurrentMagic() + 1);
177 if (progress > 1.0F) {
178 progress = 1.0F;
179 }
180
181 this.minecraftServer.serverConfigurationManager.sendPacketNearby(player, lastDigX, lastDigY, lastDigZ, 64D, player.dimension, new Packet63Digging(lastDigX, lastDigY, lastDigZ, lastDigFace, progress));
182 }
183 }
184 }
185
186 public void disconnect(String s) {
187 if (disconnected) return; // Poseidon: Kick/Disconnect spam fix
188
189 // CraftBukkit start
190 String leaveMessage = this.msgPlayerLeave.replace("%player%", this.player.name);
191
192 PlayerKickEvent event = new PlayerKickEvent(this.server.getPlayer(this.player), s, leaveMessage);
193 this.server.getPluginManager().callEvent(event);
194
195 if (event.isCancelled()) {
196 // Do not kick the player
197 return;
198 }
199 // Send the possibly modified leave message
200 s = event.getReason();
201 // CraftBukkit end
202
203 this.player.B();
204 this.sendPacket(new Packet255KickDisconnect(s));
205 this.networkManager.d();
206
207 // CraftBukkit start
208 leaveMessage = event.getLeaveMessage();
209 if (leaveMessage != null) {
210 this.minecraftServer.serverConfigurationManager.sendAll(new Packet3Chat(leaveMessage));
211 }
212 // CraftBukkit end
213
214 this.minecraftServer.serverConfigurationManager.disconnect(this.player);
215 this.disconnected = true;
216 }
217
218 // uberbukkit
219 public void a(Packet5EntityEquipment packet5) {
220 if (this.networkManager.pvn > 6) return;
221
222 this.player.packet5.process(packet5);
223 }
224
225 public void a(Packet27 packet27) {
226 // poseidon
227 PacketReceivedEvent event = new PacketReceivedEvent(server.getPlayer(player), packet27);
228 server.getPluginManager().callEvent(event);
229 if (event.isCancelled()) return;
230
231 this.player.a(packet27.c(), packet27.e(), packet27.g(), packet27.h(), packet27.d(), packet27.f());
232 }
233
234 public void a(Packet10Flying packet10flying) {
235 // poseidon
236 PacketReceivedEvent pevent = new PacketReceivedEvent(server.getPlayer(player), packet10flying);
237 server.getPluginManager().callEvent(pevent);
238 if (pevent.isCancelled()) return;
239
240 WorldServer worldserver = this.minecraftServer.getWorldServer(this.player.dimension);
241
242 this.i = true;
243 double d0;
244
245 if (!this.checkMovement) {
246 d0 = packet10flying.y - this.y;
247 if (packet10flying.x == this.x && d0 * d0 < 0.01D && packet10flying.z == this.z) {
248 this.checkMovement = true;
249 }
250 }
251
252 // CraftBukkit start
253 Player player = this.getPlayer();
254 Location from = new Location(player.getWorld(), lastPosX, lastPosY, lastPosZ, lastYaw, lastPitch); // Get the Players previous Event location.
255 Location to = player.getLocation().clone(); // Start off the To location as the Players current location.
256
257 // If the packet contains movement information then we update the To location with the correct XYZ.
258 if (packet10flying.h && !(packet10flying.h && packet10flying.y == -999.0D && packet10flying.stance == -999.0D)) {
259 to.setX(packet10flying.x);
260 to.setY(packet10flying.y);
261 to.setZ(packet10flying.z);
262 }
263
264 // If the packet contains look information then we update the To location with the correct Yaw & Pitch.
265 if (packet10flying.hasLook && Patches.HEAD_ROTATION.check(this.player, packet10flying.yaw, packet10flying.pitch)) {
266 to.setYaw(packet10flying.yaw);
267 to.setPitch(packet10flying.pitch);
268 }
269
270 // Prevent 40 event-calls for less than a single pixel of movement >.>
271 double delta = Math.pow(this.lastPosX - to.getX(), 2) + Math.pow(this.lastPosY - to.getY(), 2) + Math.pow(this.lastPosZ - to.getZ(), 2);
272 float deltaAngle = Math.abs(this.lastYaw - to.getYaw()) + Math.abs(this.lastPitch - to.getPitch());
273
274 if ((delta > 1f / 256 || deltaAngle > 10f) && (this.checkMovement && !this.player.dead)) {
275 this.player.isInWorkbench = false; // uberbukkit - cancel workbench status when player moves
276 this.lastPosX = to.getX();
277 this.lastPosY = to.getY();
278 this.lastPosZ = to.getZ();
279 this.lastYaw = to.getYaw();
280 this.lastPitch = to.getPitch();
281
282 // Skip the first time we do this
283 if (from.getX() != Double.MAX_VALUE) {
284 PlayerMoveEvent event = new PlayerMoveEvent(player, from, to);
285 this.server.getPluginManager().callEvent(event);
286
287 // If the event is cancelled we move the player back to their old location.
288 if (event.isCancelled()) {
289 this.player.netServerHandler.sendPacket(new Packet13PlayerLookMove(from.getX(), from.getY() + 1.6200000047683716D, from.getY(), from.getZ(), from.getYaw(), from.getPitch(), false));
290 return;
291 }
292
293 /* If a Plugin has changed the To destination then we teleport the Player
294 there to avoid any 'Moved wrongly' or 'Moved too quickly' errors.
295 We only do this if the Event was not cancelled. */
296 if (!to.equals(event.getTo())) {
297 this.player.getBukkitEntity().teleport(event.getTo());
298 return;
299 }
300
301 /* Check to see if the Players Location has somehow changed during the call of the event.
302 This can happen due to a plugin teleporting the player instead of using .setTo() */
303 if (!from.equals(this.getPlayer().getLocation()) && this.justTeleported) {
304 this.justTeleported = false;
305 return;
306 }
307 }
308 }
309
310 if (Double.isNaN(packet10flying.x) || Double.isNaN(packet10flying.y) || Double.isNaN(packet10flying.z) || Double.isNaN(packet10flying.stance) && player.isOnline() && !disconnected) {
311 player.teleport(player.getWorld().getSpawnLocation());
312 System.err.println(player.getName() + " was caught trying to crash the server with an invalid position.");
313 player.kickPlayer("Nope!");
314 return;
315 }
316
317 if (this.checkMovement && !this.player.dead) {
318 // CraftBukkit end
319 double d1;
320 double d2;
321 double d3;
322 double d4;
323
324 if (this.player.vehicle != null) {
325 float f = this.player.yaw;
326 float f1 = this.player.pitch;
327
328 this.player.vehicle.f();
329 d1 = this.player.locX;
330 d2 = this.player.locY;
331 d3 = this.player.locZ;
332 double d5 = 0.0D;
333
334 d4 = 0.0D;
335 if (packet10flying.hasLook) {
336 f = packet10flying.yaw;
337 f1 = packet10flying.pitch;
338 }
339
340 if (packet10flying.h && packet10flying.y == -999.0D && packet10flying.stance == -999.0D) {
341 d5 = packet10flying.x;
342 d4 = packet10flying.z;
343
344 // Project Poseidon - Start
345 // Boat crash fix ported from UberBukkit
346
347 double d8 = d5 * d5 + d4 * d4;
348 if (d8 > 100.0D) {
349 a.warning("[Poseidon]" + this.player.name + " tried crashing server on entity " + this.player.vehicle.toString() + ". They have been kicked.");
350 player.kickPlayer("Boat crash attempt detected!");
351 return;
352 }
353
354 // Project Poseidon - End
355
356 }
357
358 this.player.onGround = packet10flying.g;
359 this.player.a(true);
360 this.player.move(d5, 0.0D, d4);
361 this.player.setLocation(d1, d2, d3, f, f1);
362 this.player.motX = d5;
363 this.player.motZ = d4;
364 if (this.player.vehicle != null) {
365 worldserver.vehicleEnteredWorld(this.player.vehicle, true);
366 }
367
368 if (this.player.vehicle != null) {
369 this.player.vehicle.f();
370 this.player.vehicle.airBorne = true;
371 }
372
373 this.minecraftServer.serverConfigurationManager.d(this.player);
374 this.x = this.player.locX;
375 this.y = this.player.locY;
376 this.z = this.player.locZ;
377 worldserver.playerJoinedWorld(this.player);
378 return;
379 }
380
381 if (this.player.isSleeping()) {
382 this.player.a(true);
383 this.player.setLocation(this.x, this.y, this.z, this.player.yaw, this.player.pitch);
384 worldserver.playerJoinedWorld(this.player);
385 return;
386 }
387
388 d0 = this.player.locY;
389 this.x = this.player.locX;
390 this.y = this.player.locY;
391 this.z = this.player.locZ;
392 d1 = this.player.locX;
393 d2 = this.player.locY;
394 d3 = this.player.locZ;
395 float f2 = this.player.yaw;
396 float f3 = this.player.pitch;
397
398 if (packet10flying.h && packet10flying.y == -999.0D && packet10flying.stance == -999.0D) {
399 packet10flying.h = false;
400 }
401
402 if (packet10flying.h) {
403 d1 = packet10flying.x;
404 d2 = packet10flying.y;
405 d3 = packet10flying.z;
406 d4 = packet10flying.stance - packet10flying.y;
407 if (!this.player.isSleeping() && (d4 > 1.65D || d4 < 0.1D)) {
408 this.disconnect("Illegal stance");
409 a.warning(this.player.name + " had an illegal stance: " + d4);
410 return;
411 }
412
413 if (Math.abs(packet10flying.x) > 3.2E7D || Math.abs(packet10flying.z) > 3.2E7D) {
414 this.disconnect("Illegal position");
415 return;
416 }
417 }
418
419 if (packet10flying.hasLook) {
420 f2 = packet10flying.yaw;
421 f3 = packet10flying.pitch;
422 }
423
424 this.player.a(true);
425 this.player.br = 0.0F;
426 this.player.setLocation(this.x, this.y, this.z, f2, f3);
427 if (!this.checkMovement) {
428 return;
429 }
430
431 d4 = d1 - this.player.locX;
432 double d6 = d2 - this.player.locY;
433 double d7 = d3 - this.player.locZ;
434 double d14 = this.player.motX * this.player.motX + this.player.motY * this.player.motY + this.player.motZ * this.player.motZ;
435 double d8 = d4 * d4 + d6 * d6 + d7 * d7;
436
437 if ((boolean) PoseidonConfig.getInstance().getConfigOption("world.settings.speed-hack-check.enabled", true)) {
438 if (d8 - d14 > (double) PoseidonConfig.getInstance().getConfigOption("world.settings.speed-hack-check.distance", 100.0D) && this.checkMovement) { // CraftBukkit - Added this.checkMovement condition to solve this check being triggered by teleports
439 a.warning(this.player.name + " moved too quickly! " + d4 + "," + d6 + "," + d7 + " (" + d4 + ", " + d6 + ", " + d7 + ")");
440 if ((boolean) PoseidonConfig.getInstance().getConfigOption("world.settings.speed-hack-check.teleport", true)) {
441 this.a(this.x, this.y, this.z, this.player.yaw, this.player.pitch);
442 } else {
443 this.disconnect("You moved too quickly :( (Hacking?)");
444 }
445 return;
446 }
447 }
448
449 float f4 = 0.0625F;
450 boolean flag = worldserver.getEntities(this.player, this.player.boundingBox.clone().shrink((double) f4, (double) f4, (double) f4)).size() == 0;
451
452 this.player.move(d4, d6, d7);
453 d4 = d1 - this.player.locX;
454 d6 = d2 - this.player.locY;
455 if (d6 > -0.5D || d6 < 0.5D) {
456 d6 = 0.0D;
457 }
458
459 d7 = d3 - this.player.locZ;
460 d8 = d4 * d4 + d6 * d6 + d7 * d7;
461 boolean flag1 = false;
462
463 if (d8 > 0.0625D && !this.player.isSleeping()) {
464 flag1 = true;
465 a.warning(this.player.name + " moved wrongly!");
466 System.out.println("Got position " + d1 + ", " + d2 + ", " + d3);
467 System.out.println("Expected " + this.player.locX + ", " + this.player.locY + ", " + this.player.locZ);
468 }
469
470 this.player.setLocation(d1, d2, d3, f2, f3);
471 boolean flag2 = worldserver.getEntities(this.player, this.player.boundingBox.clone().shrink((double) f4, (double) f4, (double) f4)).size() == 0;
472
473 if (flag && (flag1 || !flag2) && !this.player.isSleeping()) {
474 this.a(this.x, this.y, this.z, f2, f3);
475 return;
476 }
477
478 AxisAlignedBB axisalignedbb = this.player.boundingBox.clone().b((double) f4, (double) f4, (double) f4).a(0.0D, -0.55D, 0.0D);
479
480 // uberbukkit
481 boolean bool = false;
482 if (isStaffExemptFromFlyKick) {
483 Player bukkitPlayer = (Player) this.player.getBukkitEntity();
484 bool = bukkitPlayer.isOp() || bukkitPlayer.hasPermission("uberbukkit.fly");
485 }
486
487 if (!this.minecraftServer.allowFlight && !worldserver.b(axisalignedbb) && !bool) {
488 if (d6 >= -0.03125D) {
489 ++this.h;
490 if (this.h > 80) {
491 a.warning(this.player.name + " was kicked for floating too long!");
492 this.disconnect("Flying is not enabled on this server");
493 return;
494 }
495 }
496 } else {
497 this.h = 0;
498 }
499
500 this.player.onGround = packet10flying.g;
501 this.minecraftServer.serverConfigurationManager.d(this.player);
502 this.player.b(this.player.locY - d0, packet10flying.g);
503 }
504 }
505
506 public void a(double d0, double d1, double d2, float f, float f1) {
507 // CraftBukkit start - Delegate to teleport(Location)
508 Player player = this.getPlayer();
509 Location from = player.getLocation();
510 Location to = new Location(this.getPlayer().getWorld(), d0, d1, d2, f, f1);
511 PlayerTeleportEvent event = new PlayerTeleportEvent(player, from, to);
512 this.server.getPluginManager().callEvent(event);
513
514 from = event.getFrom();
515 to = event.isCancelled() ? from : event.getTo();
516
517 this.teleport(to);
518 }
519
520 public void teleport(Location dest) {
521 double d0, d1, d2;
522 float f, f1;
523
524 d0 = dest.getX();
525 d1 = dest.getY();
526 d2 = dest.getZ();
527 f = dest.getYaw();
528 f1 = dest.getPitch();
529
530 // TODO: make sure this is the best way to address this.
531 if (Float.isNaN(f)) {
532 f = 0;
533 }
534
535 if (Float.isNaN(f1)) {
536 f1 = 0;
537 }
538
539 this.lastPosX = d0;
540 this.lastPosY = d1;
541 this.lastPosZ = d2;
542 this.lastYaw = f;
543 this.lastPitch = f1;
544 this.justTeleported = true;
545 // CraftBukkit end
546
547 this.checkMovement = false;
548 this.x = d0;
549 this.y = d1;
550 this.z = d2;
551 this.player.setLocation(d0, d1, d2, f, f1);
552 this.player.netServerHandler.sendPacket(new Packet13PlayerLookMove(d0, d1 + 1.6200000047683716D, d1, d2, f, f1, false));
553 }
554
555 // uberbukkit
556 public void a(Packet21PickupSpawn packet21) {
557 // copy from craftbukkit
558 if (this.lastDropTick != MinecraftServer.currentTick) {
559 this.dropCount = 0;
560 this.lastDropTick = MinecraftServer.currentTick;
561 } else {
562 // Else we increment the drop count and check the amount.
563 this.dropCount++;
564 if (this.dropCount >= 20) {
565 a.warning(this.player.name + " dropped their items too quickly!");
566 this.disconnect("You dropped your items too quickly (Hacking?)");
567 }
568 }
569 // drop itemstack
570 ItemStack hand = this.player.inventory.items[this.player.inventory.itemInHandIndex];
571 ItemStack todrop = null;
572
573 if (hand != null && hand.id == packet21.h && hand.count >= packet21.i && packet21.i == 1) {
574 todrop = hand.cloneItemStack();
575 todrop.count = packet21.i;
576 hand.count -= packet21.i;
577 } else {
578 ArrayList<ItemStack> list = this.player.packet5.queue.getQueue();
579 for (ItemStack stack : list) {
580 if (stack.id == packet21.h && stack.count >= packet21.i) {
581 todrop = stack.cloneItemStack();
582 todrop.count = packet21.i;
583 this.player.packet5.queue.removeStackFromQueue(todrop);
584 break;
585 }
586 }
587 }
588 this.player.a(todrop, false);
589 //this.player.F();
590 }
591
592 public long mineExpire = 0;
593 public long lastMine = 0;
594 public int delaySound = 0;
595
596 public void a(Packet14BlockDig packet14blockdig) {
597 // poseidon
598 PacketReceivedEvent event = new PacketReceivedEvent(server.getPlayer(player), packet14blockdig);
599 server.getPluginManager().callEvent(event);
600 if (event.isCancelled()) return;
601
602 if (this.player.dead) return; // CraftBukkit
603
604 WorldServer worldserver = this.minecraftServer.getWorldServer(this.player.dimension);
605
606 if (packet14blockdig.e == 4) {
607 // CraftBukkit start
608 // If the ticks aren't the same then the count starts from 0 and we update the lastDropTick.
609 if (this.lastDropTick != MinecraftServer.currentTick) {
610 this.dropCount = 0;
611 this.lastDropTick = MinecraftServer.currentTick;
612 } else {
613 // Else we increment the drop count and check the amount.
614 this.dropCount++;
615 if (this.dropCount >= 20) {
616 a.warning(this.player.name + " dropped their items too quickly!");
617 this.disconnect("You dropped your items too quickly (Hacking?)");
618 }
619 }
620 // CraftBukkit end
621 this.player.F();
622 } else {
623 boolean flag = worldserver.weirdIsOpCache = worldserver.dimension != 0 || this.minecraftServer.serverConfigurationManager.isOp(this.player.name); // CraftBukkit
624 boolean flag1 = false;
625
626 // uberbukkit
627
628 // Pre-b1.3 block handling
629 // e == 2 is stop digging (holds no block coordinate data)
630 // e == 3 is expected block break from client
631 // e == 1 is digging
632 // e == 0 is start digging, or digging every 5 packets (notch is weird)
633
634 // Post-b1.2_01 block handling
635 // e == 2 is stop digging
636 // e == 0 is start digging
637 Integer i = packet14blockdig.a;
638 Integer j = packet14blockdig.b;
639 Integer k = packet14blockdig.c;
640
641 if (packet14blockdig.e == 0) {
642 flag1 = true;
643 }
644
645 if (packet14blockdig.e == 1 && this.networkManager.pvn <= 8) {
646 flag1 = true;
647 }
648
649 if (packet14blockdig.e == 2 && this.networkManager.pvn >= 9) {
650 flag1 = true;
651 }
652
653 if (flag1) {
654 double d0 = this.player.locX - ((double) i + 0.5D);
655 double d1 = this.player.locY - ((double) j + 0.5D);
656 double d2 = this.player.locZ - ((double) k + 0.5D);
657 double d3 = d0 * d0 + d1 * d1 + d2 * d2;
658
659 if (d3 > 36.0D) {
660 return;
661 }
662 }
663
664 ChunkCoordinates chunkcoordinates = worldserver.getSpawn();
665 int l = (int) MathHelper.abs((float) (i - chunkcoordinates.x));
666 int i1 = (int) MathHelper.abs((float) (k - chunkcoordinates.z));
667
668 if (l > i1) {
669 i1 = l;
670 }
671
672 if (this.networkManager.pvn <= 8) {
673 // CraftBukkit start
674 CraftPlayer player = getPlayer();
675 CraftBlock block = (CraftBlock) player.getWorld().getBlockAt(i, j, k);
676 int blockId = block.getTypeId();
677 float damage = 0;
678 if (Block.byId[blockId] != null) {
679 damage = Block.byId[blockId].getDamage(player.getHandle()); //Get amount of damage going to block
680 }
681 // CraftBukkit end
682
683 if (packet14blockdig.e == 0) {
684 // CraftBukkit start
685 if (i1 > this.server.getSpawnRadius() || flag) {
686 if (blockId > 0) {
687 BlockDamageEvent breakEvent;
688 // If the amount of damage that the player is going to do to the block
689 // is >= 1, then the block is going to break (eg, flowers, torches)
690 if (damage >= 1.0F) {
691 // if we are destroying either a redstone wire with a current greater than 0 or
692 // a redstone torch that is on, then we should notify plugins that this block has
693 // returned to a current value of 0 (since it will once the redstone is destroyed)
694 if ((blockId == Block.REDSTONE_WIRE.id && block.getData() > 0) || blockId == Block.REDSTONE_TORCH_ON.id) {
695 server.getPluginManager().callEvent(new BlockRedstoneEvent(block, (blockId == Block.REDSTONE_WIRE.id ? block.getData() : 15), 0));
696 }
697 breakEvent = new BlockDamageEvent(player, block, player.getItemInHand(), true);
698 } else {
699 breakEvent = new BlockDamageEvent(player, block, player.getItemInHand(), false);
700 }
701 server.getPluginManager().callEvent(breakEvent);
702 if (!breakEvent.isCancelled()) {
703 this.player.itemInWorldManager.oldClick(i, j, k, packet14blockdig.face);
704
705 this.lastDigFace = packet14blockdig.face; // uberbukkit - handle digging
706 }
707 }
708 }
709 // CraftBukkit end
710 } else if (packet14blockdig.e == 2) {
711 // CraftBukkit start - Get last block that the player hit
712 // Otherwise the block is a Bedrock @(0,0,0)
713 block = (CraftBlock) player.getWorld().getBlockAt(lastDigX, lastDigY, lastDigZ);
714 BlockDamageEvent breakEvent = new BlockDamageEvent(player, block, player.getItemInHand(), damage >= 1.0F);
715 server.getPluginManager().callEvent(breakEvent);
716 if (!breakEvent.isCancelled()) {
717 this.player.itemInWorldManager.oldHaltBreak();
718 }
719 // CraftBukkit end
720 } else if (packet14blockdig.e == 1) {
721 // CraftBukkit start
722 if (i1 > this.server.getSpawnRadius() || flag) {
723 BlockDamageEvent breakEvent;
724 // If the amount of damage going to the block plus the current amount
725 // of damage is greater than 1, the block is going to break.
726 if (this.player.itemInWorldManager.damageDealt + damage >= 1.0F) {
727 // if we are destroying either a redstone wire with a current greater than 0 or
728 // a redstone torch that is on, then we should notify plugins that this block has
729 // returned to a current value of 0 (since it will once the redstone is destroyed)
730 if ((blockId == Block.REDSTONE_WIRE.id && block.getData() > 0) || blockId == Block.REDSTONE_TORCH_ON.id) {
731 server.getPluginManager().callEvent(new BlockRedstoneEvent(block, (blockId == Block.REDSTONE_WIRE.id ? block.getData() : 15), 0));
732 }
733 breakEvent = new BlockDamageEvent(player, block, player.getItemInHand(), damage >= 1.0F);
734 } else {
735 breakEvent = new BlockDamageEvent(player, block, player.getItemInHand(), damage >= 1.0F);
736 }
737 server.getPluginManager().callEvent(breakEvent);
738 if (!breakEvent.isCancelled()) {
739 this.player.itemInWorldManager.oldDig(i, j, k, packet14blockdig.face);
740
741 this.lastDigFace = packet14blockdig.face; // uberbukkit - handle digging
742 } else {
743 this.player.itemInWorldManager.damageDealt = 0; // Reset the amount of damage if stopping break.
744 }
745 }
746 // CraftBukkit end
747 } else if (packet14blockdig.e == 3) {
748 double d5 = this.player.locX - ((double) i + 0.5D);
749 double d6 = this.player.locY - ((double) j + 0.5D);
750 double d7 = this.player.locZ - ((double) k + 0.5D);
751 double d8 = d5 * d5 + d6 * d6 + d7 * d7;
752
753 if (d8 < 256.0D) {
754 this.player.netServerHandler.sendPacket((Packet) (new Packet53BlockChange(i, j, k, this.player.world))); // Craftbukkit
755 }
756 }
757 } else {
758 if (packet14blockdig.e == 0) {
759 // CraftBukkit
760 if (i1 < this.server.getSpawnRadius() && !flag) {
761 this.player.netServerHandler.sendPacket(new Packet53BlockChange(i, j, k, worldserver));
762 } else {
763 // CraftBukkit - add face argument
764 this.player.itemInWorldManager.dig(i, j, k, packet14blockdig.face);
765
766 // uberbukkit - handle digging
767 this.mineExpire = this.player.itemInWorldManager.getExpectedDigEnd();
768 this.lastDigFace = packet14blockdig.face;
769 }
770 } else if (packet14blockdig.e == 2) {
771 // uberbukkit - swapped i,j,k for lastDigX,lastDigY,lastDigZ
772 this.player.itemInWorldManager.a(lastDigX, lastDigY, lastDigZ);
773
774 // uberbukkit - handle digging
775 this.mineExpire = 0;
776 this.lastMine = 0;
777
778 if (worldserver.getTypeId(lastDigX, lastDigY, lastDigZ) != 0) {
779 this.player.netServerHandler.sendPacket(new Packet53BlockChange(lastDigX, lastDigY, lastDigZ, worldserver));
780 }
781 } else if (packet14blockdig.e == 3) {
782 double d4 = this.player.locX - ((double) i + 0.5D);
783 double d5 = this.player.locY - ((double) j + 0.5D);
784 double d6 = this.player.locZ - ((double) k + 0.5D);
785 double d7 = d4 * d4 + d5 * d5 + d6 * d6;
786
787 if (d7 < 256.0D) {
788 this.player.netServerHandler.sendPacket(new Packet53BlockChange(i, j, k, worldserver));
789 }
790 }
791 }
792
793 // uberbukkit - reset last positions when stops digging
794 lastDigX = i;
795 lastDigY = j;
796 lastDigZ = k;
797
798 worldserver.weirdIsOpCache = false;
799 }
800 }
801
802 public void a(Packet15Place packet15place) {
803// System.out.println("Packet15 received");
804// System.out.println("a: " + packet15place.a);
805// System.out.println("b: " + packet15place.b);
806// System.out.println("c: " + packet15place.c);
807// System.out.println("face: " + packet15place.face);
808// System.out.println("data: " + packet15place.data);
809 // poseidon
810 PacketReceivedEvent pevent = new PacketReceivedEvent(server.getPlayer(player), packet15place);
811 server.getPluginManager().callEvent(pevent);
812 if (pevent.isCancelled()) return;
813
814 WorldServer worldserver = this.minecraftServer.getWorldServer(this.player.dimension);
815
816 // CraftBukkit start
817 if (this.player.dead) return;
818
819 // uberbukkit: noptch what the fuck have you done
820 if (this.networkManager.pvn == 7) {
821 if (packet15place.itemstack != null && packet15place.a != -1 && packet15place.b != 255 && packet15place.c != -1 && (packet15place.itemstack.id == Item.BUCKET.id || packet15place.itemstack.id == Item.WATER_BUCKET.id || packet15place.itemstack.id == Item.LAVA_BUCKET.id || packet15place.itemstack.id == Item.MILK_BUCKET.id)) {
822 return;
823 }
824 }
825
826 // This is a horrible hack needed because the client sends 2 packets on 'right mouse click'
827 // aimed at a block. We shouldn't need to get the second packet if the data is handled
828 // but we cannot know what the client will do, so we might still get it
829 //
830 // If the time between packets is small enough, and the 'signature' similar, we discard the
831 // second one. This sadly has to remain until Mojang makes their packets saner. :(
832 // -- Grum
833
834 if (packet15place.face == 255) {
835 if (packet15place.itemstack != null && packet15place.itemstack.id == this.lastMaterial && this.lastPacket != null && packet15place.timestamp - this.lastPacket < 100) {
836 this.lastPacket = null;
837 return;
838 }
839 } else {
840 this.lastMaterial = packet15place.itemstack == null ? -1 : packet15place.itemstack.id;
841 this.lastPacket = packet15place.timestamp;
842 }
843
844 // CraftBukkit - if rightclick decremented the item, always send the update packet.
845 // this is not here for CraftBukkit's own functionality; rather it is to fix
846 // a notch bug where the item doesn't update correctly.
847 boolean always = false;
848
849 // CraftBukkit end
850
851 ItemStack itemstack = this.player.inventory.getItemInHand();
852 boolean flag = worldserver.weirdIsOpCache = worldserver.dimension != 0 || this.minecraftServer.serverConfigurationManager.isOp(this.player.name); // CraftBukkit
853
854 if (packet15place.face == 255) {
855 if (itemstack == null) {
856 return;
857 }
858
859 // CraftBukkit start
860 int itemstackAmount = itemstack.count;
861 PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(this.player, Action.RIGHT_CLICK_AIR, itemstack);
862 if (event.useItemInHand() != Event.Result.DENY) {
863 this.player.itemInWorldManager.useItem(this.player, this.player.world, itemstack);
864 }
865
866 // CraftBukkit - notch decrements the counter by 1 in the above method with food,
867 // snowballs and so forth, but he does it in a place that doesn't cause the
868 // inventory update packet to get sent
869 always = (itemstack.count != itemstackAmount);
870 // CraftBukkit end
871 } else {
872 int i = packet15place.a;
873 int j = packet15place.b;
874 int k = packet15place.c;
875 int l = packet15place.face;
876 ChunkCoordinates chunkcoordinates = worldserver.getSpawn();
877 int i1 = (int) MathHelper.abs((float) (i - chunkcoordinates.x));
878 int j1 = (int) MathHelper.abs((float) (k - chunkcoordinates.z));
879
880 if (i1 > j1) {
881 j1 = i1;
882 }
883
884 // CraftBukkit start - Check if we can actually do something over this large a distance
885 Location eyeLoc = this.getPlayer().getEyeLocation();
886 if (Math.pow(eyeLoc.getX() - i, 2) + Math.pow(eyeLoc.getY() - j, 2) + Math.pow(eyeLoc.getZ() - k, 2) > PLACE_DISTANCE_SQUARED) {
887 return;
888 }
889 flag = true; // spawn protection moved to ItemBlock!!!
890 // CraftBukkit end
891
892 if (j1 > 16 || flag) {
893 this.player.itemInWorldManager.interact(this.player, worldserver, itemstack, i, j, k, l);
894 }
895
896 this.player.netServerHandler.sendPacket(new Packet53BlockChange(i, j, k, worldserver));
897 if (l == 0) {
898 --j;
899 }
900
901 if (l == 1) {
902 ++j;
903 }
904
905 if (l == 2) {
906 --k;
907 }
908
909 if (l == 3) {
910 ++k;
911 }
912
913 if (l == 4) {
914 --i;
915 }
916
917 if (l == 5) {
918 ++i;
919 }
920
921 this.player.netServerHandler.sendPacket(new Packet53BlockChange(i, j, k, worldserver));
922 }
923
924 itemstack = this.player.inventory.getItemInHand();
925 if (itemstack != null && itemstack.count == 0) {
926 this.player.inventory.items[this.player.inventory.itemInHandIndex] = null;
927 }
928
929 this.player.h = true;
930 this.player.inventory.items[this.player.inventory.itemInHandIndex] = ItemStack.b(this.player.inventory.items[this.player.inventory.itemInHandIndex]);
931 Slot slot = this.player.activeContainer.a(this.player.inventory, this.player.inventory.itemInHandIndex);
932
933 this.player.activeContainer.a();
934 this.player.h = false;
935 // CraftBukkit
936 if (!ItemStack.equals(this.player.inventory.getItemInHand(), packet15place.itemstack) || always) {
937 if (this.networkManager.pvn <= 6) {
938 this.refreshInventory();
939 } else {
940 this.sendPacket(new Packet103SetSlot(this.player.activeContainer.windowId, slot.a, this.player.inventory.getItemInHand()));
941 }
942 }
943
944 worldserver.weirdIsOpCache = false;
945 }
946
947 // uberbukkit
948 public void refreshInventory() {
949 this.sendPacket(new Packet5EntityEquipment(-1, this.player.inventory.items));
950 this.sendPacket(new Packet5EntityEquipment(-2, this.player.inventory.craft));
951 this.sendPacket(new Packet5EntityEquipment(-3, this.player.inventory.armor));
952 }
953
954 public void a(String s, Object[] aobject) {
955 if (this.disconnected) return; // CraftBukkit - rarely it would send a disconnect line twice
956
957
958 if (!(boolean) PoseidonConfig.getInstance().getConfigOption("settings.remove-join-leave-debug", true) || !s.equals("disconnect.quitting")) {
959 a.info(this.player.name + " lost connection: " + s);
960 }
961
962 a.info(this.player.name + " has left the game.");
963 // CraftBukkit start - we need to handle custom quit messages
964 String quitMessage = this.minecraftServer.serverConfigurationManager.disconnect(this.player);
965 if (quitMessage != null) {
966 this.minecraftServer.serverConfigurationManager.sendAll(new Packet3Chat(quitMessage));
967 }
968 // CraftBukkit end
969 this.disconnected = true;
970 }
971
972 public void a(Packet packet) {
973 a.warning(this.getClass() + " wasn\'t prepared to deal with a " + packet.getClass());
974 this.disconnect("Protocol error, unexpected packet");
975 }
976
977 public void sendPacket(Packet packet) {
978 //Poseidon Start - Send Packet Event
979 if (packet == null) // Why do anything if there's no packet? (fixes Internal server error)
980 return;
981
982 if (firePacketEvents) {
983 PlayerSendPacketEvent event = new PlayerSendPacketEvent(this.player.name, packet);
984 Bukkit.getPluginManager().callEvent(event);
985 if (event.isCancelled()) {
986 return;
987 }
988 packet = event.getPacket(); //In case a plugin replaces the entire packet
989 }
990 //Poseidon End
991
992 // UberBukkit
993 PacketSentEvent packetSentEvent = new PacketSentEvent(getPlayer(), packet);
994 Bukkit.getPluginManager().callEvent(packetSentEvent);
995 if (packetSentEvent.isCancelled()) {
996 return;
997 }
998 packet = packetSentEvent.getPacket();
999
1000 Protocol protocol = this.player.protocol;
1001 if (!protocol.canReceivePacket(packet.b())) {
1002 this.g = this.f;
1003 return;
1004 }
1005
1006 // uberbukkit - try to disallow for incompatible blocks and packets
1007 if (packet instanceof Packet5EntityEquipment) {
1008 Packet5EntityEquipment packet5 = (Packet5EntityEquipment) packet;
1009
1010 // don't send entity equipment data to pre-b1.0 clients
1011 // (they use packet 5 for inventory data)
1012 if (packet5.items == null && this.networkManager.pvn < 7) {
1013 this.g = this.f;
1014 return;
1015 }
1016
1017 if (packet5.c > 0 && !protocol.canReceiveBlockItem(packet5.c)) {
1018 this.networkManager.queue(new Packet5EntityEquipment(packet5.a, packet5.b, null));
1019 packet = null;
1020 }
1021 } else if (packet instanceof Packet53BlockChange) {
1022 Packet53BlockChange packet53 = (Packet53BlockChange) packet;
1023 if (!protocol.canReceiveBlockItem(packet53.material)) {
1024 this.networkManager.queue(new Packet53BlockChange(packet53.a, packet53.b, packet53.c, 1, packet53.data));
1025 packet = null;
1026 }
1027 } else if (packet instanceof Packet18ArmAnimation) {
1028 Packet18ArmAnimation packet18 = (Packet18ArmAnimation) packet;
1029
1030 // skip riding/burning/sneaking packets for a1.1.2_01
1031 if (this.networkManager.pvn <= 2 && packet18.b >= 100) {
1032 this.g = this.f;
1033 return;
1034 }
1035 }
1036
1037 // CraftBukkit start
1038 else if (packet instanceof Packet6SpawnPosition) {
1039 Packet6SpawnPosition packet6 = (Packet6SpawnPosition) packet;
1040 this.player.compassTarget = new Location(this.getPlayer().getWorld(), packet6.x, packet6.y, packet6.z);
1041 } else if (packet instanceof Packet3Chat) {
1042 String message = ((Packet3Chat) packet).message;
1043 // uberbukkit
1044 String[] wrapped = null;
1045 if (this.networkManager.pvn >= 9) { // TODO check compatibility
1046 wrapped = TextWrapper.wrapText(message);
1047 } else {
1048 wrapped = TextWrapper.wrapTextLegacy(message);
1049 }
1050
1051 for (final String line : wrapped) {
1052 this.networkManager.queue(new Packet3Chat(line));
1053 }
1054 packet = null;
1055 } else if (packet.k == true) {
1056 // Reroute all low-priority packets through to compression thread.
1057 ChunkCompressionThread.sendPacket(this.player, packet);
1058 packet = null;
1059 }
1060 if (packet != null) this.networkManager.queue(packet);
1061 // CraftBukkit end
1062
1063 this.g = this.f;
1064 }
1065
1066 public void a(Packet16BlockItemSwitch packet16blockitemswitch) {
1067 // poseidon
1068 PacketReceivedEvent pevent = new PacketReceivedEvent(server.getPlayer(player), packet16blockitemswitch);
1069 server.getPluginManager().callEvent(pevent);
1070 if (pevent.isCancelled()) return;
1071
1072 if (this.player.dead) return; // CraftBukkit
1073
1074 if (this.networkManager.pvn >= 7) {
1075 if (packet16blockitemswitch.itemInHandIndex >= 0 && packet16blockitemswitch.itemInHandIndex <= InventoryPlayer.e()) {
1076 // CraftBukkit start
1077 PlayerItemHeldEvent event = new PlayerItemHeldEvent(this.getPlayer(), this.player.inventory.itemInHandIndex, packet16blockitemswitch.itemInHandIndex);
1078 this.server.getPluginManager().callEvent(event);
1079 // CraftBukkit end
1080
1081 this.player.inventory.itemInHandIndex = packet16blockitemswitch.itemInHandIndex;
1082 } else {
1083 a.warning(this.player.name + " tried to set an invalid carried item");
1084 this.disconnect("Invalid hotbar selection (Hacking?)");
1085 }
1086 } else {
1087
1088 for (int i = 0; i < 9; i++) {
1089 ItemStack stack = this.player.inventory.items[i];
1090
1091 if ((stack != null && stack.id == packet16blockitemswitch.itemId) || (stack == null && packet16blockitemswitch.itemId == 0)) {
1092 this.player.inventory.itemInHandIndex = i;
1093 }
1094 }
1095 }
1096 }
1097
1098 public void a(Packet3Chat packet3chat) {
1099 // poseidon
1100 PacketReceivedEvent event = new PacketReceivedEvent(server.getPlayer(player), packet3chat);
1101 server.getPluginManager().callEvent(event);
1102 if (event.isCancelled()) return;
1103
1104 String s = packet3chat.message;
1105
1106 if (s.length() > 100) {
1107 this.disconnect("Chat message too long");
1108 } else {
1109 s = s.trim();
1110
1111 for (int i = 0; i < s.length(); ++i) {
1112 if (FontAllowedCharacters.allowedCharacters.indexOf(s.charAt(i)) < 0) {
1113 this.disconnect("Illegal characters in chat");
1114 return;
1115 }
1116 }
1117
1118 // CraftBukkit start
1119 this.chat(s);
1120 }
1121 }
1122
1123 public boolean chat(String s) {
1124 if (!this.player.dead) {
1125 // UberBukkit - Start
1126 // Forcefully closes a container when a player sends a chat message
1127 if (player.activeContainer != player.defaultContainer) {
1128 player.y();
1129 }
1130 // UberBukkit - End
1131
1132 if (s.startsWith("/")) {
1133 this.handleCommand(s);
1134 return true;
1135 } else {
1136 Player player = this.getPlayer();
1137 PlayerChatEvent event = new PlayerChatEvent(player, s);
1138 this.server.getPluginManager().callEvent(event);
1139
1140 if (event.isCancelled()) {
1141 return true;
1142 }
1143
1144 s = String.format(event.getFormat(), event.getPlayer().getDisplayName(), event.getMessage());
1145 minecraftServer.console.sendMessage(s);
1146 for (Player recipient : event.getRecipients()) {
1147 recipient.sendMessage(s);
1148 }
1149 }
1150 }
1151
1152 return false;
1153 // CraftBukkit end
1154 }
1155
1156 private void handleCommand(String s) {
1157 // CraftBukkit start
1158 CraftPlayer player = this.getPlayer();
1159
1160 PlayerCommandPreprocessEvent event = new PlayerCommandPreprocessEvent(player, s);
1161 this.server.getPluginManager().callEvent(event);
1162
1163 if (event.isCancelled()) {
1164 return;
1165 }
1166
1167 s = event.getMessage(); //Poseidon: Override command with new command string.
1168
1169 try {
1170 if (this.server.dispatchCommand(player, s.substring(1))) {
1171 //Project Poseidon Start
1172 //Hide commands from being logged in console
1173 String cmdName = s.split(" ")[0].replaceAll("/", "");
1174
1175 if (Poseidon.getServer().isCommandHidden(cmdName)) {
1176 a.info(player.getName() + " issued server command: COMMAND REDACTED");
1177 } else {
1178 a.info(player.getName() + " issued server command: " + s);
1179 }
1180
1181 //Project Poseidon End
1182 return;
1183 }
1184 } catch (CommandException ex) {
1185 player.sendMessage(ChatColor.RED + "An internal error occurred while attempting to perform this command");
1186 Logger.getLogger(NetServerHandler.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
1187 return;
1188 }
1189 // CraftBukkit end
1190
1191 /* CraftBukkit start - No longer neaded av we have already handled it server.dispatchCommand above.
1192 if (s.toLowerCase().startsWith("/me ")) {
1193 s = "* " + this.player.name + " " + s.substring(s.indexOf(" ")).trim();
1194 a.info(s);
1195 this.minecraftServer.serverConfigurationManager.sendAll(new Packet3Chat(s));
1196 } else if (s.toLowerCase().startsWith("/kill")) {
1197 this.player.damageEntity(this.player, 1000); // CraftBukkit - replace null entity with player entity; TODO: decide if we want damage with a null source to fire an event.
1198 } else if (s.toLowerCase().startsWith("/tell ")) {
1199 String[] astring = s.split(" ");
1200
1201 if (astring.length >= 3) {
1202 s = s.substring(s.indexOf(" ")).trim();
1203 s = s.substring(s.indexOf(" ")).trim();
1204 s = "\u00A77" + this.player.name + " whispers " + s;
1205 a.info(s + " to " + astring[1]);
1206 if (!this.minecraftServer.serverConfigurationManager.a(astring[1], (Packet) (new Packet3Chat(s)))) {
1207 this.sendPacket(new Packet3Chat("\u00A7cThere\'s no player by that name online."));
1208 }
1209 }
1210 } else {
1211 String s1;
1212
1213 if (this.minecraftServer.serverConfigurationManager.isOp(this.player.name)) {
1214 s1 = s.substring(1);
1215 a.info(this.player.name + " issued server command: " + s1);
1216 this.minecraftServer.issueCommand(s1, this);
1217 } else {
1218 s1 = s.substring(1);
1219 a.info(this.player.name + " tried command: " + s1);
1220 }
1221 }
1222 // CraftBukkit end */
1223 }
1224
1225 public void a(Packet18ArmAnimation packet18armanimation) {
1226 // poseidon
1227 PacketReceivedEvent pevent = new PacketReceivedEvent(server.getPlayer(player), packet18armanimation);
1228 server.getPluginManager().callEvent(pevent);
1229 if (pevent.isCancelled()) return;
1230
1231 // CraftBukkit start
1232 if (this.player.dead) return;
1233
1234 if (packet18armanimation.b == 104 || packet18armanimation.b == 105) {
1235 PlayerToggleSneakEvent event = new PlayerToggleSneakEvent(this.getPlayer(), packet18armanimation.b == 104);
1236 this.server.getPluginManager().callEvent(event);
1237
1238 if (event.isCancelled()) {
1239 return;
1240 }
1241 }
1242 // CraftBukkit end
1243
1244 if (packet18armanimation.b == 1) {
1245 // CraftBukkit start - raytrace to look for 'rogue armswings'
1246 float f = 1.0F;
1247 float f1 = this.player.lastPitch + (this.player.pitch - this.player.lastPitch) * f;
1248 float f2 = this.player.lastYaw + (this.player.yaw - this.player.lastYaw) * f;
1249 double d0 = this.player.lastX + (this.player.locX - this.player.lastX) * (double) f;
1250 double d1 = this.player.lastY + (this.player.locY - this.player.lastY) * (double) f + 1.62D - (double) this.player.height;
1251 double d2 = this.player.lastZ + (this.player.locZ - this.player.lastZ) * (double) f;
1252 Vec3D vec3d = Vec3D.create(d0, d1, d2);
1253
1254 float f3 = MathHelper.cos(-f2 * 0.017453292F - 3.1415927F);
1255 float f4 = MathHelper.sin(-f2 * 0.017453292F - 3.1415927F);
1256 float f5 = -MathHelper.cos(-f1 * 0.017453292F);
1257 float f6 = MathHelper.sin(-f1 * 0.017453292F);
1258 float f7 = f4 * f5;
1259 float f8 = f3 * f5;
1260 double d3 = 5.0D;
1261 Vec3D vec3d1 = vec3d.add((double) f7 * d3, (double) f6 * d3, (double) f8 * d3);
1262 MovingObjectPosition movingobjectposition = this.player.world.rayTrace(vec3d, vec3d1, true);
1263
1264 if (movingobjectposition == null || movingobjectposition.type != EnumMovingObjectType.TILE) {
1265 CraftEventFactory.callPlayerInteractEvent(this.player, Action.LEFT_CLICK_AIR, this.player.inventory.getItemInHand());
1266 }
1267
1268 // Arm swing animation
1269 PlayerAnimationEvent event = new PlayerAnimationEvent(this.getPlayer());
1270 this.server.getPluginManager().callEvent(event);
1271
1272 if (event.isCancelled()) return;
1273 // CraftBukkit end
1274
1275 this.player.w();
1276
1277 // uberbukkit - handle digging
1278 if (this.mineExpire >= System.currentTimeMillis() && this.networkManager.pvn >= 9) {
1279 lastMine = System.currentTimeMillis();
1280 }
1281 } else if (packet18armanimation.b == 104) {
1282 this.player.setSneak(true);
1283 } else if (packet18armanimation.b == 105) {
1284 this.player.setSneak(false);
1285 }
1286 }
1287
1288 public void a(Packet19EntityAction packet19entityaction) {
1289 // poseidon
1290 PacketReceivedEvent pevent = new PacketReceivedEvent(server.getPlayer(player), packet19entityaction);
1291 server.getPluginManager().callEvent(pevent);
1292 if (pevent.isCancelled()) return;
1293
1294 // CraftBukkit start
1295 if (this.player.dead) return;
1296
1297 if (packet19entityaction.animation == 1 || packet19entityaction.animation == 2) {
1298 PlayerToggleSneakEvent event = new PlayerToggleSneakEvent(this.getPlayer(), packet19entityaction.animation == 1);
1299 this.server.getPluginManager().callEvent(event);
1300
1301 if (event.isCancelled()) {
1302 return;
1303 }
1304 }
1305 // CraftBukkit end
1306
1307 if (packet19entityaction.animation == 1) {
1308 this.player.setSneak(true);
1309 } else if (packet19entityaction.animation == 2) {
1310 this.player.setSneak(false);
1311 } else if (packet19entityaction.animation == 3) {
1312 this.player.a(false, true, true);
1313 this.checkMovement = false;
1314 }
1315 }
1316
1317 public void a(Packet0KeepAlive packet0KeepAlive) {
1318 this.receivedKeepAlive = true;
1319 }
1320
1321 public void a(Packet255KickDisconnect packet255kickdisconnect) {
1322 // poseidon
1323 PacketReceivedEvent event = new PacketReceivedEvent(server.getPlayer(player), packet255kickdisconnect);
1324 server.getPluginManager().callEvent(event);
1325 if (event.isCancelled()) return;
1326
1327 // uberbukkit - drop item queue on disconnect
1328 if (this.networkManager.pvn <= 6) {
1329 ArrayList<ItemStack> queue = this.player.packet5.queue.dropAllQueue();
1330 Player bukkitEntity = (Player) this.player.getBukkitEntity();
1331 for (ItemStack item : queue) {
1332 System.out.println("Drop queue id: " + item.id + ", dmg: " + item.damage + ", cnt: " + item.count);
1333 HashMap<Integer, org.bukkit.inventory.ItemStack> map = bukkitEntity.getInventory().addItem(new CraftItemStack(item));
1334 // drop what couldn't fit in the inventory
1335 for (org.bukkit.inventory.ItemStack stack : map.values()) {
1336 bukkitEntity.getWorld().dropItemNaturally(bukkitEntity.getLocation(), stack);
1337 }
1338 }
1339 }
1340 this.networkManager.a("disconnect.quitting", new Object[0]);
1341 }
1342
1343 public int b() {
1344 return this.networkManager.e();
1345 }
1346
1347 public void sendMessage(String s) {
1348 this.sendPacket(new Packet3Chat("\u00A77" + s));
1349 }
1350
1351 public String getName() {
1352 return this.player.name;
1353 }
1354
1355 public void a(Packet7UseEntity packet7useentity) {
1356 // poseidon
1357 PacketReceivedEvent pevent = new PacketReceivedEvent(server.getPlayer(player), packet7useentity);
1358 server.getPluginManager().callEvent(pevent);
1359 if (pevent.isCancelled()) return;
1360
1361 if (this.player.dead) return; // CraftBukkit
1362
1363 WorldServer worldserver = this.minecraftServer.getWorldServer(this.player.dimension);
1364 Entity entity = worldserver.getEntity(packet7useentity.target);
1365 ItemStack itemInHand = this.player.inventory.getItemInHand();
1366
1367 if (entity != null) {
1368
1369 // uberbukkit start
1370 // backported from release 1.2, fixes mobs being unpunchable from certain positions
1371 boolean flag = this.player.e(entity);
1372 double maxRange = 36.0D;
1373
1374 if (!flag) maxRange = 9.0D;
1375
1376 if (this.player.g(entity) >= maxRange) return;
1377
1378 // uberbukkit end
1379
1380 if (packet7useentity.c == 0) {
1381 Player player = (Player) this.getPlayer();
1382 org.bukkit.entity.Entity bukkitEntity = entity.getBukkitEntity();
1383 // CraftBukkit start
1384 //Project Poseidon Start - Fixes a Minecart dupe glitch
1385 if (player.isInsideVehicle() && bukkitEntity instanceof StorageMinecart) {
1386 return;
1387 }
1388 //Project Poseidon End
1389 PlayerInteractEntityEvent event = new PlayerInteractEntityEvent(player, bukkitEntity);
1390 this.server.getPluginManager().callEvent(event);
1391
1392 if (event.isCancelled()) {
1393 return;
1394 }
1395 // CraftBukkit end
1396 this.player.c(entity);
1397 // CraftBukkit start - update the client if the item is an infinite one
1398 if (itemInHand != null && itemInHand.count <= -1) {
1399 this.player.updateInventory(this.player.activeContainer);
1400 }
1401 // CraftBukkit end
1402 } else if (packet7useentity.c == 1) {
1403 this.player.d(entity);
1404 // CraftBukkit start - update the client if the item is an infinite one
1405 if (itemInHand != null && itemInHand.count <= -1) {
1406 this.player.updateInventory(this.player.activeContainer);
1407 }
1408 // CraftBukkit end
1409 }
1410 }
1411 }
1412
1413 public void a(Packet9Respawn packet9respawn) {
1414 // poseidon
1415 PacketReceivedEvent event = new PacketReceivedEvent(server.getPlayer(player), packet9respawn);
1416 server.getPluginManager().callEvent(event);
1417 if (event.isCancelled()) return;
1418
1419 if (this.player.health <= 0) {
1420 this.player = this.minecraftServer.serverConfigurationManager.moveToWorld(this.player, 0);
1421
1422 this.getPlayer().setHandle(this.player); // CraftBukkit
1423 }
1424 }
1425
1426 public void a(Packet101CloseWindow packet101closewindow) {
1427 if (this.player.dead) return; // CraftBukkit
1428
1429 this.player.A();
1430 }
1431
1432 public void a(Packet102WindowClick packet102windowclick) {
1433 // poseidon
1434 PacketReceivedEvent event = new PacketReceivedEvent(server.getPlayer(player), packet102windowclick);
1435 server.getPluginManager().callEvent(event);
1436 if (event.isCancelled()) return;
1437
1438 if (this.player.dead) return; // CraftBukkit
1439
1440 if (this.player.activeContainer.windowId == packet102windowclick.a && this.player.activeContainer.c(this.player)) {
1441 if (this.player.activeContainer.isPositioned() && !Patches.CONTAINER_DISTANCE.check(this.player, this.player.activeContainer.getPosition())) {
1442 return;
1443 }
1444
1445 ItemStack itemstack = this.player.activeContainer.a(packet102windowclick.b, packet102windowclick.c, packet102windowclick.f, this.player);
1446
1447 if (ItemStack.equals(packet102windowclick.e, itemstack)) {
1448 this.player.netServerHandler.sendPacket(new Packet106Transaction(packet102windowclick.a, packet102windowclick.d, true));
1449 this.player.h = true;
1450 this.player.activeContainer.a();
1451 this.player.z();
1452 this.player.h = false;
1453 } else {
1454 this.n.put(this.player.activeContainer.windowId, packet102windowclick.d);
1455 this.player.netServerHandler.sendPacket(new Packet106Transaction(packet102windowclick.a, packet102windowclick.d, false));
1456 this.player.activeContainer.a(this.player, false);
1457 ArrayList arraylist = new ArrayList();
1458
1459 for (int i = 0; i < this.player.activeContainer.e.size(); ++i) {
1460 arraylist.add(((Slot) this.player.activeContainer.e.get(i)).getItem());
1461 }
1462
1463 this.player.a(this.player.activeContainer, arraylist);
1464 }
1465 }
1466 }
1467
1468 public void a(Packet106Transaction packet106transaction) {
1469 // poseidon
1470 PacketReceivedEvent event = new PacketReceivedEvent(server.getPlayer(player), packet106transaction);
1471 server.getPluginManager().callEvent(event);
1472 if (event.isCancelled()) return;
1473
1474 if (this.player.dead) return; // CraftBukkit
1475
1476 Short oshort = (Short) this.n.get(this.player.activeContainer.windowId);
1477
1478 if (oshort != null && packet106transaction.b == oshort && this.player.activeContainer.windowId == packet106transaction.a && !this.player.activeContainer.c(this.player)) {
1479 if (this.player.activeContainer.isPositioned() && !Patches.CONTAINER_DISTANCE.check(this.player, this.player.activeContainer.getPosition())) {
1480 return;
1481 }
1482
1483 this.player.activeContainer.a(this.player, true);
1484 }
1485 }
1486
1487 public void a(Packet130UpdateSign packet130updatesign) {
1488 // poseidon
1489 PacketReceivedEvent pevent = new PacketReceivedEvent(server.getPlayer(player), packet130updatesign);
1490 server.getPluginManager().callEvent(pevent);
1491 if (pevent.isCancelled()) return;
1492
1493 if (this.player.dead) return; // CraftBukkit
1494
1495 WorldServer worldserver = this.minecraftServer.getWorldServer(this.player.dimension);
1496
1497 if (worldserver.isLoaded(packet130updatesign.x, packet130updatesign.y, packet130updatesign.z)) {
1498 TileEntity tileentity = worldserver.getTileEntity(packet130updatesign.x, packet130updatesign.y, packet130updatesign.z);
1499
1500 if (tileentity instanceof TileEntitySign) {
1501 TileEntitySign tileentitysign = (TileEntitySign) tileentity;
1502
1503 if (!tileentitysign.a()) {
1504 this.minecraftServer.c("Player " + this.player.name + " just tried to change non-editable sign");
1505 // CraftBukkit
1506 this.sendPacket(new Packet130UpdateSign(packet130updatesign.x, packet130updatesign.y, packet130updatesign.z, tileentitysign.lines));
1507 return;
1508 }
1509 }
1510
1511 int i;
1512 int j;
1513
1514 for (j = 0; j < 4; ++j) {
1515 boolean flag = true;
1516
1517 if (packet130updatesign.lines[j].length() > 15) {
1518 flag = false;
1519 } else {
1520 for (i = 0; i < packet130updatesign.lines[j].length(); ++i) {
1521 if (FontAllowedCharacters.allowedCharacters.indexOf(packet130updatesign.lines[j].charAt(i)) < 0) {
1522 flag = false;
1523 }
1524 }
1525 }
1526
1527 if (!flag) {
1528 packet130updatesign.lines[j] = "!?";
1529 }
1530 }
1531
1532 if (tileentity instanceof TileEntitySign) {
1533 j = packet130updatesign.x;
1534 int k = packet130updatesign.y;
1535
1536 i = packet130updatesign.z;
1537 TileEntitySign tileentitysign1 = (TileEntitySign) tileentity;
1538
1539 // CraftBukkit start
1540 Player player = this.server.getPlayer(this.player);
1541 SignChangeEvent event = new SignChangeEvent((CraftBlock) player.getWorld().getBlockAt(j, k, i), this.server.getPlayer(this.player), packet130updatesign.lines);
1542 this.server.getPluginManager().callEvent(event);
1543
1544 if (!event.isCancelled()) {
1545 for (int l = 0; l < 4; ++l) {
1546 tileentitysign1.lines[l] = event.getLine(l);
1547 }
1548 tileentitysign1.a(false);
1549 }
1550 // CraftBukkit end
1551
1552 tileentitysign1.update();
1553 worldserver.notify(j, k, i);
1554 }
1555 }
1556 }
1557
1558 public boolean c() {
1559 return true;
1560 }
1561}