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>
This commit is contained in:
@@ -114,7 +114,7 @@
|
|||||||
@Nullable
|
@Nullable
|
||||||
private Vec3 startingToFallPosition;
|
private Vec3 startingToFallPosition;
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -258,7 +293,31 @@
|
@@ -258,6 +293,30 @@
|
||||||
private final CommandSource commandSource;
|
private final CommandSource commandSource;
|
||||||
private int containerCounter;
|
private int containerCounter;
|
||||||
public boolean wonGame;
|
public boolean wonGame;
|
||||||
@@ -123,7 +123,7 @@
|
|||||||
+ public boolean queueHealthUpdatePacket;
|
+ public boolean queueHealthUpdatePacket;
|
||||||
+ public net.minecraft.network.protocol.game.ClientboundSetHealthPacket queuedHealthUpdatePacket;
|
+ public net.minecraft.network.protocol.game.ClientboundSetHealthPacket queuedHealthUpdatePacket;
|
||||||
+ // Paper end - cancellable death event
|
+ // Paper end - cancellable death event
|
||||||
|
+
|
||||||
+ // CraftBukkit start
|
+ // CraftBukkit start
|
||||||
+ public CraftPlayer.TransferCookieConnection transferCookieConnection;
|
+ public CraftPlayer.TransferCookieConnection transferCookieConnection;
|
||||||
+ public String displayName;
|
+ public String displayName;
|
||||||
@@ -142,10 +142,9 @@
|
|||||||
+ // CraftBukkit end
|
+ // CraftBukkit end
|
||||||
+ public boolean isRealPlayer; // Paper
|
+ public boolean isRealPlayer; // Paper
|
||||||
+ public com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper - PlayerNaturallySpawnCreaturesEvent
|
+ public com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper - PlayerNaturallySpawnCreaturesEvent
|
||||||
+
|
|
||||||
public ServerPlayer(MinecraftServer server, ServerLevel world, GameProfile profile, ClientInformation clientOptions) {
|
public ServerPlayer(MinecraftServer server, ServerLevel world, GameProfile profile, ClientInformation clientOptions) {
|
||||||
super(world, world.getSharedSpawnPos(), world.getSharedSpawnAngle(), profile);
|
super(world, world.getSharedSpawnPos(), world.getSharedSpawnAngle(), profile);
|
||||||
this.chatVisibility = ChatVisiblity.FULL;
|
|
||||||
@@ -266,7 +325,7 @@
|
@@ -266,7 +325,7 @@
|
||||||
this.canChatColor = true;
|
this.canChatColor = true;
|
||||||
this.lastActionTime = Util.getMillis();
|
this.lastActionTime = Util.getMillis();
|
||||||
@@ -380,12 +379,10 @@
|
|||||||
Logger logger = ServerPlayer.LOGGER;
|
Logger logger = ServerPlayer.LOGGER;
|
||||||
|
|
||||||
Objects.requireNonNull(logger);
|
Objects.requireNonNull(logger);
|
||||||
@@ -684,7 +833,30 @@
|
@@ -686,6 +835,29 @@
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ // CraftBukkit start - World fallback code, either respawn location or global spawn
|
+ // CraftBukkit start - World fallback code, either respawn location or global spawn
|
||||||
+ public void spawnIn(Level world) {
|
+ public void spawnIn(Level world) {
|
||||||
+ this.setLevel(world);
|
+ this.setLevel(world);
|
||||||
@@ -406,11 +403,12 @@
|
|||||||
+ this.setPos(position);
|
+ this.setPos(position);
|
||||||
+ }
|
+ }
|
||||||
+ this.gameMode.setLevel((ServerLevel) world);
|
+ this.gameMode.setLevel((ServerLevel) world);
|
||||||
}
|
+ }
|
||||||
+ // CraftBukkit end
|
+ // CraftBukkit end
|
||||||
|
+
|
||||||
public void setExperiencePoints(int points) {
|
public void setExperiencePoints(int points) {
|
||||||
float f = (float) this.getXpNeededForNextLevel();
|
float f = (float) this.getXpNeededForNextLevel();
|
||||||
|
float f1 = (f - 1.0F) / f;
|
||||||
@@ -744,6 +916,11 @@
|
@@ -744,6 +916,11 @@
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -448,19 +446,19 @@
|
|||||||
this.lastSentHealth = this.getHealth();
|
this.lastSentHealth = this.getHealth();
|
||||||
this.lastSentFood = this.foodData.getFoodLevel();
|
this.lastSentFood = this.foodData.getFoodLevel();
|
||||||
this.lastFoodSaturationZero = this.foodData.getSaturationLevel() == 0.0F;
|
this.lastFoodSaturationZero = this.foodData.getSaturationLevel() == 0.0F;
|
||||||
@@ -851,6 +1032,12 @@
|
@@ -850,6 +1031,12 @@
|
||||||
|
this.lastRecordedExperience = this.totalExperience;
|
||||||
this.updateScoreForCriteria(ObjectiveCriteria.EXPERIENCE, Mth.ceil((float) this.lastRecordedExperience));
|
this.updateScoreForCriteria(ObjectiveCriteria.EXPERIENCE, Mth.ceil((float) this.lastRecordedExperience));
|
||||||
}
|
}
|
||||||
|
+
|
||||||
+ // CraftBukkit start - Force max health updates
|
+ // CraftBukkit start - Force max health updates
|
||||||
+ if (this.maxHealthCache != this.getMaxHealth()) {
|
+ if (this.maxHealthCache != this.getMaxHealth()) {
|
||||||
+ this.getBukkitEntity().updateScaledHealth();
|
+ this.getBukkitEntity().updateScaledHealth();
|
||||||
+ }
|
+ }
|
||||||
+ // CraftBukkit end
|
+ // CraftBukkit end
|
||||||
+
|
|
||||||
if (this.experienceLevel != this.lastRecordedLevel) {
|
if (this.experienceLevel != this.lastRecordedLevel) {
|
||||||
this.lastRecordedLevel = this.experienceLevel;
|
this.lastRecordedLevel = this.experienceLevel;
|
||||||
this.updateScoreForCriteria(ObjectiveCriteria.LEVEL, Mth.ceil((float) this.lastRecordedLevel));
|
|
||||||
@@ -865,6 +1052,20 @@
|
@@ -865,6 +1052,20 @@
|
||||||
CriteriaTriggers.LOCATION.trigger(this);
|
CriteriaTriggers.LOCATION.trigger(this);
|
||||||
}
|
}
|
||||||
@@ -545,12 +543,12 @@
|
|||||||
+ }
|
+ }
|
||||||
+ this.gameEvent(GameEvent.ENTITY_DIE); // moved from the top of this method
|
+ this.gameEvent(GameEvent.ENTITY_DIE); // moved from the top of this method
|
||||||
+ // Paper end
|
+ // Paper end
|
||||||
|
+
|
||||||
+ // SPIGOT-943 - only call if they have an inventory open
|
+ // SPIGOT-943 - only call if they have an inventory open
|
||||||
+ if (this.containerMenu != this.inventoryMenu) {
|
+ if (this.containerMenu != this.inventoryMenu) {
|
||||||
+ this.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.DEATH); // Paper - Inventory close reason
|
+ this.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.DEATH); // Paper - Inventory close reason
|
||||||
+ }
|
+ }
|
||||||
+
|
|
||||||
+ net.kyori.adventure.text.Component deathMessage = event.deathMessage() != null ? event.deathMessage() : net.kyori.adventure.text.Component.empty(); // Paper - Adventure
|
+ net.kyori.adventure.text.Component deathMessage = event.deathMessage() != null ? event.deathMessage() : net.kyori.adventure.text.Component.empty(); // Paper - Adventure
|
||||||
+
|
+
|
||||||
+ if (deathMessage != null && deathMessage != net.kyori.adventure.text.Component.empty() && flag) { // Paper - Adventure // TODO: allow plugins to override?
|
+ if (deathMessage != null && deathMessage != net.kyori.adventure.text.Component.empty() && flag) { // Paper - Adventure // TODO: allow plugins to override?
|
||||||
@@ -1291,7 +1289,27 @@
|
|||||||
this.requestedViewDistance = clientOptions.viewDistance();
|
this.requestedViewDistance = clientOptions.viewDistance();
|
||||||
this.chatVisibility = clientOptions.chatVisibility();
|
this.chatVisibility = clientOptions.chatVisibility();
|
||||||
this.canChatColor = clientOptions.chatColors();
|
this.canChatColor = clientOptions.chatColors();
|
||||||
@@ -1962,7 +2426,7 @@
|
@@ -1957,12 +2421,27 @@
|
||||||
|
|
||||||
|
this.camera = (Entity) (entity == null ? this : entity);
|
||||||
|
if (entity1 != this.camera) {
|
||||||
|
+ // Paper start - Add PlayerStartSpectatingEntityEvent and PlayerStopSpectatingEntity
|
||||||
|
+ if (this.camera == this) {
|
||||||
|
+ com.destroystokyo.paper.event.player.PlayerStopSpectatingEntityEvent playerStopSpectatingEntityEvent = new com.destroystokyo.paper.event.player.PlayerStopSpectatingEntityEvent(this.getBukkitEntity(), entity1.getBukkitEntity());
|
||||||
|
+ if (!playerStopSpectatingEntityEvent.callEvent()) {
|
||||||
|
+ this.camera = entity1; // rollback camera entity again
|
||||||
|
+ 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()) {
|
||||||
|
+ this.camera = entity1; // rollback camera entity again
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ // Paper end - Add PlayerStartSpectatingEntityEvent and PlayerStopSpectatingEntity
|
||||||
|
Level world = this.camera.level();
|
||||||
|
|
||||||
if (world instanceof ServerLevel) {
|
if (world instanceof ServerLevel) {
|
||||||
ServerLevel worldserver = (ServerLevel) world;
|
ServerLevel worldserver = (ServerLevel) world;
|
||||||
|
|
||||||
@@ -1300,7 +1318,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (entity != null) {
|
if (entity != null) {
|
||||||
@@ -1999,11 +2463,11 @@
|
@@ -1999,11 +2478,11 @@
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public Component getTabListDisplayName() {
|
public Component getTabListDisplayName() {
|
||||||
@@ -1314,7 +1332,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -2046,17 +2510,43 @@
|
@@ -2046,17 +2525,43 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRespawnPosition(ResourceKey<Level> dimension, @Nullable BlockPos pos, float angle, boolean forced, boolean sendMessage) {
|
public void setRespawnPosition(ResourceKey<Level> dimension, @Nullable BlockPos pos, float angle, boolean forced, boolean sendMessage) {
|
||||||
@@ -1365,7 +1383,7 @@
|
|||||||
} else {
|
} else {
|
||||||
this.respawnPosition = null;
|
this.respawnPosition = null;
|
||||||
this.respawnDimension = Level.OVERWORLD;
|
this.respawnDimension = Level.OVERWORLD;
|
||||||
@@ -2088,18 +2578,44 @@
|
@@ -2088,18 +2593,44 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -1414,7 +1432,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.awardStat(Stats.DROP);
|
this.awardStat(Stats.DROP);
|
||||||
@@ -2375,16 +2891,160 @@
|
@@ -2375,16 +2906,160 @@
|
||||||
return TicketType.ENDER_PEARL.timeout();
|
return TicketType.ENDER_PEARL.timeout();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1447,8 +1465,8 @@
|
|||||||
+ } else {
|
+ } else {
|
||||||
+ // Adds timeOffset to the beginning of this day.
|
+ // Adds timeOffset to the beginning of this day.
|
||||||
+ return this.level().getDayTime() - (this.level().getDayTime() % 24000) + this.timeOffset;
|
+ return this.level().getDayTime() - (this.level().getDayTime() % 24000) + this.timeOffset;
|
||||||
}
|
+ }
|
||||||
}
|
+ }
|
||||||
+
|
+
|
||||||
+ public WeatherType weather = null;
|
+ public WeatherType weather = null;
|
||||||
+
|
+
|
||||||
@@ -1469,8 +1487,8 @@
|
|||||||
+ this.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.STOP_RAINING, 0));
|
+ this.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.STOP_RAINING, 0));
|
||||||
+ } else {
|
+ } else {
|
||||||
+ this.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.START_RAINING, 0));
|
+ this.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.START_RAINING, 0));
|
||||||
+ }
|
}
|
||||||
+ }
|
}
|
||||||
+
|
+
|
||||||
+ private float pluginRainPosition;
|
+ private float pluginRainPosition;
|
||||||
+ private float pluginRainPositionPrevious;
|
+ private float pluginRainPositionPrevious;
|
||||||
|
|||||||
Reference in New Issue
Block a user