Commits
1 - | --- /home/matt/mc-dev-private//net/minecraft/server/PlayerConnection.java 2015-04-15 17:35:03.688828804 +0100 |
2 - | +++ src/main/java/net/minecraft/server/PlayerConnection.java 2015-04-15 17:35:03.692828804 +0100 |
1 + | --- /home/matt/mc-dev-private//net/minecraft/server/PlayerConnection.java 2015-04-17 11:54:58.464656095 +0100 |
2 + | +++ src/main/java/net/minecraft/server/PlayerConnection.java 2015-04-17 11:54:58.468656095 +0100 |
3 3 | |
4 4 | import org.apache.logging.log4j.LogManager; |
5 5 | import org.apache.logging.log4j.Logger; |
6 6 | |
7 7 | +// CraftBukkit start |
8 8 | +import java.util.concurrent.ExecutionException; |
9 9 | +import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; |
10 10 | +import java.util.HashSet; |
11 11 | + |
12 12 | +import org.bukkit.craftbukkit.entity.CraftPlayer; |
109 109 | + for (int spam; (spam = this.chatThrottle) > 0 && !chatSpamField.compareAndSet(this, spam, spam - 1); ) ; |
110 110 | + /* Use thread-safe field access instead |
111 111 | if (this.chatThrottle > 0) { |
112 112 | --this.chatThrottle; |
113 113 | } |
114 114 | + */ |
115 115 | + // CraftBukkit end |
116 116 | |
117 117 | if (this.m > 0) { |
118 118 | --this.m; |
119 - | |
119 + | |
120 120 | } |
121 121 | |
122 122 | public void disconnect(String s) { |
123 123 | + // CraftBukkit start - fire PlayerKickEvent |
124 124 | + String leaveMessage = EnumChatFormat.YELLOW + this.player.getName() + " left the game."; |
125 125 | + |
126 126 | + PlayerKickEvent event = new PlayerKickEvent(this.server.getPlayer(this.player), s, leaveMessage); |
127 127 | + |
128 128 | + if (this.server.getServer().isRunning()) { |
129 129 | + this.server.getPluginManager().callEvent(event); |
142 142 | - public void operationComplete(Future<? super Void> future) throws Exception { |
143 143 | + public void operationComplete(Future future) throws Exception { // CraftBukkit - fix decompile error |
144 144 | PlayerConnection.this.networkManager.close(chatcomponenttext); |
145 145 | } |
146 146 | }, new GenericFutureListener[0]); |
147 147 | + this.a(chatcomponenttext); // CraftBukkit - fire quit instantly |
148 148 | this.networkManager.k(); |
149 149 | - Futures.getUnchecked(this.minecraftServer.postToMainThread(new Runnable() { |
150 150 | - public void run() { |
151 151 | - PlayerConnection.this.networkManager.l(); |
152 - | - } |
152 + | + // CraftBukkit - Don't wait |
153 + | + this.minecraftServer.postToMainThread(new Runnable() { |
154 + | + public void run() { |
155 + | + PlayerConnection.this.networkManager.l(); |
156 + | } |
153 157 | - })); |
158 + | + }); |
154 159 | } |
155 160 | |
156 161 | public void a(PacketPlayInSteerVehicle packetplayinsteervehicle) { |
157 - | |
162 + | |
158 163 | |
159 164 | public void a(PacketPlayInFlying packetplayinflying) { |
160 165 | PlayerConnectionUtils.ensureMainThread(packetplayinflying, this, this.player.u()); |
161 166 | + // CraftBukkit start - Check for NaN |
162 167 | + if (!NumberConversions.isFinite(packetplayinflying.x) |
163 168 | + || !NumberConversions.isFinite(packetplayinflying.y) |
164 169 | + || !NumberConversions.isFinite(packetplayinflying.z) |
165 170 | + || !NumberConversions.isFinite(packetplayinflying.yaw) |
166 171 | + || !NumberConversions.isFinite(packetplayinflying.pitch)) { |
167 172 | + c.warn(player.getName() + " was caught trying to crash the server with an invalid position."); |
168 173 | + getPlayer().kickPlayer("Nope!"); |
169 174 | + return; |
170 175 | + } |
171 176 | + // CraftBukkit end |
172 177 | WorldServer worldserver = this.minecraftServer.getWorldServer(this.player.dimension); |
173 178 | |
174 179 | this.h = true; |
175 - | |
180 + | |
176 181 | this.checkMovement = true; |
177 182 | } |
178 183 | } |
179 184 | + // CraftBukkit start - fire PlayerMoveEvent |
180 185 | + Player player = this.getPlayer(); |
181 186 | + Location from = new Location(player.getWorld(), lastPosX, lastPosY, lastPosZ, lastYaw, lastPitch); // Get the Players previous Event location. |
182 187 | + Location to = player.getLocation().clone(); // Start off the To location as the Players current location. |
183 188 | + |
184 189 | + // If the packet contains movement information then we update the To location with the correct XYZ. |
185 190 | + if (packetplayinflying.hasPos && !(packetplayinflying.hasPos && packetplayinflying.y == -999.0D)) { |
233 238 | + return; |
234 239 | + } |
235 240 | + } |
236 241 | + } |
237 242 | + |
238 243 | + if (this.checkMovement && !this.player.dead) { |
239 244 | + // CraftBukkit end |
240 245 | this.f = this.e; |
241 246 | double d7; |
242 247 | double d8; |
243 - | |
248 + | |
244 249 | |
245 250 | this.minecraftServer.getPlayerList().d(this.player); |
246 251 | if (this.player.vehicle != null) { |
247 252 | + this.player.vehicle.ai = true; // CraftBukkit - moved from below |
248 253 | if (d3 > 4.0D) { |
249 254 | Entity entity = this.player.vehicle; |
250 255 | |
251 - | |
256 + | |
252 257 | this.a(this.player.locX, this.player.locY, this.player.locZ, this.player.yaw, this.player.pitch); |
253 258 | } |
254 259 | |
255 260 | - this.player.vehicle.ai = true; |
256 261 | + // this.player.vehicle.ai = true; // CraftBukkit - moved up |
257 262 | } |
258 263 | |
259 264 | if (this.checkMovement) { |
260 - | |
265 + | |
261 266 | double d11 = d7 - this.player.locX; |
262 267 | double d12 = d8 - this.player.locY; |
263 268 | double d13 = d9 - this.player.locZ; |
264 269 | - double d14 = Math.min(Math.abs(d11), Math.abs(this.player.motX)); |
265 270 | - double d15 = Math.min(Math.abs(d12), Math.abs(this.player.motY)); |
266 271 | - double d16 = Math.min(Math.abs(d13), Math.abs(this.player.motZ)); |
267 272 | + // CraftBukkit start - min to max |
268 273 | + double d14 = Math.max(Math.abs(d11), Math.abs(this.player.motX)); |
269 274 | + double d15 = Math.max(Math.abs(d12), Math.abs(this.player.motY)); |
270 275 | + double d16 = Math.max(Math.abs(d13), Math.abs(this.player.motZ)); |
271 276 | + // CraftBukkit end |
272 277 | double d17 = d14 * d14 + d15 * d15 + d16 * d16; |
273 278 | |
274 279 | - if (d17 > 100.0D && (!this.minecraftServer.S() || !this.minecraftServer.R().equals(this.player.getName()))) { |
275 280 | + if (d17 > 100.0D && this.checkMovement && (!this.minecraftServer.S() || !this.minecraftServer.R().equals(this.player.getName()))) { // CraftBukkit - Added this.checkMovement condition to solve this check being triggered by teleports |
276 281 | PlayerConnection.c.warn(this.player.getName() + " moved too quickly! " + d11 + "," + d12 + "," + d13 + " (" + d14 + ", " + d15 + ", " + d16 + ")"); |
277 282 | this.a(this.o, this.p, this.q, this.player.yaw, this.player.pitch); |
278 283 | return; |
279 - | |
284 + | |
280 285 | } |
281 286 | |
282 287 | public void a(double d0, double d1, double d2, float f, float f1) { |
283 288 | - this.a(d0, d1, d2, f, f1, Collections.emptySet()); |
284 289 | + this.a(d0, d1, d2, f, f1, Collections.<PacketPlayOutPosition.EnumPlayerTeleportFlags>emptySet()); // CraftBukkit fix decompile errors |
285 290 | } |
286 291 | |
287 292 | public void a(double d0, double d1, double d2, float f, float f1, Set<PacketPlayOutPosition.EnumPlayerTeleportFlags> set) { |
288 293 | + // CraftBukkit start - Delegate to teleport(Location) |
289 294 | + Player player = this.getPlayer(); |
324 329 | + this.lastPosX = d0; |
325 330 | + this.lastPosY = d1; |
326 331 | + this.lastPosZ = d2; |
327 332 | + this.lastYaw = f; |
328 333 | + this.lastPitch = f1; |
329 334 | + this.justTeleported = true; |
330 335 | + // CraftBukkit end |
331 336 | this.checkMovement = false; |
332 337 | this.o = d0; |
333 338 | this.p = d1; |
334 - | |
339 + | |
335 340 | |
336 341 | public void a(PacketPlayInBlockDig packetplayinblockdig) { |
337 342 | PlayerConnectionUtils.ensureMainThread(packetplayinblockdig, this, this.player.u()); |
338 343 | + if (this.player.dead) return; // CraftBukkit |
339 344 | WorldServer worldserver = this.minecraftServer.getWorldServer(this.player.dimension); |
340 345 | BlockPosition blockposition = packetplayinblockdig.a(); |
341 346 | |
342 347 | this.player.z(); |
343 348 | + // CraftBukkit start |
344 349 | switch (PlayerConnection.SyntheticClass_1.a[packetplayinblockdig.c().ordinal()]) { |
380 385 | |
381 386 | - case 4: |
382 387 | - case 5: |
383 388 | - case 6: |
384 389 | + case 4: // START_DESTROY_BLOCK |
385 390 | + case 5: // ABORT_DESTROY_BLOCK |
386 391 | + case 6: // STOP_DESTROY_BLOCK |
387 392 | double d0 = this.player.locX - ((double) blockposition.getX() + 0.5D); |
388 393 | double d1 = this.player.locY - ((double) blockposition.getY() + 0.5D) + 1.5D; |
389 394 | double d2 = this.player.locZ - ((double) blockposition.getZ() + 0.5D); |
390 - | |
395 + | |
391 396 | if (!this.minecraftServer.a(worldserver, blockposition, this.player) && worldserver.getWorldBorder().a(blockposition)) { |
392 397 | this.player.playerInteractManager.a(blockposition, packetplayinblockdig.b()); |
393 398 | } else { |
394 399 | + // CraftBukkit start - fire PlayerInteractEvent |
395 400 | + CraftEventFactory.callPlayerInteractEvent(this.player, Action.LEFT_CLICK_BLOCK, blockposition, packetplayinblockdig.b(), this.player.inventory.getItemInHand()); |
396 401 | this.player.playerConnection.sendPacket(new PacketPlayOutBlockChange(worldserver, blockposition)); |
397 402 | + // Update any tile entity data for this block |
398 403 | + TileEntity tileentity = worldserver.getTileEntity(blockposition); |
399 404 | + if (tileentity != null) { |
400 405 | + this.player.playerConnection.sendPacket(tileentity.getUpdatePacket()); |
401 406 | + } |
402 407 | + // CraftBukkit end |
403 408 | } |
404 409 | } else { |
405 410 | if (packetplayinblockdig.c() == PacketPlayInBlockDig.EnumPlayerDigType.STOP_DESTROY_BLOCK) { |
406 - | |
411 + | |
407 412 | default: |
408 413 | throw new IllegalArgumentException("Invalid player action"); |
409 414 | } |
410 415 | + // CraftBukkit end |
411 416 | } |
412 417 | |
413 418 | public void a(PacketPlayInBlockPlace packetplayinblockplace) { |
414 419 | PlayerConnectionUtils.ensureMainThread(packetplayinblockplace, this, this.player.u()); |
415 420 | WorldServer worldserver = this.minecraftServer.getWorldServer(this.player.dimension); |
416 421 | + |
419 424 | + |
420 425 | + // CraftBukkit - if rightclick decremented the item, always send the update packet. */ |
421 426 | + // this is not here for CraftBukkit's own functionality; rather it is to fix |
422 427 | + // a notch bug where the item doesn't update correctly. |
423 428 | + boolean always = false; |
424 429 | + // CraftBukkit end |
425 430 | + |
426 431 | ItemStack itemstack = this.player.inventory.getItemInHand(); |
427 432 | boolean flag = false; |
428 433 | BlockPosition blockposition = packetplayinblockplace.a(); |
429 - | |
434 + | |
430 435 | return; |
431 436 | } |
432 437 | |
433 438 | - this.player.playerInteractManager.useItem(this.player, worldserver, itemstack); |
434 439 | + // CraftBukkit start |
435 440 | + int itemstackAmount = itemstack.count; |
436 441 | + |
437 442 | + // Raytrace to look for 'rogue armswings' |
438 443 | + float f1 = this.player.pitch; |
439 444 | + float f2 = this.player.yaw; |
471 476 | + } |
472 477 | + |
473 478 | + // CraftBukkit - notch decrements the counter by 1 in the above method with food, |
474 479 | + // snowballs and so forth, but he does it in a place that doesn't cause the |
475 480 | + // inventory update packet to get sent |
476 481 | + always = (itemstack.count != itemstackAmount) || itemstack.getItem() == Item.getItemOf(Blocks.WATERLILY); |
477 482 | + // CraftBukkit end |
478 483 | } else if (blockposition.getY() >= this.minecraftServer.getMaxBuildHeight() - 1 && (enumdirection == EnumDirection.UP || blockposition.getY() >= this.minecraftServer.getMaxBuildHeight())) { |
479 484 | ChatMessage chatmessage = new ChatMessage("build.tooHigh", new Object[] { Integer.valueOf(this.minecraftServer.getMaxBuildHeight())}); |
480 485 | |
481 - | |
486 + | |
482 487 | this.player.playerConnection.sendPacket(new PacketPlayOutChat(chatmessage)); |
483 488 | flag = true; |
484 489 | } else { |
485 490 | + // CraftBukkit start - Check if we can actually do something over this large a distance |
486 491 | + Location eyeLoc = this.getPlayer().getEyeLocation(); |
487 492 | + double reachDistance = NumberConversions.square(eyeLoc.getX() - blockposition.getX()) + NumberConversions.square(eyeLoc.getY() - blockposition.getY()) + NumberConversions.square(eyeLoc.getZ() - blockposition.getZ()); |
488 493 | + if (reachDistance > (this.getPlayer().getGameMode() == org.bukkit.GameMode.CREATIVE ? CREATIVE_PLACE_DISTANCE_SQUARED : SURVIVAL_PLACE_DISTANCE_SQUARED)) { |
489 494 | + return; |
490 495 | + } |
491 496 | + |
492 497 | + if (!worldserver.getWorldBorder().a(blockposition)) { |
493 498 | + return; |
494 499 | + } |
495 500 | + |
496 501 | if (this.checkMovement && this.player.e((double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D) < 64.0D && !this.minecraftServer.a(worldserver, blockposition, this.player) && worldserver.getWorldBorder().a(blockposition)) { |
497 502 | - this.player.playerInteractManager.interact(this.player, worldserver, itemstack, blockposition, enumdirection, packetplayinblockplace.d(), packetplayinblockplace.e(), packetplayinblockplace.f()); |
498 503 | + always = !this.player.playerInteractManager.interact(this.player, worldserver, itemstack, blockposition, enumdirection, packetplayinblockplace.d(), packetplayinblockplace.e(), packetplayinblockplace.f()); |
499 504 | } |
500 505 | |
501 506 | flag = true; |
502 - | |
507 + | |
503 508 | |
504 509 | this.player.activeContainer.b(); |
505 510 | this.player.g = false; |
506 511 | - if (!ItemStack.matches(this.player.inventory.getItemInHand(), packetplayinblockplace.getItemStack())) { |
507 512 | + // CraftBukkit - TODO CHECK IF NEEDED -- new if structure might not need 'always'. Kept it in for now, but may be able to remove in future |
508 513 | + if (!ItemStack.matches(this.player.inventory.getItemInHand(), packetplayinblockplace.getItemStack()) || always) { |
509 514 | this.sendPacket(new PacketPlayOutSetSlot(this.player.activeContainer.windowId, slot.rawSlotIndex, this.player.inventory.getItemInHand())); |
510 515 | } |
511 516 | } |
512 - | |
517 + | |
513 518 | WorldServer[] aworldserver = this.minecraftServer.worldServer; |
514 519 | int i = aworldserver.length; |
515 520 | |
516 521 | - for (int j = 0; j < i; ++j) { |
517 522 | - WorldServer worldserver = aworldserver[j]; |
518 523 | + // CraftBukkit - use the worlds array list |
519 524 | + for (WorldServer worldserver : minecraftServer.worlds) { |
520 525 | |
521 526 | if (worldserver != null) { |
522 527 | entity = packetplayinspectate.a(worldserver); |
523 - | |
528 + | |
524 529 | if (entity != null) { |
525 530 | this.player.e((Entity) this.player); |
526 531 | this.player.mount((Entity) null); |
527 532 | + |
528 533 | + /* CraftBukkit start - replace with bukkit handling for multi-world |
529 534 | if (entity.world != this.player.world) { |
530 535 | WorldServer worldserver1 = this.player.u(); |
531 536 | WorldServer worldserver2 = (WorldServer) entity.world; |
532 - | |
537 + | |
533 538 | } else { |
534 539 | this.player.enderTeleportTo(entity.locX, entity.locY, entity.locZ); |
535 540 | } |
536 541 | + */ |
537 542 | + this.player.getBukkitEntity().teleport(entity.getBukkitEntity(), PlayerTeleportEvent.TeleportCause.SPECTATE); |
538 543 | + // CraftBukkit end |
539 544 | } |
540 545 | } |
541 546 | |
542 - | |
547 + | |
543 548 | public void a(PacketPlayInResourcePackStatus packetplayinresourcepackstatus) {} |
544 549 | |
545 550 | public void a(IChatBaseComponent ichatbasecomponent) { |
546 551 | - PlayerConnection.c.info(this.player.getName() + " lost connection: " + ichatbasecomponent); |
547 552 | + // CraftBukkit start - Rarely it would send a disconnect line twice |
548 553 | + if (this.processedDisconnect) { |
549 554 | + return; |
550 555 | + } else { |
551 556 | + this.processedDisconnect = true; |
552 557 | + } |
564 569 | this.player.q(); |
565 570 | - this.minecraftServer.getPlayerList().disconnect(this.player); |
566 571 | + String quitMessage = this.minecraftServer.getPlayerList().disconnect(this.player); |
567 572 | + if ((quitMessage != null) && (quitMessage.length() > 0)) { |
568 573 | + this.minecraftServer.getPlayerList().sendMessage(CraftChatMessage.fromString(quitMessage)); |
569 574 | + } |
570 575 | + // CraftBukkit end |
571 576 | if (this.minecraftServer.S() && this.player.getName().equals(this.minecraftServer.R())) { |
572 577 | PlayerConnection.c.info("Stopping singleplayer server as player logged out"); |
573 578 | this.minecraftServer.safeShutdown(); |
574 - | |
579 + | |
575 580 | } |
576 581 | } |
577 582 | |
578 583 | + // CraftBukkit start |
579 584 | + if (packet == null) { |
580 585 | + return; |
581 586 | + } else if (packet instanceof PacketPlayOutSpawnPosition) { |
582 587 | + PacketPlayOutSpawnPosition packet6 = (PacketPlayOutSpawnPosition) packet; |
583 588 | + this.player.compassTarget = new Location(this.getPlayer().getWorld(), packet6.position.getX(), packet6.position.getY(), packet6.position.getZ()); |
584 589 | + } |
585 590 | + // CraftBukkit end |
586 591 | + |
587 592 | try { |
588 593 | this.networkManager.handle(packet); |
589 594 | } catch (Throwable throwable) { |
590 - | |
595 + | |
591 596 | } |
592 597 | |
593 598 | public void a(PacketPlayInHeldItemSlot packetplayinhelditemslot) { |
594 599 | + // CraftBukkit start |
595 600 | + if (this.player.dead) return; |
596 601 | PlayerConnectionUtils.ensureMainThread(packetplayinhelditemslot, this, this.player.u()); |
597 602 | if (packetplayinhelditemslot.a() >= 0 && packetplayinhelditemslot.a() < PlayerInventory.getHotbarSize()) { |
598 603 | + PlayerItemHeldEvent event = new PlayerItemHeldEvent(this.getPlayer(), this.player.inventory.itemInHandIndex, packetplayinhelditemslot.a()); |
599 604 | + this.server.getPluginManager().callEvent(event); |
600 605 | + if (event.isCancelled()) { |
617 622 | + // CraftBukkit start - async chat |
618 623 | + boolean isSync = packetplayinchat.a().startsWith("/"); |
619 624 | + if (packetplayinchat.a().startsWith("/")) { |
620 625 | + PlayerConnectionUtils.ensureMainThread(packetplayinchat, this, this.player.u()); |
621 626 | + } |
622 627 | + // CraftBukkit end |
623 628 | + if (this.player.dead || this.player.getChatFlags() == EntityHuman.EnumChatVisibility.HIDDEN) { // CraftBukkit - dead men tell no tales |
624 629 | ChatMessage chatmessage = new ChatMessage("chat.cannotSend", new Object[0]); |
625 630 | |
626 631 | chatmessage.getChatModifier().setColor(EnumChatFormat.RED); |
627 - | |
632 + | |
628 633 | |
629 634 | for (int i = 0; i < s.length(); ++i) { |
630 635 | if (!SharedConstants.isAllowedChatCharacter(s.charAt(i))) { |
631 636 | - this.disconnect("Illegal characters in chat"); |
632 637 | + // CraftBukkit start - threadsafety |
633 638 | + if (!isSync) { |
634 639 | + Waitable waitable = new Waitable() { |
635 640 | + @Override |
636 641 | + protected Object evaluate() { |
637 642 | + PlayerConnection.this.disconnect("Illegal characters in chat"); |
875 880 | + |
876 881 | + if (e2.isCancelled()) { |
877 882 | + return; |
878 883 | + } |
879 884 | + break; |
880 885 | + } |
881 886 | + // CraftBukkit end |
882 887 | this.player.z(); |
883 888 | switch (PlayerConnection.SyntheticClass_1.b[packetplayinentityaction.b().ordinal()]) { |
884 889 | case 1: |
885 - | |
890 + | |
886 891 | |
887 892 | case 5: |
888 893 | this.player.a(false, true, true); |
889 894 | - this.checkMovement = false; |
890 895 | + // this.checkMovement = false; // CraftBukkit - this is handled in teleport |
891 896 | break; |
892 897 | |
893 898 | case 6: |
894 - | |
899 + | |
895 900 | } |
896 901 | |
897 902 | public void a(PacketPlayInUseEntity packetplayinuseentity) { |
898 903 | + if (this.player.dead) return; // CraftBukkit |
899 904 | PlayerConnectionUtils.ensureMainThread(packetplayinuseentity, this, this.player.u()); |
900 905 | WorldServer worldserver = this.minecraftServer.getWorldServer(this.player.dimension); |
901 906 | Entity entity = packetplayinuseentity.a((World) worldserver); |
902 - | |
907 + | |
903 908 | } |
904 909 | |
905 910 | if (this.player.h(entity) < d0) { |
906 911 | + ItemStack itemInHand = this.player.inventory.getItemInHand(); // CraftBukkit |
907 912 | + |
908 913 | + if (packetplayinuseentity.a() == PacketPlayInUseEntity.EnumEntityUseAction.INTERACT |
909 914 | + || packetplayinuseentity.a() == PacketPlayInUseEntity.EnumEntityUseAction.INTERACT_AT) { |
910 915 | + // CraftBukkit start |
911 916 | + boolean triggerLeashUpdate = itemInHand != null && itemInHand.getItem() == Items.LEAD && entity instanceof EntityInsentient; |
912 917 | + Item origItem = this.player.inventory.getItemInHand() == null ? null : this.player.inventory.getItemInHand().getItem(); |
961 966 | this.player.attack(entity); |
962 967 | + |
963 968 | + // CraftBukkit start |
964 969 | + if (itemInHand != null && itemInHand.count <= -1) { |
965 970 | + this.player.updateInventory(this.player.activeContainer); |
966 971 | + } |
967 972 | + // CraftBukkit end |
968 973 | } |
969 974 | } |
970 975 | } |
971 - | |
976 + | |
972 977 | switch (PlayerConnection.SyntheticClass_1.c[packetplayinclientcommand_enumclientcommand.ordinal()]) { |
973 978 | case 1: |
974 979 | if (this.player.viewingCredits) { |
975 980 | - this.player = this.minecraftServer.getPlayerList().moveToWorld(this.player, 0, true); |
976 981 | + // this.player = this.minecraftServer.getPlayerList().moveToWorld(this.player, 0, true); |
977 982 | + this.minecraftServer.getPlayerList().changeDimension(this.player, 0, PlayerTeleportEvent.TeleportCause.END_PORTAL); // CraftBukkit - reroute logic through custom portal management |
978 983 | } else if (this.player.u().getWorldData().isHardcore()) { |
979 984 | if (this.minecraftServer.S() && this.player.getName().equals(this.minecraftServer.R())) { |
980 985 | this.player.playerConnection.disconnect("You have died. Game over, man, it\'s game over!"); |
981 - | |
986 + | |
982 987 | } |
983 988 | |
984 989 | public void a(PacketPlayInCloseWindow packetplayinclosewindow) { |
985 990 | + if (this.player.dead) return; // CraftBukkit |
986 991 | PlayerConnectionUtils.ensureMainThread(packetplayinclosewindow, this, this.player.u()); |
987 992 | + |
988 993 | + CraftEventFactory.handleInventoryCloseEvent(this.player); // CraftBukkit |
989 994 | + |
990 995 | this.player.p(); |
991 996 | } |
994 999 | + if (this.player.dead) return; // CraftBukkit |
995 1000 | PlayerConnectionUtils.ensureMainThread(packetplayinwindowclick, this, this.player.u()); |
996 1001 | this.player.z(); |
997 1002 | if (this.player.activeContainer.windowId == packetplayinwindowclick.a() && this.player.activeContainer.c(this.player)) { |
998 1003 | - if (this.player.v()) { |
999 1004 | + boolean cancelled = this.player.v(); // CraftBukkit - see below if |
1000 1005 | + if (false) { // CraftBukkit this.player.v()) { |
1001 1006 | ArrayList arraylist = Lists.newArrayList(); |
1002 1007 | |
1003 1008 | for (int i = 0; i < this.player.activeContainer.c.size(); ++i) { |
1004 - | |
1009 + | |
1005 1010 | |
1006 1011 | this.player.a(this.player.activeContainer, (List) arraylist); |
1007 1012 | } else { |
1008 1013 | - ItemStack itemstack = this.player.activeContainer.clickItem(packetplayinwindowclick.b(), packetplayinwindowclick.c(), packetplayinwindowclick.f(), this.player); |
1009 1014 | + // ItemStack itemstack = this.player.activeContainer.clickItem(packetplayinwindowclick.b(), packetplayinwindowclick.c(), packetplayinwindowclick.f(), this.player); |
1010 1015 | + // CraftBukkit start - Call InventoryClickEvent |
1011 1016 | + if (packetplayinwindowclick.b() < -1 && packetplayinwindowclick.b() != -999) { |
1012 1017 | + return; |
1013 1018 | + } |
1014 1019 | + |
1266 1271 | + if (event instanceof CraftItemEvent) { |
1267 1272 | + // Need to update the inventory on crafting to |
1268 1273 | + // correctly support custom recipes |
1269 1274 | + player.updateInventory(player.activeContainer); |
1270 1275 | + } |
1271 1276 | + } |
1272 1277 | + // CraftBukkit end |
1273 1278 | |
1274 1279 | if (ItemStack.matches(packetplayinwindowclick.e(), itemstack)) { |
1275 1280 | this.player.playerConnection.sendPacket(new PacketPlayOutTransaction(packetplayinwindowclick.a(), packetplayinwindowclick.d(), true)); |
1276 - | |
1281 + | |
1277 1282 | } |
1278 1283 | |
1279 1284 | boolean flag1 = packetplayinsetcreativeslot.a() >= 1 && packetplayinsetcreativeslot.a() < 36 + PlayerInventory.getHotbarSize(); |
1280 1285 | - boolean flag2 = itemstack == null || itemstack.getItem() != null; |
1281 1286 | + // CraftBukkit - Add invalidItems check |
1282 1287 | + boolean flag2 = itemstack == null || itemstack.getItem() != null && !invalidItems.contains(Item.getId(itemstack.getItem())); |
1283 1288 | boolean flag3 = itemstack == null || itemstack.getData() >= 0 && itemstack.count <= 64 && itemstack.count > 0; |
1284 1289 | + // CraftBukkit start - Call click event |
1285 1290 | + if (flag || (flag1 && !ItemStack.matches(this.player.defaultContainer.getSlot(packetplayinsetcreativeslot.a()).getItem(), packetplayinsetcreativeslot.getItemStack()))) { // Insist on valid slot |
1286 1291 | + |
1316 1321 | + this.player.playerConnection.sendPacket(new PacketPlayOutSetSlot(this.player.defaultContainer.windowId, packetplayinsetcreativeslot.a(), this.player.defaultContainer.getSlot(packetplayinsetcreativeslot.a()).getItem())); |
1317 1322 | + this.player.playerConnection.sendPacket(new PacketPlayOutSetSlot(-1, -1, null)); |
1318 1323 | + } |
1319 1324 | + return; |
1320 1325 | + } |
1321 1326 | + } |
1322 1327 | + // CraftBukkit end |
1323 1328 | |
1324 1329 | if (flag1 && flag2 && flag3) { |
1325 1330 | if (itemstack == null) { |
1326 - | |
1331 + | |
1327 1332 | } |
1328 1333 | |
1329 1334 | public void a(PacketPlayInTransaction packetplayintransaction) { |
1330 1335 | + if (this.player.dead) return; // CraftBukkit |
1331 1336 | PlayerConnectionUtils.ensureMainThread(packetplayintransaction, this, this.player.u()); |
1332 1337 | Short oshort = (Short) this.n.get(this.player.activeContainer.windowId); |
1333 1338 | |
1334 - | |
1339 + | |
1335 1340 | } |
1336 1341 | |
1337 1342 | public void a(PacketPlayInUpdateSign packetplayinupdatesign) { |
1338 1343 | + if (this.player.dead) return; // CraftBukkit |
1339 1344 | PlayerConnectionUtils.ensureMainThread(packetplayinupdatesign, this, this.player.u()); |
1340 1345 | this.player.z(); |
1341 1346 | WorldServer worldserver = this.minecraftServer.getWorldServer(this.player.dimension); |
1342 - | |
1347 + | |
1343 1348 | |
1344 1349 | if (!tileentitysign.b() || tileentitysign.c() != this.player) { |
1345 1350 | this.minecraftServer.warning("Player " + this.player.getName() + " just tried to change non-editable sign"); |
1346 1351 | + this.sendPacket(new PacketPlayOutUpdateSign(tileentity.world, packetplayinupdatesign.a(), tileentitysign.lines)); // CraftBukkit |
1347 1352 | return; |
1348 1353 | } |
1349 1354 | |
1350 1355 | IChatBaseComponent[] aichatbasecomponent = packetplayinupdatesign.b(); |
1351 1356 | |
1352 1357 | + // CraftBukkit start |
1364 1369 | + |
1365 1370 | + if (!event.isCancelled()) { |
1366 1371 | + System.arraycopy(org.bukkit.craftbukkit.block.CraftSign.sanitizeLines(event.getLines()), 0, tileentitysign.lines, 0, 4); |
1367 1372 | + tileentitysign.isEditable = false; |
1368 1373 | } |
1369 1374 | + // System.arraycopy(packetplayinupdatesign.b(), 0, tileentitysign.lines, 0, 4); |
1370 1375 | + // CraftBukkit end |
1371 1376 | |
1372 1377 | tileentitysign.update(); |
1373 1378 | worldserver.notify(blockposition); |
1374 - | |
1379 + | |
1375 1380 | |
1376 1381 | public void a(PacketPlayInAbilities packetplayinabilities) { |
1377 1382 | PlayerConnectionUtils.ensureMainThread(packetplayinabilities, this, this.player.u()); |
1378 1383 | - this.player.abilities.isFlying = packetplayinabilities.isFlying() && this.player.abilities.canFly; |
1379 1384 | + // CraftBukkit start |
1380 1385 | + if (this.player.abilities.canFly && this.player.abilities.isFlying != packetplayinabilities.isFlying()) { |
1381 1386 | + PlayerToggleFlightEvent event = new PlayerToggleFlightEvent(this.server.getPlayer(this.player), packetplayinabilities.isFlying()); |
1382 1387 | + this.server.getPluginManager().callEvent(event); |
1383 1388 | + if (!event.isCancelled()) { |
1384 1389 | + this.player.abilities.isFlying = packetplayinabilities.isFlying(); // Actually set the player's flying status |
1393 1398 | PlayerConnectionUtils.ensureMainThread(packetplayintabcomplete, this, this.player.u()); |
1394 1399 | + // CraftBukkit start |
1395 1400 | + if (chatSpamField.addAndGet(this, 10) > 500 && !this.minecraftServer.getPlayerList().isOp(this.player.getProfile())) { |
1396 1401 | + this.disconnect("disconnect.spam"); |
1397 1402 | + return; |
1398 1403 | + } |
1399 1404 | + // CraftBukkit end |
1400 1405 | ArrayList arraylist = Lists.newArrayList(); |
1401 1406 | Iterator iterator = this.minecraftServer.tabCompleteCommand(this.player, packetplayintabcomplete.a(), packetplayintabcomplete.b()).iterator(); |
1402 1407 | |
1403 - | |
1408 + | |
1404 1409 | itemstack1 = this.player.inventory.getItemInHand(); |
1405 1410 | if (itemstack1 != null) { |
1406 1411 | if (itemstack.getItem() == Items.WRITABLE_BOOK && itemstack.getItem() == itemstack1.getItem()) { |
1407 1412 | + itemstack1 = new ItemStack(Items.WRITABLE_BOOK); // CraftBukkit |
1408 1413 | itemstack1.a("pages", (NBTBase) itemstack.getTag().getList("pages", 8)); |
1409 1414 | + CraftEventFactory.handleEditBookEvent(player, itemstack1); // CraftBukkit |
1410 1415 | } |
1411 1416 | |
1412 1417 | return; |
1413 1418 | } |
1414 1419 | } catch (Exception exception) { |
1415 1420 | PlayerConnection.c.error("Couldn\'t handle book info", exception); |
1416 1421 | + this.disconnect("Invalid book data!"); // CraftBukkit |
1417 1422 | return; |
1418 1423 | } finally { |
1419 1424 | packetdataserializer.release(); |
1420 - | |
1425 + | |
1421 1426 | itemstack1 = this.player.inventory.getItemInHand(); |
1422 1427 | if (itemstack1 != null) { |
1423 1428 | if (itemstack.getItem() == Items.WRITTEN_BOOK && itemstack1.getItem() == Items.WRITABLE_BOOK) { |
1424 1429 | + // CraftBukkit start |
1425 1430 | + itemstack1 = new ItemStack(Items.WRITTEN_BOOK); |
1426 1431 | itemstack1.a("author", (NBTBase) (new NBTTagString(this.player.getName()))); |
1427 1432 | itemstack1.a("title", (NBTBase) (new NBTTagString(itemstack.getTag().getString("title")))); |
1428 1433 | itemstack1.a("pages", (NBTBase) itemstack.getTag().getList("pages", 8)); |
1429 1434 | itemstack1.setItem(Items.WRITTEN_BOOK); |
1430 1435 | + CraftEventFactory.handleEditBookEvent(player, itemstack1); |
1431 1436 | + // CraftBukkit end |
1432 1437 | } |
1433 1438 | |
1434 1439 | return; |
1435 1440 | } |
1436 1441 | } catch (Exception exception1) { |
1437 1442 | PlayerConnection.c.error("Couldn\'t sign book", exception1); |
1438 1443 | + this.disconnect("Invalid book data!"); // CraftBukkit |
1439 1444 | return; |
1440 1445 | } finally { |
1441 1446 | packetdataserializer.release(); |
1442 - | |
1447 + | |
1443 1448 | } |
1444 1449 | } catch (Exception exception2) { |
1445 1450 | PlayerConnection.c.error("Couldn\'t select trade", exception2); |
1446 1451 | + this.disconnect("Invalid trade data!"); // CraftBukkit |
1447 1452 | } |
1448 1453 | } else if ("MC|AdvCdm".equals(packetplayincustompayload.a())) { |
1449 1454 | if (!this.minecraftServer.getEnableCommandBlock()) { |
1450 1455 | this.player.sendMessage(new ChatMessage("advMode.notEnabled", new Object[0])); |
1451 1456 | - } else if (this.player.a(2, "") && this.player.abilities.canInstantlyBuild) { |
1452 1457 | + } else if (this.player.getBukkitEntity().isOp() && this.player.abilities.canInstantlyBuild) { // CraftBukkit - Change to Bukkit OP versus Vanilla OP |
1453 1458 | packetdataserializer = packetplayincustompayload.b(); |
1454 1459 | |
1455 1460 | try { |
1456 - | |
1461 + | |
1457 1462 | } |
1458 1463 | } catch (Exception exception3) { |
1459 1464 | PlayerConnection.c.error("Couldn\'t set command block", exception3); |
1460 1465 | + this.disconnect("Invalid CommandBlock data!"); // CraftBukkit |
1461 1466 | } finally { |
1462 1467 | packetdataserializer.release(); |
1463 1468 | } |
1464 - | |
1469 + | |
1465 1470 | } |
1466 1471 | } catch (Exception exception4) { |
1467 1472 | PlayerConnection.c.error("Couldn\'t set beacon", exception4); |
1468 1473 | + this.disconnect("Invalid beacon data!"); // CraftBukkit |
1469 1474 | } |
1470 1475 | } |
1471 1476 | } else if ("MC|ItemName".equals(packetplayincustompayload.a()) && this.player.activeContainer instanceof ContainerAnvil) { |
1472 - | |
1477 + | |
1473 1478 | containeranvil.a(""); |
1474 1479 | } |
1475 1480 | } |
1476 1481 | + // CraftBukkit start |
1477 1482 | + else if (packetplayincustompayload.a().equals("REGISTER")) { |
1478 1483 | + String channels = packetplayincustompayload.b().toString(com.google.common.base.Charsets.UTF_8); |
1479 1484 | + for (String channel : channels.split("\0")) { |
1480 1485 | + getPlayer().addChannel(channel); |
1481 1486 | + } |
1482 1487 | + } else if (packetplayincustompayload.a().equals("UNREGISTER")) { |