mirror of
https://github.com/PaperMC/Paper.git
synced 2025-07-26 09:42:06 -07:00
patches
fix
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -0,0 +0,0 @@ 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.toString() + " from spectating invalid entity " + entity.toString());
|
||||
+ return;
|
||||
+ }
|
||||
+ if (this.isImmobile()) {
|
||||
+ // use debug: clients might maliciously spam this
|
||||
+ MinecraftServer.LOGGER.debug("Blocking frozen player " + this.toString() + " from spectating entity " + entity.toString());
|
||||
+ 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
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
|
||||
}
|
||||
}
|
||||
|
||||
- private void a(List<TextFilter.FilteredText> list, UnaryOperator<String> unaryoperator, ItemStack itemstack, int slot, ItemStack old) { // CraftBukkit
|
||||
+ public void a(List<TextFilter.FilteredText> list, UnaryOperator<String> unaryoperator, ItemStack itemstack, int slot, ItemStack old) { // CraftBukkit // Paper - make public
|
||||
ListTag nbttaglist = new ListTag();
|
||||
|
||||
if (this.player.isTextFilteringEnabled()) {
|
||||
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
|
||||
this.a(x, y, z, yaw, pitch, PlayerTeleportEvent.TeleportCause.UNKNOWN);
|
||||
}
|
||||
|
||||
+ public final void teleport(double d0, double d1, double d2, float f, float f1, PlayerTeleportEvent.TeleportCause cause) { this.a(d0, d1, d2, f, f1, cause); } // Paper - OBFHELPER
|
||||
public void a(double d0, double d1, double d2, float f, float f1, PlayerTeleportEvent.TeleportCause cause) {
|
||||
this.a(d0, d1, d2, f, f1, Collections.emptySet(), true, cause);
|
||||
}
|
Reference in New Issue
Block a user