f521a18a17
Upstream has released updates that appear to apply and compile correctly. This update has not been tested by PaperMC and as with ANY update, please do your own testing Bukkit Changes: 75a0ee4f SPIGOT-6691: Material.LAVA_CAULDRON is not Levelled CraftBukkit Changes: e1c96e50 SPIGOT-6682: Blocking with shield not reset after die 97f629b6 SPIGOT-6220: Structures in the world with custom generator not work 85379258 Increase outdated build delay f7f8dce4 SPIGOT-6552: Some inventory types reset cursor on switch
88 Zeilen
4.3 KiB
Diff
88 Zeilen
4.3 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Caleb Bassham <caleb.bassham@gmail.com>
|
|
Date: Fri, 28 Sep 2018 02:32:19 -0500
|
|
Subject: [PATCH] Call player spectator target events and improve
|
|
implementation
|
|
|
|
Use a proper teleport for teleporting to entities in different
|
|
worlds.
|
|
|
|
Implementation improvements authored by Spottedleaf <Spottedleaf@users.noreply.github.com>
|
|
Validate that the target entity is valid and deny spectate
|
|
requests from frozen players.
|
|
|
|
Also, make sure the entity is spawned to the client before
|
|
sending the camera packet. If the entity isn't spawned clientside
|
|
when it receives the camera packet, then the client will not
|
|
spectate the target entity.
|
|
|
|
Co-authored-by: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
|
index e73046e6d322ddc0feb4979ec0038c4a56778ed9..1db6027543a11d46b97b72d0a7a0f37f929c81e1 100644
|
|
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
|
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
|
@@ -1822,14 +1822,58 @@ public class ServerPlayer extends Player {
|
|
}
|
|
|
|
public void setCamera(Entity entity) {
|
|
+ // Paper start - Add PlayerStartSpectatingEntityEvent and PlayerStopSpectatingEntity Event and improve implementation
|
|
Entity entity1 = this.getCamera();
|
|
|
|
- this.camera = (Entity) (entity == null ? this : entity);
|
|
- if (entity1 != this.camera) {
|
|
- this.connection.send(new ClientboundSetCameraPacket(this.camera));
|
|
- this.connection.b(this.camera.getX(), this.camera.getY(), this.camera.getZ(), this.getYRot(), this.getXRot(), TeleportCause.SPECTATE); // CraftBukkit
|
|
+ if (entity == null) {
|
|
+ entity = this;
|
|
}
|
|
|
|
+ if (entity1 == entity) return; // new spec target is the current spec target
|
|
+
|
|
+ if (entity == this) {
|
|
+ com.destroystokyo.paper.event.player.PlayerStopSpectatingEntityEvent playerStopSpectatingEntityEvent = new com.destroystokyo.paper.event.player.PlayerStopSpectatingEntityEvent(this.getBukkitEntity(), entity1.getBukkitEntity());
|
|
+
|
|
+ if (!playerStopSpectatingEntityEvent.callEvent()) {
|
|
+ return;
|
|
+ }
|
|
+ } else {
|
|
+ com.destroystokyo.paper.event.player.PlayerStartSpectatingEntityEvent playerStartSpectatingEntityEvent = new com.destroystokyo.paper.event.player.PlayerStartSpectatingEntityEvent(this.getBukkitEntity(), entity1.getBukkitEntity(), entity.getBukkitEntity());
|
|
+
|
|
+ if (!playerStartSpectatingEntityEvent.callEvent()) {
|
|
+ return;
|
|
+ }
|
|
+ }
|
|
+ // Validate
|
|
+ if (entity != this) {
|
|
+ if (entity.isRemoved() || !entity.valid || entity.level == null) {
|
|
+ MinecraftServer.LOGGER.info("Blocking player " + this + " from spectating invalid entity " + entity);
|
|
+ return;
|
|
+ }
|
|
+ if (this.isImmobile()) {
|
|
+ // use debug: clients might maliciously spam this
|
|
+ MinecraftServer.LOGGER.debug("Blocking frozen player " + this + " from spectating entity " + entity);
|
|
+ return;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ this.camera = entity; // only set after validating state
|
|
+
|
|
+ if (entity != this) {
|
|
+ // Make sure we're in the right place
|
|
+ this.ejectPassengers(); // teleport can fail if we have passengers...
|
|
+ this.getBukkitEntity().teleport(new Location(entity.getCommandSenderWorld().getWorld(), entity.getX(), entity.getY(), entity.getZ(), this.getYRot(), this.getXRot()), TeleportCause.SPECTATE); // Correctly handle cross-world entities from api calls by using CB teleport
|
|
+
|
|
+ // Make sure we're tracking the entity before sending
|
|
+ ChunkMap.TrackedEntity tracker = ((ServerLevel)entity.level).getChunkSource().chunkMap.entityMap.get(entity.getId());
|
|
+ if (tracker != null) { // dumb plugins...
|
|
+ tracker.updatePlayer(this);
|
|
+ }
|
|
+ } else {
|
|
+ this.connection.teleport(this.camera.getX(), this.camera.getY(), this.camera.getZ(), this.getYRot(), this.getXRot(), TeleportCause.SPECTATE); // CraftBukkit
|
|
+ }
|
|
+ this.connection.send(new ClientboundSetCameraPacket(entity));
|
|
+ // Paper end
|
|
}
|
|
|
|
@Override
|