and some more patches
This commit is contained in:
parent
76879ba957
commit
9ae92d26b8
15 changed files with 62 additions and 74 deletions
|
@ -1,109 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shane Freeder <theboyetronic@gmail.com>
|
||||
Date: Sun, 18 Nov 2018 15:53:43 +0000
|
||||
Subject: [PATCH] Support cancellation supression of EntityDismount/VehicleExit
|
||||
events"
|
||||
|
||||
Entities must be dismounted before teleportation in order to avoid
|
||||
multiple issues in the server with regards to teleportation, shamefully,
|
||||
too many plugins rely on the events firing, which means that not firing
|
||||
these events caues more issues than it solves;
|
||||
|
||||
In order to counteract this, Entity dismount/exit vehicle events have
|
||||
been modified to supress cancellation (and has a method to allow plugins
|
||||
to check if this has been set), noting that cancellation will be silently
|
||||
surpressed given that plugins are not expecting this event to not be cancellable.
|
||||
|
||||
This is a far from ideal scenario, however: given the current state of this
|
||||
event and other alternatives causing issues elsewhere, I believe that
|
||||
this is going to be the best soultion all around.
|
||||
|
||||
Improvements/suggestions welcome!
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/event/vehicle/VehicleExitEvent.java b/src/main/java/org/bukkit/event/vehicle/VehicleExitEvent.java
|
||||
index 963b9ead4ca0426b2e95c5641b0e89317c48853d..39f6afd2f9cbcff6a74a91a21dcc3e29d2497dd8 100644
|
||||
--- a/src/main/java/org/bukkit/event/vehicle/VehicleExitEvent.java
|
||||
+++ b/src/main/java/org/bukkit/event/vehicle/VehicleExitEvent.java
|
||||
@@ -13,10 +13,18 @@ public class VehicleExitEvent extends VehicleEvent implements Cancellable {
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private boolean cancelled;
|
||||
private final LivingEntity exited;
|
||||
+ private final boolean isCancellable; // Paper
|
||||
|
||||
- public VehicleExitEvent(@NotNull final Vehicle vehicle, @NotNull final LivingEntity exited) {
|
||||
+ public VehicleExitEvent(@NotNull final Vehicle vehicle, @NotNull final LivingEntity exited, boolean isCancellable) { // Paper
|
||||
super(vehicle);
|
||||
this.exited = exited;
|
||||
+ // Paper start
|
||||
+ this.isCancellable = isCancellable;
|
||||
+ }
|
||||
+
|
||||
+ public VehicleExitEvent(@NotNull final Vehicle vehicle, @NotNull final LivingEntity exited) {
|
||||
+ this(vehicle, exited, true);
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -36,9 +44,18 @@ public class VehicleExitEvent extends VehicleEvent implements Cancellable {
|
||||
|
||||
@Override
|
||||
public void setCancelled(boolean cancel) {
|
||||
+ // Paper start
|
||||
+ if (cancel && !isCancellable) {
|
||||
+ return;
|
||||
+ }
|
||||
this.cancelled = cancel;
|
||||
}
|
||||
|
||||
+ public boolean isCancellable() {
|
||||
+ return isCancellable;
|
||||
+ // Paper end
|
||||
+ }
|
||||
+
|
||||
@NotNull
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
diff --git a/src/main/java/org/spigotmc/event/entity/EntityDismountEvent.java b/src/main/java/org/spigotmc/event/entity/EntityDismountEvent.java
|
||||
index 00d8ec81b4ae6ca5e438161ec9135e3c1edea6f4..a7632c8f5cb1bce4be0e456ec34f4a69c5ce80f3 100644
|
||||
--- a/src/main/java/org/spigotmc/event/entity/EntityDismountEvent.java
|
||||
+++ b/src/main/java/org/spigotmc/event/entity/EntityDismountEvent.java
|
||||
@@ -14,10 +14,19 @@ public class EntityDismountEvent extends EntityEvent implements Cancellable {
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private boolean cancelled;
|
||||
private final Entity dismounted;
|
||||
+ private final boolean isCancellable; // Paper
|
||||
|
||||
public EntityDismountEvent(@NotNull Entity what, @NotNull Entity dismounted) {
|
||||
- super(what);
|
||||
+ // Paper start
|
||||
+ this(what, dismounted, true);
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ public EntityDismountEvent(@NotNull Entity what, @NotNull Entity dismounted, boolean isCancellable) {
|
||||
+ // Paper end
|
||||
+ super( what );
|
||||
this.dismounted = dismounted;
|
||||
+ this.isCancellable = isCancellable; // Paper
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -32,9 +41,18 @@ public class EntityDismountEvent extends EntityEvent implements Cancellable {
|
||||
|
||||
@Override
|
||||
public void setCancelled(boolean cancel) {
|
||||
+ // Paper start
|
||||
+ if (cancel && !isCancellable) {
|
||||
+ return;
|
||||
+ }
|
||||
this.cancelled = cancel;
|
||||
}
|
||||
|
||||
+ public boolean isCancellable() {
|
||||
+ return isCancellable;
|
||||
+ // Paper end
|
||||
+ }
|
||||
+
|
||||
@NotNull
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
|
@ -1,66 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Sun, 7 Oct 2018 04:29:51 -0500
|
||||
Subject: [PATCH] Add more Zombie API
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/entity/Zombie.java b/src/main/java/org/bukkit/entity/Zombie.java
|
||||
index a5b20b0454af5ea78e2bb7f16a56c38670c84efb..1217576e6f08abf0175ab800cfca058d5deda116 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Zombie.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Zombie.java
|
||||
@@ -90,4 +90,55 @@ public interface Zombie extends Monster, Ageable {
|
||||
* @param time new conversion time
|
||||
*/
|
||||
void setConversionTime(int time);
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Check if zombie is drowning
|
||||
+ *
|
||||
+ * @return True if zombie conversion process has begun
|
||||
+ */
|
||||
+ boolean isDrowning();
|
||||
+
|
||||
+ /**
|
||||
+ * Make zombie start drowning
|
||||
+ *
|
||||
+ * @param drownedConversionTime Amount of time until zombie converts from drowning
|
||||
+ *
|
||||
+ * @deprecated See {@link #setConversionTime(int)}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ void startDrowning(int drownedConversionTime);
|
||||
+
|
||||
+ /**
|
||||
+ * Stop a zombie from starting the drowning conversion process
|
||||
+ */
|
||||
+ void stopDrowning();
|
||||
+
|
||||
+ /**
|
||||
+ * Set if zombie has its arms raised
|
||||
+ *
|
||||
+ * @param raised True to raise arms
|
||||
+ */
|
||||
+ void setArmsRaised(boolean raised);
|
||||
+
|
||||
+ /**
|
||||
+ * Check if zombie has arms raised
|
||||
+ *
|
||||
+ * @return True if arms are raised
|
||||
+ */
|
||||
+ boolean isArmsRaised();
|
||||
+
|
||||
+ /**
|
||||
+ * Check if this zombie will burn in the sunlight
|
||||
+ *
|
||||
+ * @return True if zombie will burn in sunlight
|
||||
+ */
|
||||
+ boolean shouldBurnInDay();
|
||||
+
|
||||
+ /**
|
||||
+ * Set if this zombie should burn in the sunlight
|
||||
+ *
|
||||
+ * @param shouldBurnInDay True to burn in sunlight
|
||||
+ */
|
||||
+ void setShouldBurnInDay(boolean shouldBurnInDay);
|
||||
+ // Paper end
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: DoNotSpamPls <7570108+DoNotSpamPls@users.noreply.github.com>
|
||||
Date: Tue, 23 Oct 2018 19:32:55 +0300
|
||||
Subject: [PATCH] Change the reserved channel check to be sensible
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/plugin/messaging/StandardMessenger.java b/src/main/java/org/bukkit/plugin/messaging/StandardMessenger.java
|
||||
index 1d061412cdafa28c6940c7433747ab1dabe23de1..6fda7f3aa68e76af64362e9afed70fc6a5e92986 100644
|
||||
--- a/src/main/java/org/bukkit/plugin/messaging/StandardMessenger.java
|
||||
+++ b/src/main/java/org/bukkit/plugin/messaging/StandardMessenger.java
|
||||
@@ -172,7 +172,7 @@ public class StandardMessenger implements Messenger {
|
||||
public boolean isReservedChannel(@NotNull String channel) {
|
||||
channel = validateAndCorrectChannel(channel);
|
||||
|
||||
- return channel.contains("minecraft") && !channel.equals("minecraft:brand");
|
||||
+ return channel.equals("minecraft:register") || channel.equals("minecraft:unregister"); // Paper
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/test/java/org/bukkit/plugin/messaging/StandardMessengerTest.java b/src/test/java/org/bukkit/plugin/messaging/StandardMessengerTest.java
|
||||
index dce3d619a6f1791197e44277c2dee9eaf19ff56f..7e2335ed8acc692af1e70eddcf97ee7a56e30f68 100644
|
||||
--- a/src/test/java/org/bukkit/plugin/messaging/StandardMessengerTest.java
|
||||
+++ b/src/test/java/org/bukkit/plugin/messaging/StandardMessengerTest.java
|
||||
@@ -25,8 +25,8 @@ public class StandardMessengerTest {
|
||||
assertTrue(messenger.isReservedChannel("minecraft:register"));
|
||||
assertFalse(messenger.isReservedChannel("test:register"));
|
||||
assertTrue(messenger.isReservedChannel("minecraft:unregister"));
|
||||
- assertFalse(messenger.isReservedChannel("test:nregister"));
|
||||
- assertTrue(messenger.isReservedChannel("minecraft:something"));
|
||||
+ assertFalse(messenger.isReservedChannel("test:unregister")); // Paper - fix typo
|
||||
+ assertFalse(messenger.isReservedChannel("minecraft:something")); // Paper - now less strict
|
||||
assertFalse(messenger.isReservedChannel("minecraft:brand"));
|
||||
}
|
||||
|
|
@ -1,136 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
Date: Sun, 7 Oct 2018 12:05:06 -0700
|
||||
Subject: [PATCH] Add PlayerConnectionCloseEvent
|
||||
|
||||
This event is invoked when a player has disconnected. It is guaranteed that,
|
||||
if the server is in online-mode, that the provided uuid and username have been
|
||||
validated.
|
||||
|
||||
The event is invoked for players who have not yet logged into the world, whereas
|
||||
PlayerQuitEvent is only invoked on players who have logged into the world.
|
||||
|
||||
The event is invoked for players who have already logged into the world,
|
||||
although whether or not the player exists in the world at the time of
|
||||
firing is undefined. (That is, whether the plugin can retrieve a Player object
|
||||
using the event parameters is undefined). However, it is guaranteed that this
|
||||
event is invoked AFTER PlayerQuitEvent, if the player has already logged into
|
||||
the world.
|
||||
|
||||
This event is guaranteed to never fire unless AsyncPlayerPreLoginEvent has
|
||||
been called beforehand, and this event may not be called in parallel with
|
||||
AsyncPlayerPreLoginEvent for the same connection.
|
||||
|
||||
Cancelling the AsyncPlayerPreLoginEvent guarantees the corresponding
|
||||
PlayerConnectionCloseEvent is never called.
|
||||
|
||||
The event may be invoked asynchronously or synchronously. As it stands,
|
||||
it is never invoked asynchronously. However, plugins should check
|
||||
Event#isAsynchronous to be future-proof.
|
||||
|
||||
On purpose, the deprecated PlayerPreLoginEvent event is left out of the
|
||||
API spec for this event. Plugins should not be using that event, and
|
||||
how PlayerPreLoginEvent interacts with PlayerConnectionCloseEvent
|
||||
is undefined.
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/player/PlayerConnectionCloseEvent.java b/src/main/java/com/destroystokyo/paper/event/player/PlayerConnectionCloseEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..12c1c6fe9dc8dc5f5faf6dcf99f6857219ef22b8
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/player/PlayerConnectionCloseEvent.java
|
||||
@@ -0,0 +1,95 @@
|
||||
+package com.destroystokyo.paper.event.player;
|
||||
+
|
||||
+import org.bukkit.event.Event;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+
|
||||
+import java.net.InetAddress;
|
||||
+import java.util.UUID;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * <p>
|
||||
+ * This event is invoked when a player has disconnected. It is guaranteed that,
|
||||
+ * if the server is in online-mode, that the provided uuid and username have been
|
||||
+ * validated.
|
||||
+ * </p>
|
||||
+ *
|
||||
+ * <p>
|
||||
+ * The event is invoked for players who have not yet logged into the world, whereas
|
||||
+ * {@link org.bukkit.event.player.PlayerQuitEvent} is only invoked on players who have logged into the world.
|
||||
+ * </p>
|
||||
+ *
|
||||
+ * <p>
|
||||
+ * The event is invoked for players who have already logged into the world,
|
||||
+ * although whether or not the player exists in the world at the time of
|
||||
+ * firing is undefined. (That is, whether the plugin can retrieve a Player object
|
||||
+ * using the event parameters is undefined). However, it is guaranteed that this
|
||||
+ * event is invoked AFTER {@link org.bukkit.event.player.PlayerQuitEvent}, if the player has already logged into the world.
|
||||
+ * </p>
|
||||
+ *
|
||||
+ * <p>
|
||||
+ * This event is guaranteed to never fire unless {@link org.bukkit.event.player.AsyncPlayerPreLoginEvent} has
|
||||
+ * been fired beforehand, and this event may not be called in parallel with
|
||||
+ * {@link org.bukkit.event.player.AsyncPlayerPreLoginEvent} for the same connection.
|
||||
+ * </p>
|
||||
+ *
|
||||
+ * <p>
|
||||
+ * Cancelling the {@link org.bukkit.event.player.AsyncPlayerPreLoginEvent} guarantees the corresponding
|
||||
+ * {@code PlayerConnectionCloseEvent} is never called.
|
||||
+ * </p>
|
||||
+ *
|
||||
+ * <p>
|
||||
+ * The event may be invoked asynchronously or synchronously. Plugins should check
|
||||
+ * {@link Event#isAsynchronous()} and handle accordingly.
|
||||
+ * </p>
|
||||
+ */
|
||||
+public class PlayerConnectionCloseEvent extends Event {
|
||||
+
|
||||
+ private static final HandlerList HANDLERS = new HandlerList();
|
||||
+
|
||||
+ @NotNull private final UUID playerUniqueId;
|
||||
+ @NotNull private final String playerName;
|
||||
+ @NotNull private final InetAddress ipAddress;
|
||||
+
|
||||
+ public PlayerConnectionCloseEvent(@NotNull final UUID playerUniqueId, @NotNull final String playerName, @NotNull final InetAddress ipAddress, final boolean async) {
|
||||
+ super(async);
|
||||
+ this.playerUniqueId = playerUniqueId;
|
||||
+ this.playerName = playerName;
|
||||
+ this.ipAddress = ipAddress;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Returns the {@code UUID} of the player disconnecting.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public UUID getPlayerUniqueId() {
|
||||
+ return this.playerUniqueId;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Returns the name of the player disconnecting.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public String getPlayerName() {
|
||||
+ return this.playerName;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Returns the player's IP address.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public InetAddress getIpAddress() {
|
||||
+ return this.ipAddress;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return HANDLERS;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return HANDLERS;
|
||||
+ }
|
||||
+}
|
|
@ -1,62 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <zach@zachbr.io>
|
||||
Date: Wed, 2 Jan 2019 00:31:12 -0600
|
||||
Subject: [PATCH] Add APIs to replace OfflinePlayer#getLastPlayed
|
||||
|
||||
Currently OfflinePlayer#getLastPlayed could more accurately be described
|
||||
as "OfflinePlayer#getLastTimeTheirDataWasSaved".
|
||||
|
||||
The API doc says it should return the last time the server "witnessed"
|
||||
the player, whilst also saying it should return the last time they
|
||||
logged in. The current implementation does neither.
|
||||
|
||||
Given this interesting contradiction in the API documentation and the
|
||||
current defacto implementation, I've elected to deprecate (with no
|
||||
intent to remove) and replace it with two new methods, clearly named and
|
||||
documented as to their purpose.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/OfflinePlayer.java b/src/main/java/org/bukkit/OfflinePlayer.java
|
||||
index 6cf05fed701c67a2c797a4e0839c795802a238a1..3afd5f5c0208a4ee93b5dbfc2aab2b9d2e8a7544 100644
|
||||
--- a/src/main/java/org/bukkit/OfflinePlayer.java
|
||||
+++ b/src/main/java/org/bukkit/OfflinePlayer.java
|
||||
@@ -147,7 +147,9 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio
|
||||
* UTC.
|
||||
*
|
||||
* @return Date of last log-in for this player, or 0
|
||||
+ * @deprecated The API contract is ambiguous and the implementation may or may not return the correct value given this API ambiguity. It is instead recommended use {@link #getLastLogin()} or {@link #getLastSeen()} depending on your needs.
|
||||
*/
|
||||
+ @Deprecated
|
||||
public long getLastPlayed();
|
||||
|
||||
/**
|
||||
@@ -165,6 +167,30 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio
|
||||
*/
|
||||
@Nullable
|
||||
public Location getBedSpawnLocation();
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Gets the last date and time that this player logged into the server.
|
||||
+ * <p>
|
||||
+ * If the player has never played before, this will return 0. Otherwise,
|
||||
+ * it will be the amount of milliseconds since midnight, January 1, 1970
|
||||
+ * UTC.
|
||||
+ *
|
||||
+ * @return last login time
|
||||
+ */
|
||||
+ public long getLastLogin();
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the last date and time that this player was seen on the server.
|
||||
+ * <p>
|
||||
+ * If the player has never played before, this will return 0. If the
|
||||
+ * player is currently online, this will return the current time.
|
||||
+ * Otherwise it will be the amount of milliseconds since midnight,
|
||||
+ * January 1, 1970 UTC.
|
||||
+ *
|
||||
+ * @return last seen time
|
||||
+ */
|
||||
+ public long getLastSeen();
|
||||
+ // Paper end
|
||||
|
||||
/**
|
||||
* Increments the given statistic for this player.
|
|
@ -1,134 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shane Freeder <theboyetronic@gmail.com>
|
||||
Date: Thu, 15 Nov 2018 13:38:37 +0000
|
||||
Subject: [PATCH] force entity dismount during teleportation
|
||||
|
||||
Entities must be dismounted before teleportation in order to avoid
|
||||
multiple issues in the server with regards to teleportation, shamefully,
|
||||
too many plugins rely on the events firing, which means that not firing
|
||||
these events caues more issues than it solves;
|
||||
|
||||
In order to counteract this, Entity dismount/exit vehicle events have
|
||||
been modified to supress cancellation (and has a method to allow plugins
|
||||
to check if this has been set), noting that cancellation will be silently
|
||||
surpressed given that plugins are not expecting this event to not be cancellable.
|
||||
|
||||
This is a far from ideal scenario, however: given the current state of this
|
||||
event and other alternatives causing issues elsewhere, I believe that
|
||||
this is going to be the best soultion all around.
|
||||
|
||||
Improvements/suggestions welcome!
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
index d32e6feca6c39a28f80574e4b080ddd4cbb60fdc..42035548577b7c60806a557dd9f9931ca9584e8c 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -1296,11 +1296,13 @@ public class ServerPlayer extends Player {
|
||||
}
|
||||
}
|
||||
|
||||
- @Override
|
||||
- public void stopRiding() {
|
||||
+ // Paper start
|
||||
+ @Override public void stopRiding() { stopRiding(false); }
|
||||
+ @Override public void stopRiding(boolean suppressCancellation) {
|
||||
+ // Paper end
|
||||
Entity entity = this.getVehicle();
|
||||
|
||||
- super.stopRiding();
|
||||
+ super.stopRiding(suppressCancellation); // Paper
|
||||
Entity entity1 = this.getVehicle();
|
||||
|
||||
if (entity1 != entity && this.connection != null) {
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
index b4f2b969ad30be38c0a9e3f8efd2a57c3e0f7df0..3c7e75b8fc1bfbe08e232fcba412c83f4aba274c 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -2245,12 +2245,15 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n
|
||||
|
||||
}
|
||||
|
||||
- public void removeVehicle() {
|
||||
+ // Paper start
|
||||
+ public void removeVehicle() { stopRiding(false); }
|
||||
+ public void stopRiding(boolean suppressCancellation) {
|
||||
+ // Paper end
|
||||
if (this.vehicle != null) {
|
||||
Entity entity = this.vehicle;
|
||||
|
||||
this.vehicle = null;
|
||||
- if (!entity.removePassenger(this)) this.vehicle = entity; // CraftBukkit
|
||||
+ if (!entity.removePassenger(this, suppressCancellation)) this.vehicle = entity; // CraftBukkit // Paper
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2313,7 +2316,10 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n
|
||||
return true; // CraftBukkit
|
||||
}
|
||||
|
||||
- protected boolean removePassenger(Entity entity) { // CraftBukkit
|
||||
+ // Paper start
|
||||
+ protected boolean removePassenger(Entity entity) { return removePassenger(entity, false);}
|
||||
+ protected boolean removePassenger(Entity entity, boolean suppressCancellation) { // CraftBukkit
|
||||
+ // Paper end
|
||||
if (entity.getVehicle() == this) {
|
||||
throw new IllegalStateException("Use x.stopRiding(y), not y.removePassenger(x)");
|
||||
} else {
|
||||
@@ -2323,7 +2329,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n
|
||||
if (this.getBukkitEntity() instanceof Vehicle && entity.getBukkitEntity() instanceof LivingEntity) {
|
||||
VehicleExitEvent event = new VehicleExitEvent(
|
||||
(Vehicle) this.getBukkitEntity(),
|
||||
- (LivingEntity) entity.getBukkitEntity()
|
||||
+ (LivingEntity) entity.getBukkitEntity(), !suppressCancellation // Paper
|
||||
);
|
||||
// Suppress during worldgen
|
||||
if (this.valid) {
|
||||
@@ -2337,7 +2343,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n
|
||||
}
|
||||
// CraftBukkit end
|
||||
// Spigot start
|
||||
- org.spigotmc.event.entity.EntityDismountEvent event = new org.spigotmc.event.entity.EntityDismountEvent(entity.getBukkitEntity(), this.getBukkitEntity());
|
||||
+ org.spigotmc.event.entity.EntityDismountEvent event = new org.spigotmc.event.entity.EntityDismountEvent(entity.getBukkitEntity(), this.getBukkitEntity(), !suppressCancellation); // Paper
|
||||
// Suppress during worldgen
|
||||
if (this.valid) {
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
index a7aa62e52105b7adb7725f7abeae376df8f7bb3e..472b8db386dfb580734999900562d358e5ea146a 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -3335,11 +3335,13 @@ public abstract class LivingEntity extends Entity {
|
||||
return ((Byte) this.entityData.get(LivingEntity.DATA_LIVING_ENTITY_FLAGS) & 4) != 0;
|
||||
}
|
||||
|
||||
- @Override
|
||||
- public void stopRiding() {
|
||||
+ // Paper start
|
||||
+ @Override public void stopRiding() { stopRiding(false); }
|
||||
+ @Override public void stopRiding(boolean suppressCancellation) {
|
||||
+ // Paper end
|
||||
Entity entity = this.getVehicle();
|
||||
|
||||
- super.stopRiding();
|
||||
+ super.stopRiding(suppressCancellation); // Paper - suppress
|
||||
if (entity != null && entity != this.getVehicle() && !this.level.isClientSide) {
|
||||
this.dismountVehicle(entity);
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
index f5bc151aae4f8335994507c89a094177347dfce1..19b5538e54f1c6073c3478393c1388ffca33291e 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
@@ -1094,9 +1094,11 @@ public abstract class Player extends LivingEntity {
|
||||
return -0.35D;
|
||||
}
|
||||
|
||||
- @Override
|
||||
- public void removeVehicle() {
|
||||
- super.removeVehicle();
|
||||
+ // Paper start
|
||||
+ @Override public void removeVehicle() { stopRiding(false); }
|
||||
+ @Override public void stopRiding(boolean suppressCancellation) {
|
||||
+ // Paper end
|
||||
+ super.stopRiding(suppressCancellation); // Paper - suppress
|
||||
this.boardingCooldown = 0;
|
||||
}
|
||||
|
|
@ -1,115 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Sun, 7 Oct 2018 04:29:59 -0500
|
||||
Subject: [PATCH] Add more Zombie API
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/Zombie.java b/src/main/java/net/minecraft/world/entity/monster/Zombie.java
|
||||
index f17a91a654d11aaace39f04b3f4c3e061a374dc9..96d172c428c6293b346201159422e2a581e350d9 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Zombie.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Zombie.java
|
||||
@@ -96,6 +96,7 @@ public class Zombie extends Monster {
|
||||
private int inWaterTime;
|
||||
public int conversionTime;
|
||||
private int lastTick = MinecraftServer.currentTick; // CraftBukkit - add field
|
||||
+ private boolean shouldBurnInDay = true; // Paper
|
||||
|
||||
public Zombie(EntityType<? extends Zombie> type, Level world) {
|
||||
super(type, world);
|
||||
@@ -264,6 +265,12 @@ public class Zombie extends Monster {
|
||||
super.aiStep();
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ public void stopDrowning() {
|
||||
+ this.conversionTime = -1;
|
||||
+ this.getEntityData().set(Zombie.DATA_DROWNED_CONVERSION_ID, false);
|
||||
+ }
|
||||
+ // Paper end
|
||||
public void startUnderWaterConversion(int ticksUntilWaterConversion) {
|
||||
this.lastTick = MinecraftServer.currentTick; // CraftBukkit
|
||||
this.conversionTime = ticksUntilWaterConversion;
|
||||
@@ -293,9 +300,15 @@ public class Zombie extends Monster {
|
||||
}
|
||||
|
||||
public boolean isSunSensitive() {
|
||||
- return true;
|
||||
+ return this.shouldBurnInDay; // Paper - use api value instead
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ public void setShouldBurnInDay(boolean shouldBurnInDay) {
|
||||
+ this.shouldBurnInDay = shouldBurnInDay;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public boolean hurt(DamageSource source, float amount) {
|
||||
if (!super.hurt(source, amount)) {
|
||||
@@ -415,6 +428,7 @@ public class Zombie extends Monster {
|
||||
nbt.putBoolean("CanBreakDoors", this.canBreakDoors());
|
||||
nbt.putInt("InWaterTime", this.isInWater() ? this.inWaterTime : -1);
|
||||
nbt.putInt("DrownedConversionTime", this.isUnderWaterConverting() ? this.conversionTime : -1);
|
||||
+ nbt.putBoolean("Paper.ShouldBurnInDay", this.shouldBurnInDay); // Paper
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -426,6 +440,11 @@ public class Zombie extends Monster {
|
||||
if (nbt.contains("DrownedConversionTime", 99) && nbt.getInt("DrownedConversionTime") > -1) {
|
||||
this.startUnderWaterConversion(nbt.getInt("DrownedConversionTime"));
|
||||
}
|
||||
+ // Paper start
|
||||
+ if (nbt.contains("Paper.ShouldBurnInDay")) {
|
||||
+ this.shouldBurnInDay = nbt.getBoolean("Paper.ShouldBurnInDay");
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftZombie.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftZombie.java
|
||||
index 2e643e92569512ac4e75c0ef2ee7aa4b688e7356..77e4875484bdaedfba576a6b008245c488b2a112 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftZombie.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftZombie.java
|
||||
@@ -93,6 +93,42 @@ public class CraftZombie extends CraftMonster implements Zombie {
|
||||
@Override
|
||||
public void setAgeLock(boolean b) {
|
||||
}
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public boolean isDrowning() {
|
||||
+ return getHandle().isUnderWaterConverting();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void startDrowning(int drownedConversionTime) {
|
||||
+ getHandle().startUnderWaterConversion(drownedConversionTime);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void stopDrowning() {
|
||||
+ getHandle().stopDrowning();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean shouldBurnInDay() {
|
||||
+ return getHandle().isSunSensitive();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isArmsRaised() {
|
||||
+ return getHandle().isAggressive();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setArmsRaised(final boolean raised) {
|
||||
+ getHandle().setAggressive(raised);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setShouldBurnInDay(boolean shouldBurnInDay) {
|
||||
+ getHandle().setShouldBurnInDay(shouldBurnInDay);
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
@Override
|
||||
public boolean getAgeLock() {
|
|
@ -1,75 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Fri, 16 Nov 2018 23:08:50 -0500
|
||||
Subject: [PATCH] Book Size Limits
|
||||
|
||||
Puts some limits on the size of books.
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
||||
index 769353df1fcdaacecd80085165a1d72f99b577ee..4875e323e8ba52cf91259262b8418310061718ad 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
||||
@@ -368,6 +368,13 @@ public class PaperConfig {
|
||||
}
|
||||
}
|
||||
|
||||
+ public static int maxBookPageSize = 2560;
|
||||
+ public static double maxBookTotalSizeMultiplier = 0.98D;
|
||||
+ private static void maxBookSize() {
|
||||
+ maxBookPageSize = Math.min(8192, getInt("settings.book-size.page-max", maxBookPageSize));
|
||||
+ maxBookTotalSizeMultiplier = getDouble("settings.book-size.total-multiplier", maxBookTotalSizeMultiplier);
|
||||
+ }
|
||||
+
|
||||
public static boolean asyncChunks = false;
|
||||
private static void asyncChunks() {
|
||||
ConfigurationSection section;
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index a615821cf605208c61be27f8bd026437b799de14..0103c76c183d0e866a98c26f2d1cf557ba4f67e8 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -1001,6 +1001,45 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
|
||||
|
||||
@Override
|
||||
public void handleEditBook(ServerboundEditBookPacket packet) {
|
||||
+ // Paper start
|
||||
+ if (!this.cserver.isPrimaryThread()) {
|
||||
+ List<String> pageList = packet.getPages();
|
||||
+ long byteTotal = 0;
|
||||
+ int maxBookPageSize = com.destroystokyo.paper.PaperConfig.maxBookPageSize;
|
||||
+ double multiplier = Math.max(0.3D, Math.min(1D, com.destroystokyo.paper.PaperConfig.maxBookTotalSizeMultiplier));
|
||||
+ long byteAllowed = maxBookPageSize;
|
||||
+ for (String testString : pageList) {
|
||||
+ int byteLength = testString.getBytes(java.nio.charset.StandardCharsets.UTF_8).length;
|
||||
+ if (byteLength > 256 * 4) {
|
||||
+ ServerGamePacketListenerImpl.LOGGER.warn(this.player.getScoreboardName() + " tried to send a book with with a page too large!");
|
||||
+ server.scheduleOnMain(() -> this.disconnect("Book too large!"));
|
||||
+ return;
|
||||
+ }
|
||||
+ byteTotal += byteLength;
|
||||
+ int length = testString.length();
|
||||
+ int multibytes = 0;
|
||||
+ if (byteLength != length) {
|
||||
+ for (char c : testString.toCharArray()) {
|
||||
+ if (c > 127) {
|
||||
+ multibytes++;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ byteAllowed += (maxBookPageSize * Math.min(1, Math.max(0.1D, (double) length / 255D))) * multiplier;
|
||||
+
|
||||
+ if (multibytes > 1) {
|
||||
+ // penalize MB
|
||||
+ byteAllowed -= multibytes;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (byteTotal > byteAllowed) {
|
||||
+ ServerGamePacketListenerImpl.LOGGER.warn(this.player.getScoreboardName() + " tried to send too large of a book. Book Size: " + byteTotal + " - Allowed: "+ byteAllowed + " - Pages: " + pageList.size());
|
||||
+ server.scheduleOnMain(() -> this.disconnect("Book too large!"));
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
// CraftBukkit start
|
||||
if (this.lastBookTick + 20 > MinecraftServer.currentTick) {
|
||||
this.disconnect("Book edited too quickly!");
|
|
@ -1,79 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
Date: Sun, 7 Oct 2018 12:05:28 -0700
|
||||
Subject: [PATCH] Add PlayerConnectionCloseEvent
|
||||
|
||||
This event is invoked when a player has disconnected. It is guaranteed that,
|
||||
if the server is in online-mode, that the provided uuid and username have been
|
||||
validated.
|
||||
|
||||
The event is invoked for players who have not yet logged into the world, whereas
|
||||
PlayerQuitEvent is only invoked on players who have logged into the world.
|
||||
|
||||
The event is invoked for players who have already logged into the world,
|
||||
although whether or not the player exists in the world at the time of
|
||||
firing is undefined. (That is, whether the plugin can retrieve a Player object
|
||||
using the event parameters is undefined). However, it is guaranteed that this
|
||||
event is invoked AFTER PlayerQuitEvent, if the player has already logged into
|
||||
the world.
|
||||
|
||||
This event is guaranteed to never fire unless AsyncPlayerPreLoginEvent has
|
||||
been called beforehand, and this event may not be called in parallel with
|
||||
AsyncPlayerPreLoginEvent for the same connection.
|
||||
|
||||
Cancelling the AsyncPlayerPreLoginEvent guarantees the corresponding
|
||||
PlayerConnectionCloseEvent is never called.
|
||||
|
||||
The event may be invoked asynchronously or synchronously. As it stands,
|
||||
it is never invoked asynchronously. However, plugins should check
|
||||
Event#isAsynchronous to be future-proof.
|
||||
|
||||
On purpose, the deprecated PlayerPreLoginEvent event is left out of the
|
||||
API spec for this event. Plugins should not be using that event, and
|
||||
how PlayerPreLoginEvent interacts with PlayerConnectionCloseEvent
|
||||
is undefined.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/network/Connection.java b/src/main/java/net/minecraft/network/Connection.java
|
||||
index 3b943894750022aa84de8af97db3eebf71db1afa..e5f8c48c8d57ce0df4e7aacdbc3a6d3e9b3cb6e1 100644
|
||||
--- a/src/main/java/net/minecraft/network/Connection.java
|
||||
+++ b/src/main/java/net/minecraft/network/Connection.java
|
||||
@@ -418,6 +418,26 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
this.getPacketListener().onDisconnect(new TranslatableComponent("multiplayer.disconnect.generic"));
|
||||
}
|
||||
this.queue.clear(); // Free up packet queue.
|
||||
+ // Paper start - Add PlayerConnectionCloseEvent
|
||||
+ final PacketListener packetListener = this.getPacketListener();
|
||||
+ if (packetListener instanceof ServerGamePacketListenerImpl) {
|
||||
+ /* Player was logged in */
|
||||
+ final ServerGamePacketListenerImpl playerConnection = (ServerGamePacketListenerImpl) packetListener;
|
||||
+ new com.destroystokyo.paper.event.player.PlayerConnectionCloseEvent(playerConnection.player.getUUID(),
|
||||
+ playerConnection.player.getScoreboardName(), ((java.net.InetSocketAddress)address).getAddress(), false).callEvent();
|
||||
+ } else if (packetListener instanceof ServerLoginPacketListenerImpl) {
|
||||
+ /* Player is login stage */
|
||||
+ final ServerLoginPacketListenerImpl loginListener = (ServerLoginPacketListenerImpl) packetListener;
|
||||
+ switch (loginListener.state) {
|
||||
+ case READY_TO_ACCEPT:
|
||||
+ case DELAY_ACCEPT:
|
||||
+ case ACCEPTED:
|
||||
+ final com.mojang.authlib.GameProfile profile = loginListener.getGameProfile(); /* Should be non-null at this stage */
|
||||
+ new com.destroystokyo.paper.event.player.PlayerConnectionCloseEvent(profile.getId(), profile.getName(),
|
||||
+ ((java.net.InetSocketAddress)address).getAddress(), false).callEvent();
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
index 3fd913f3e963cf2da849a52364356e3b2da11eee..b5d8987d2903086d69bbd6ba8092e568c94be63f 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
@@ -59,7 +59,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener
|
||||
public ServerLoginPacketListenerImpl.State state;
|
||||
private int tick;
|
||||
@Nullable
|
||||
- GameProfile gameProfile;
|
||||
+ GameProfile gameProfile; @Deprecated private void setGameProfile(final GameProfile profile) { this.gameProfile = profile; } @Deprecated public GameProfile getGameProfile() { return this.gameProfile; } // Paper - OBFHELPER
|
||||
private final String serverId;
|
||||
@Nullable
|
||||
private ServerPlayer delayedAcceptPlayer;
|
|
@ -1,30 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shane Freeder <theboyetronic@gmail.com>
|
||||
Date: Tue, 18 Dec 2018 02:15:08 +0000
|
||||
Subject: [PATCH] Prevent Enderman from loading chunks
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
|
||||
index de167655a556a700bdc7d92fa54b802924b2a61a..b27e2e1e2270a7a2f3e36b90a19237e39e4175b8 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
|
||||
@@ -465,7 +465,8 @@ public class EnderMan extends Monster implements NeutralMob {
|
||||
int j = Mth.floor(this.enderman.getY() + random.nextDouble() * 2.0D);
|
||||
int k = Mth.floor(this.enderman.getZ() - 1.0D + random.nextDouble() * 2.0D);
|
||||
BlockPos blockposition = new BlockPos(i, j, k);
|
||||
- BlockState iblockdata = world.getBlockState(blockposition);
|
||||
+ BlockState iblockdata = world.getTypeIfLoaded(blockposition); // Paper
|
||||
+ if (iblockdata == null) return; // Paper
|
||||
BlockPos blockposition1 = blockposition.below();
|
||||
BlockState iblockdata1 = world.getBlockState(blockposition1);
|
||||
BlockState iblockdata2 = this.enderman.getCarriedBlock();
|
||||
@@ -511,7 +512,8 @@ public class EnderMan extends Monster implements NeutralMob {
|
||||
int j = Mth.floor(this.enderman.getY() + random.nextDouble() * 3.0D);
|
||||
int k = Mth.floor(this.enderman.getZ() - 2.0D + random.nextDouble() * 4.0D);
|
||||
BlockPos blockposition = new BlockPos(i, j, k);
|
||||
- BlockState iblockdata = world.getBlockState(blockposition);
|
||||
+ BlockState iblockdata = world.getTypeIfLoaded(blockposition); // Paper
|
||||
+ if (iblockdata == null) return; // Paper
|
||||
Vec3 vec3d = new Vec3((double) this.enderman.getBlockX() + 0.5D, (double) j + 0.5D, (double) this.enderman.getBlockZ() + 0.5D);
|
||||
Vec3 vec3d1 = new Vec3((double) i + 0.5D, (double) j + 0.5D, (double) k + 0.5D);
|
||||
BlockHitResult movingobjectpositionblock = world.clip(new ClipContext(vec3d, vec3d1, ClipContext.Block.OUTLINE, ClipContext.Fluid.NONE, this.enderman));
|
|
@ -1,164 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <zach@zachbr.io>
|
||||
Date: Wed, 2 Jan 2019 00:35:43 -0600
|
||||
Subject: [PATCH] Add APIs to replace OfflinePlayer#getLastPlayed
|
||||
|
||||
Currently OfflinePlayer#getLastPlayed could more accurately be described
|
||||
as "OfflinePlayer#getLastTimeTheirDataWasSaved".
|
||||
|
||||
The API doc says it should return the last time the server "witnessed"
|
||||
the player, whilst also saying it should return the last time they
|
||||
logged in. The current implementation does neither.
|
||||
|
||||
Given this interesting contradiction in the API documentation and the
|
||||
current defacto implementation, I've elected to deprecate (with no
|
||||
intent to remove) and replace it with two new methods, clearly named and
|
||||
documented as to their purpose.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
index a45b21a882b34cce3f36ce71a5f803d53331deb0..936e8070f9612cc1d1d960ef873afa4df52911d7 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -219,6 +219,7 @@ public class ServerPlayer extends Player {
|
||||
public int latency;
|
||||
public boolean wonGame;
|
||||
private int containerUpdateDelay; // Paper
|
||||
+ public long loginTime; // Paper
|
||||
// Paper start - cancellable death event
|
||||
public boolean queueHealthUpdatePacket = false;
|
||||
public net.minecraft.network.protocol.game.ClientboundSetHealthPacket queuedHealthUpdatePacket;
|
||||
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
index 69c32801d219d992143ab6f90d01d93963b7ff5e..f8827ca44a6e099d0a8a05265b01e6f5da3567e0 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
@@ -172,6 +172,7 @@ public abstract class PlayerList {
|
||||
}
|
||||
|
||||
public void placeNewPlayer(Connection connection, ServerPlayer player) {
|
||||
+ player.loginTime = System.currentTimeMillis(); // Paper
|
||||
GameProfile gameprofile = player.getGameProfile();
|
||||
GameProfileCache usercache = this.server.getProfileCache();
|
||||
Optional<GameProfile> optional = usercache.get(gameprofile.getId());
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java b/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java
|
||||
index 93de44b05a698515457052c9c684c4ef44c5cc40..b20bfe5ab165bf86985e5ff2f93f415d9710e0e4 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java
|
||||
@@ -244,6 +244,61 @@ public class CraftOfflinePlayer implements OfflinePlayer, ConfigurationSerializa
|
||||
return this.getData() != null;
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public long getLastLogin() {
|
||||
+ Player player = getPlayer();
|
||||
+ if (player != null) return player.getLastLogin();
|
||||
+
|
||||
+ CompoundTag data = getPaperData();
|
||||
+
|
||||
+ if (data != null) {
|
||||
+ if (data.contains("LastLogin")) {
|
||||
+ return data.getLong("LastLogin");
|
||||
+ } else {
|
||||
+ // if the player file cannot provide accurate data, this is probably the closest we can approximate
|
||||
+ File file = getDataFile();
|
||||
+ return file.lastModified();
|
||||
+ }
|
||||
+ } else {
|
||||
+ return 0;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public long getLastSeen() {
|
||||
+ Player player = getPlayer();
|
||||
+ if (player != null) return player.getLastSeen();
|
||||
+
|
||||
+ CompoundTag data = getPaperData();
|
||||
+
|
||||
+ if (data != null) {
|
||||
+ if (data.contains("LastSeen")) {
|
||||
+ return data.getLong("LastSeen");
|
||||
+ } else {
|
||||
+ // if the player file cannot provide accurate data, this is probably the closest we can approximate
|
||||
+ File file = getDataFile();
|
||||
+ return file.lastModified();
|
||||
+ }
|
||||
+ } else {
|
||||
+ return 0;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private CompoundTag getPaperData() {
|
||||
+ CompoundTag result = getData();
|
||||
+
|
||||
+ if (result != null) {
|
||||
+ if (!result.contains("Paper")) {
|
||||
+ result.put("Paper", new CompoundTag());
|
||||
+ }
|
||||
+ result = result.getCompound("Paper");
|
||||
+ }
|
||||
+
|
||||
+ return result;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public Location getBedSpawnLocation() {
|
||||
CompoundTag data = this.getData();
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
index 7b7ceefbcc1f0be710dd8995f0afaad98f9c044d..97dd1831cfa1a74ccd80fb79a222d228bc694072 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
@@ -151,6 +151,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
private org.bukkit.event.player.PlayerResourcePackStatusEvent.Status resourcePackStatus;
|
||||
private String resourcePackHash;
|
||||
private static final boolean DISABLE_CHANNEL_LIMIT = System.getProperty("paper.disableChannelLimit") != null; // Paper - add a flag to disable the channel limit
|
||||
+ private long lastSaveTime;
|
||||
// Paper end
|
||||
|
||||
public CraftPlayer(CraftServer server, ServerPlayer entity) {
|
||||
@@ -1520,6 +1521,18 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
this.firstPlayed = firstPlayed;
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public long getLastLogin() {
|
||||
+ return getHandle().loginTime;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public long getLastSeen() {
|
||||
+ return isOnline() ? System.currentTimeMillis() : this.lastSaveTime;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
public void readExtraData(CompoundTag nbttagcompound) {
|
||||
this.hasPlayedBefore = true;
|
||||
if (nbttagcompound.contains("bukkit")) {
|
||||
@@ -1542,6 +1555,8 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
}
|
||||
|
||||
public void setExtraData(CompoundTag nbttagcompound) {
|
||||
+ this.lastSaveTime = System.currentTimeMillis(); // Paper
|
||||
+
|
||||
if (!nbttagcompound.contains("bukkit")) {
|
||||
nbttagcompound.put("bukkit", new CompoundTag());
|
||||
}
|
||||
@@ -1556,6 +1571,16 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
data.putLong("firstPlayed", this.getFirstPlayed());
|
||||
data.putLong("lastPlayed", System.currentTimeMillis());
|
||||
data.putString("lastKnownName", handle.getScoreboardName());
|
||||
+
|
||||
+ // Paper start - persist for use in offline save data
|
||||
+ if (!nbttagcompound.contains("Paper")) {
|
||||
+ nbttagcompound.put("Paper", new CompoundTag());
|
||||
+ }
|
||||
+
|
||||
+ CompoundTag paper = nbttagcompound.getCompound("Paper");
|
||||
+ paper.putLong("LastLogin", handle.loginTime);
|
||||
+ paper.putLong("LastSeen", System.currentTimeMillis());
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
@Override
|
|
@ -1,24 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: connorhartley <vectrixu+gh@gmail.com>
|
||||
Date: Mon, 7 Jan 2019 14:43:48 -0600
|
||||
Subject: [PATCH] Workaround for vehicle tracking issue on disconnect
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
index 03257305e1364a6dbda3358ff2cfba5565b4d5da..366d1de99479b53d2e9dac03d71a5a3b1be31ee3 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -1539,6 +1539,13 @@ public class ServerPlayer extends Player {
|
||||
public void disconnect() {
|
||||
this.disconnected = true;
|
||||
this.ejectPassengers();
|
||||
+
|
||||
+ // Paper start - Workaround an issue where the vehicle doesn't track the passenger disconnection dismount.
|
||||
+ if (this.isPassenger() && this.getVehicle() instanceof ServerPlayer) {
|
||||
+ this.stopRiding();
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
if (this.isSleeping()) {
|
||||
this.stopSleepInBed(true, false);
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <zach@zachbr.io>
|
||||
Date: Thu, 31 Jan 2019 16:33:36 -0500
|
||||
Subject: [PATCH] Fire BlockPistonRetractEvent for all empty pistons
|
||||
|
||||
There is an explicit check in the handling code for empty pistons that
|
||||
prevents sticky pistons from firing the event. However when we look back
|
||||
at the history we see that this check was originally added so that ONLY
|
||||
sticky pistons would fire the retract event. I'm not sure why.
|
||||
https://hub.spigotmc.org/stash/projects/SPIGOT/repos/craftbukkit/commits/1092acbddf07edfa4100bc6824504ac75088e913
|
||||
|
||||
Over the course of several updates, the meaning of that field appears to
|
||||
have changed from "is NOT sticky" to "is sticky". So now its having the
|
||||
opposite effect. Only normal pistons fire the retraction event. And like
|
||||
all things in CB, it's just been carried around since.
|
||||
|
||||
If we are to believe the history, the correct fix for this issue is to
|
||||
flip it so it only fires for sticky pistons, but that puts us in a
|
||||
bind. It's already firing for non-sticky pistons, changing it now would
|
||||
likely result in breakage. Furthermore, there is little documentation as
|
||||
to WHY that was ever intended to be the case.
|
||||
|
||||
Instead we opt to remove the check entirely so that the event fires for
|
||||
all piston types.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java b/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java
|
||||
index ca9e94b92d26eb6cd3ca6ff4b8cb1cd98aabf4e0..c345bd7542f3ffa09719864887e1516f1182e7e3 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java
|
||||
@@ -147,7 +147,7 @@ public class PistonBaseBlock extends DirectionalBlock {
|
||||
}
|
||||
|
||||
// CraftBukkit start
|
||||
- if (!this.isSticky) {
|
||||
+ //if (!this.sticky) { // Paper - Prevents empty sticky pistons from firing retract - history behind is odd
|
||||
org.bukkit.block.Block block = world.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ());
|
||||
BlockPistonRetractEvent event = new BlockPistonRetractEvent(block, ImmutableList.<org.bukkit.block.Block>of(), CraftBlock.notchToBlockFace(enumdirection));
|
||||
world.getCraftServer().getPluginManager().callEvent(event);
|
||||
@@ -155,7 +155,7 @@ public class PistonBaseBlock extends DirectionalBlock {
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
- }
|
||||
+ //} // Paper
|
||||
// PAIL: checkME - what happened to setTypeAndData?
|
||||
// CraftBukkit end
|
||||
world.blockEvent(pos, this, b0, enumdirection.get3DDataValue());
|
|
@ -1,33 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <zach@zachbr.io>
|
||||
Date: Mon, 4 Feb 2019 23:33:24 -0500
|
||||
Subject: [PATCH] Block Entity#remove from being called on Players
|
||||
|
||||
This doesn't result in the same behavior as other entities and causes
|
||||
several problems. Anyone ever complain about the "Cannot send chat
|
||||
message" thing? That's one of the issues this causes, among others.
|
||||
|
||||
If a plugin developer can come up with a valid reason to call this on a
|
||||
Player we will look at limiting the scope of this change. It appears to
|
||||
be unintentional in the few cases we've seen so far.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
index 97dd1831cfa1a74ccd80fb79a222d228bc694072..0a5aeafbb47b4bd10a471572ef04b4b9f1e31ace 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
@@ -2343,6 +2343,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
public void resetCooldown() {
|
||||
getHandle().resetAttackStrengthTicker();
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public void remove() {
|
||||
+ if (this.getHandle().getClass().equals(ServerPlayer.class)) { // special case for NMS plugins inheriting
|
||||
+ throw new UnsupportedOperationException("Calling Entity#remove on players produces undefined (bad) behavior");
|
||||
+ } else {
|
||||
+ super.remove();
|
||||
+ }
|
||||
+ }
|
||||
// Paper end
|
||||
|
||||
// Spigot start
|
Loading…
Add table
Add a link
Reference in a new issue