Prepare for updating server patches
This commit is contained in:
parent
79b873c901
commit
a8ef7aa56f
1193 changed files with 301 additions and 362 deletions
3761
patches/unapplied/api/0006-Timings-v2.patch
Normal file
3761
patches/unapplied/api/0006-Timings-v2.patch
Normal file
File diff suppressed because it is too large
Load diff
4092
patches/unapplied/api/0007-Adventure.patch
Normal file
4092
patches/unapplied/api/0007-Adventure.patch
Normal file
File diff suppressed because it is too large
Load diff
33
patches/unapplied/api/0008-Player-affects-spawning-API.patch
Normal file
33
patches/unapplied/api/0008-Player-affects-spawning-API.patch
Normal file
|
@ -0,0 +1,33 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jedediah Smith <jedediah@silencegreys.com>
|
||||
Date: Mon, 29 Feb 2016 17:22:34 -0600
|
||||
Subject: [PATCH] Player affects spawning API
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java
|
||||
index d88613f54f368a27130675c4ea7569646dbe74d7..3fa8a69376cf6d5cc5987fea5cbbce228b1408d1 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Player.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Player.java
|
||||
@@ -1475,6 +1475,22 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
|
||||
@Deprecated // Paper
|
||||
public String getLocale();
|
||||
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Get whether the player can affect mob spawning
|
||||
+ *
|
||||
+ * @return if the player can affect mob spawning
|
||||
+ */
|
||||
+ public boolean getAffectsSpawning();
|
||||
+
|
||||
+ /**
|
||||
+ * Set whether the player can affect mob spawning
|
||||
+ *
|
||||
+ * @param affects Whether the player can affect mob spawning
|
||||
+ */
|
||||
+ public void setAffectsSpawning(boolean affects);
|
||||
+ // Paper end
|
||||
+
|
||||
/**
|
||||
* Update the list of commands sent to the client.
|
||||
* <br>
|
49
patches/unapplied/api/0009-Add-getTPS-method.patch
Normal file
49
patches/unapplied/api/0009-Add-getTPS-method.patch
Normal file
|
@ -0,0 +1,49 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 29 Feb 2016 17:24:57 -0600
|
||||
Subject: [PATCH] Add getTPS method
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
|
||||
index b8e63b2c2870dd2eb9d31f51590b9b958de6a17f..06d84ca5ce794d264dc50b83283bc09e550b8cb7 100644
|
||||
--- a/src/main/java/org/bukkit/Bukkit.java
|
||||
+++ b/src/main/java/org/bukkit/Bukkit.java
|
||||
@@ -1671,6 +1671,17 @@ public final class Bukkit {
|
||||
return server.getEntity(uuid);
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Gets the current server TPS
|
||||
+ * @return current server TPS (1m, 5m, 15m in Paper-Server)
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public static double[] getTPS() {
|
||||
+ return server.getTPS();
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
/**
|
||||
* Get the advancement specified by this key.
|
||||
*
|
||||
diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
|
||||
index f048278df8abb313a319136e8b697d9c87fb5d0a..c076053238cd6f1787834ee505497d66a17d3769 100644
|
||||
--- a/src/main/java/org/bukkit/Server.java
|
||||
+++ b/src/main/java/org/bukkit/Server.java
|
||||
@@ -1414,6 +1414,16 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
|
||||
@Nullable
|
||||
Entity getEntity(@NotNull UUID uuid);
|
||||
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Gets the current server TPS
|
||||
+ *
|
||||
+ * @return current server TPS (1m, 5m, 15m in Paper-Server)
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public double[] getTPS();
|
||||
+ // Paper end
|
||||
+
|
||||
/**
|
||||
* Get the advancement specified by this key.
|
||||
*
|
66
patches/unapplied/api/0010-Entity-Origin-API.patch
Normal file
66
patches/unapplied/api/0010-Entity-Origin-API.patch
Normal file
|
@ -0,0 +1,66 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Byteflux <byte@byteflux.net>
|
||||
Date: Mon, 29 Feb 2016 17:50:31 -0600
|
||||
Subject: [PATCH] Entity Origin API
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/entity/Entity.java b/src/main/java/org/bukkit/entity/Entity.java
|
||||
index 03d8ac1b41659540d7eb3d7e218cdfaa4acb683b..7e0ec58ea1d23501f0273882ebae8e45513b02cf 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Entity.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Entity.java
|
||||
@@ -663,5 +663,15 @@ public interface Entity extends Metadatable, CommandSender, Nameable, Persistent
|
||||
default net.kyori.adventure.text.event.HoverEvent<net.kyori.adventure.text.event.HoverEvent.ShowEntity> asHoverEvent(final @NotNull java.util.function.UnaryOperator<net.kyori.adventure.text.event.HoverEvent.ShowEntity> op) {
|
||||
return net.kyori.adventure.text.event.HoverEvent.showEntity(op.apply(net.kyori.adventure.text.event.HoverEvent.ShowEntity.of(this.getType().getKey(), this.getUniqueId(), this.customName())));
|
||||
}
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the location where this entity originates from.
|
||||
+ * <p>
|
||||
+ * This value can be null if the entity hasn't yet been added to the world.
|
||||
+ *
|
||||
+ * @return Location where entity originates or null if not yet added
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ Location getOrigin();
|
||||
// Paper end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/entity/FallingBlock.java b/src/main/java/org/bukkit/entity/FallingBlock.java
|
||||
index 64f9d3fd870d65afd2ee9a85625b149163eee144..14cb0d770561151570ab4399ca5facff43076819 100644
|
||||
--- a/src/main/java/org/bukkit/entity/FallingBlock.java
|
||||
+++ b/src/main/java/org/bukkit/entity/FallingBlock.java
|
||||
@@ -54,4 +54,15 @@ public interface FallingBlock extends Entity {
|
||||
* @param hurtEntities whether entities will be damaged by this block.
|
||||
*/
|
||||
void setHurtEntities(boolean hurtEntities);
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the source block location of the FallingBlock
|
||||
+ *
|
||||
+ * @return the source block location the FallingBlock was spawned from
|
||||
+ * @deprecated replaced by {@link Entity#getOrigin()}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ default org.bukkit.Location getSourceLoc() {
|
||||
+ return this.getOrigin();
|
||||
+ }
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/entity/TNTPrimed.java b/src/main/java/org/bukkit/entity/TNTPrimed.java
|
||||
index a23cfdf66877f0a61eae700de084c76e6ee7b431..0813bd913c8fdb2001963ce3e82c07c2af105418 100644
|
||||
--- a/src/main/java/org/bukkit/entity/TNTPrimed.java
|
||||
+++ b/src/main/java/org/bukkit/entity/TNTPrimed.java
|
||||
@@ -53,4 +53,15 @@ public interface TNTPrimed extends Explosive {
|
||||
* @param source the source of this primed TNT
|
||||
*/
|
||||
public void setSource(@Nullable Entity source);
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the source block location of the TNTPrimed
|
||||
+ *
|
||||
+ * @return the source block location the TNTPrimed was spawned from
|
||||
+ * @deprecated replaced by {@link Entity#getOrigin()}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ default org.bukkit.Location getSourceLoc() {
|
||||
+ return this.getOrigin();
|
||||
+ }
|
||||
}
|
185
patches/unapplied/api/0011-Version-Command-2.0.patch
Normal file
185
patches/unapplied/api/0011-Version-Command-2.0.patch
Normal file
|
@ -0,0 +1,185 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <zach@zachbr.io>
|
||||
Date: Mon, 27 May 2019 01:10:06 -0500
|
||||
Subject: [PATCH] Version Command 2.0
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/util/VersionFetcher.java b/src/main/java/com/destroystokyo/paper/util/VersionFetcher.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..a736d7bcdc5861a01b66ba36158db1c716339346
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/util/VersionFetcher.java
|
||||
@@ -0,0 +1,45 @@
|
||||
+package com.destroystokyo.paper.util;
|
||||
+
|
||||
+import net.kyori.adventure.text.Component;
|
||||
+import net.kyori.adventure.text.format.NamedTextColor;
|
||||
+import org.bukkit.Bukkit;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+public interface VersionFetcher {
|
||||
+ /**
|
||||
+ * Amount of time to cache results for in milliseconds
|
||||
+ * <p>
|
||||
+ * Negative values will never cache.
|
||||
+ *
|
||||
+ * @return cache time
|
||||
+ */
|
||||
+ long getCacheTime();
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the version message to cache and show to command senders.
|
||||
+ *
|
||||
+ * <p>NOTE: This is run in a new thread separate from that of the command processing thread</p>
|
||||
+ *
|
||||
+ * @param serverVersion the current version of the server (will match {@link Bukkit#getVersion()})
|
||||
+ * @return the message to show when requesting a version
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ Component getVersionMessage(@NotNull String serverVersion);
|
||||
+
|
||||
+ class DummyVersionFetcher implements VersionFetcher {
|
||||
+
|
||||
+ @Override
|
||||
+ public long getCacheTime() {
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public Component getVersionMessage(@NotNull String serverVersion) {
|
||||
+ Bukkit.getLogger().warning("Version provider has not been set, cannot check for updates!");
|
||||
+ Bukkit.getLogger().info("Override the default implementation of org.bukkit.UnsafeValues#getVersionFetcher()");
|
||||
+ new Throwable().printStackTrace();
|
||||
+ return Component.text("Unable to check for updates. No version provider set.", NamedTextColor.RED);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/UnsafeValues.java b/src/main/java/org/bukkit/UnsafeValues.java
|
||||
index 207c656c0a11a3a630bc70491efcf433b2681e18..195b6bb328de92c4d17d1cd14e13578226b1ac3c 100644
|
||||
--- a/src/main/java/org/bukkit/UnsafeValues.java
|
||||
+++ b/src/main/java/org/bukkit/UnsafeValues.java
|
||||
@@ -84,5 +84,12 @@ public interface UnsafeValues {
|
||||
* @return name
|
||||
*/
|
||||
String getTimingsServerName();
|
||||
+
|
||||
+ /**
|
||||
+ * Called once by the version command on first use, then cached.
|
||||
+ */
|
||||
+ default com.destroystokyo.paper.util.VersionFetcher getVersionFetcher() {
|
||||
+ return new com.destroystokyo.paper.util.VersionFetcher.DummyVersionFetcher();
|
||||
+ }
|
||||
// Paper end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/command/defaults/VersionCommand.java b/src/main/java/org/bukkit/command/defaults/VersionCommand.java
|
||||
index 2305eb40832a82159cd89162934870cf57e1aa0e..4c2ddc722a9dc4011906ad9530b13fa9be1d3ff9 100644
|
||||
--- a/src/main/java/org/bukkit/command/defaults/VersionCommand.java
|
||||
+++ b/src/main/java/org/bukkit/command/defaults/VersionCommand.java
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.bukkit.command.defaults;
|
||||
|
||||
+import com.destroystokyo.paper.util.VersionFetcher; // Paper - version supplier
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.io.Resources;
|
||||
@@ -16,6 +17,7 @@ import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
+import net.kyori.adventure.text.Component; // Paper
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
@@ -26,6 +28,15 @@ import org.bukkit.util.StringUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class VersionCommand extends BukkitCommand {
|
||||
+ private VersionFetcher versionFetcher;
|
||||
+ private VersionFetcher getVersionFetcher() { // lazy load because unsafe isn't available at command registration
|
||||
+ if (versionFetcher == null) {
|
||||
+ versionFetcher = Bukkit.getUnsafe().getVersionFetcher();
|
||||
+ }
|
||||
+
|
||||
+ return versionFetcher;
|
||||
+ }
|
||||
+
|
||||
public VersionCommand(@NotNull String name) {
|
||||
super(name);
|
||||
|
||||
@@ -40,7 +51,7 @@ public class VersionCommand extends BukkitCommand {
|
||||
if (!testPermission(sender)) return true;
|
||||
|
||||
if (args.length == 0) {
|
||||
- sender.sendMessage("This server is running " + Bukkit.getName() + " version " + Bukkit.getVersion() + " (Implementing API version " + Bukkit.getBukkitVersion() + ")");
|
||||
+ //sender.sendMessage("This server is running " + Bukkit.getName() + " version " + Bukkit.getVersion() + " (Implementing API version " + Bukkit.getBukkitVersion() + ")"); // Paper - moved to setVersionMessage
|
||||
sendVersion(sender);
|
||||
} else {
|
||||
StringBuilder name = new StringBuilder();
|
||||
@@ -146,14 +157,14 @@ public class VersionCommand extends BukkitCommand {
|
||||
|
||||
private final ReentrantLock versionLock = new ReentrantLock();
|
||||
private boolean hasVersion = false;
|
||||
- private String versionMessage = null;
|
||||
+ private Component versionMessage = null; // Paper
|
||||
private final Set<CommandSender> versionWaiters = new HashSet<CommandSender>();
|
||||
private boolean versionTaskStarted = false;
|
||||
private long lastCheck = 0;
|
||||
|
||||
private void sendVersion(@NotNull CommandSender sender) {
|
||||
if (hasVersion) {
|
||||
- if (System.currentTimeMillis() - lastCheck > 21600000) {
|
||||
+ if (System.currentTimeMillis() - lastCheck > getVersionFetcher().getCacheTime()) { // Paper - use version supplier
|
||||
lastCheck = System.currentTimeMillis();
|
||||
hasVersion = false;
|
||||
} else {
|
||||
@@ -168,7 +179,7 @@ public class VersionCommand extends BukkitCommand {
|
||||
return;
|
||||
}
|
||||
versionWaiters.add(sender);
|
||||
- sender.sendMessage("Checking version, please wait...");
|
||||
+ sender.sendMessage(Component.text("Checking version, please wait...", net.kyori.adventure.text.format.NamedTextColor.WHITE, net.kyori.adventure.text.format.TextDecoration.ITALIC)); // Paper
|
||||
if (!versionTaskStarted) {
|
||||
versionTaskStarted = true;
|
||||
new Thread(new Runnable() {
|
||||
@@ -186,6 +197,13 @@ public class VersionCommand extends BukkitCommand {
|
||||
|
||||
private void obtainVersion() {
|
||||
String version = Bukkit.getVersion();
|
||||
+ // Paper start
|
||||
+ if (version.startsWith("null")) { // running from ide?
|
||||
+ setVersionMessage(Component.text("Unknown version, custom build?", net.kyori.adventure.text.format.NamedTextColor.YELLOW));
|
||||
+ return;
|
||||
+ }
|
||||
+ setVersionMessage(getVersionFetcher().getVersionMessage(version));
|
||||
+ /*
|
||||
if (version == null) version = "Custom";
|
||||
String[] parts = version.substring(0, version.indexOf(' ')).split("-");
|
||||
if (parts.length == 4) {
|
||||
@@ -215,11 +233,24 @@ public class VersionCommand extends BukkitCommand {
|
||||
} else {
|
||||
setVersionMessage("Unknown version, custom build?");
|
||||
}
|
||||
+ */
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
- private void setVersionMessage(@NotNull String msg) {
|
||||
+ // Paper start
|
||||
+ private void setVersionMessage(final @NotNull Component msg) {
|
||||
lastCheck = System.currentTimeMillis();
|
||||
- versionMessage = msg;
|
||||
+ final Component message = net.kyori.adventure.text.TextComponent.ofChildren(
|
||||
+ Component.text("This server is running " + Bukkit.getName() + " version " + Bukkit.getVersion() + " (Implementing API version " + Bukkit.getBukkitVersion() + ")", net.kyori.adventure.text.format.NamedTextColor.WHITE),
|
||||
+ Component.newline(),
|
||||
+ msg
|
||||
+ );
|
||||
+ this.versionMessage = Component.text()
|
||||
+ .append(message)
|
||||
+ .hoverEvent(Component.text("Click to copy to clipboard", net.kyori.adventure.text.format.NamedTextColor.WHITE))
|
||||
+ .clickEvent(net.kyori.adventure.text.event.ClickEvent.copyToClipboard(net.kyori.adventure.text.serializer.plain.PlainComponentSerializer.plain().serialize(message)))
|
||||
+ .build();
|
||||
+ // Paper end
|
||||
versionLock.lock();
|
||||
try {
|
||||
hasVersion = true;
|
62
patches/unapplied/api/0012-Add-PlayerLocaleChangeEvent.patch
Normal file
62
patches/unapplied/api/0012-Add-PlayerLocaleChangeEvent.patch
Normal file
|
@ -0,0 +1,62 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Isaac Moore <rmsy@me.com>
|
||||
Date: Mon, 29 Feb 2016 18:02:25 -0600
|
||||
Subject: [PATCH] Add PlayerLocaleChangeEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/player/PlayerLocaleChangeEvent.java b/src/main/java/com/destroystokyo/paper/event/player/PlayerLocaleChangeEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..29dd763a99ce7c6ecb176b9fb346a400369d48a0
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/player/PlayerLocaleChangeEvent.java
|
||||
@@ -0,0 +1,50 @@
|
||||
+package com.destroystokyo.paper.event.player;
|
||||
+
|
||||
+import org.bukkit.entity.Player;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.player.PlayerEvent;
|
||||
+
|
||||
+/**
|
||||
+ * Called when the locale of the player is changed.
|
||||
+ *
|
||||
+ * @deprecated Replaced by {@link org.bukkit.event.player.PlayerLocaleChangeEvent} upstream
|
||||
+ */
|
||||
+@Deprecated
|
||||
+public class PlayerLocaleChangeEvent extends PlayerEvent {
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+ private final String oldLocale;
|
||||
+ private final String newLocale;
|
||||
+
|
||||
+ public PlayerLocaleChangeEvent(final Player player, final String oldLocale, final String newLocale) {
|
||||
+ super(player);
|
||||
+ this.oldLocale = oldLocale;
|
||||
+ this.newLocale = newLocale;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the locale the player switched from.
|
||||
+ *
|
||||
+ * @return player's old locale
|
||||
+ */
|
||||
+ public String getOldLocale() {
|
||||
+ return oldLocale;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the locale the player is changed to.
|
||||
+ *
|
||||
+ * @return player's new locale
|
||||
+ */
|
||||
+ public String getNewLocale() {
|
||||
+ return newLocale;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+}
|
133
patches/unapplied/api/0013-Add-view-distance-API.patch
Normal file
133
patches/unapplied/api/0013-Add-view-distance-API.patch
Normal file
|
@ -0,0 +1,133 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Byteflux <byte@byteflux.net>
|
||||
Date: Mon, 29 Feb 2016 18:05:37 -0600
|
||||
Subject: [PATCH] Add view distance API
|
||||
|
||||
Add per player no-tick, tick, and send view distances.
|
||||
|
||||
Also add send/no-tick view distance to World.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java
|
||||
index c58b1885662c6a234ffee75995051c9750c1a512..7b1fb280a86ab44756fc233b085f878d2a27ad66 100644
|
||||
--- a/src/main/java/org/bukkit/World.java
|
||||
+++ b/src/main/java/org/bukkit/World.java
|
||||
@@ -2450,6 +2450,52 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
|
||||
int getSimulationDistance();
|
||||
// Spigot end
|
||||
|
||||
+ // Paper start - view distance api
|
||||
+ /**
|
||||
+ * Sets the view distance for this world.
|
||||
+ * @param viewDistance view distance in [2, 32]
|
||||
+ */
|
||||
+ void setViewDistance(int viewDistance);
|
||||
+
|
||||
+ /**
|
||||
+ * Returns the no-tick view distance for this world.
|
||||
+ * <p>
|
||||
+ * No-tick view distance is the view distance where chunks will load, however the chunks and their entities will not
|
||||
+ * be set to tick.
|
||||
+ * </p>
|
||||
+ * @return The no-tick view distance for this world.
|
||||
+ */
|
||||
+ int getNoTickViewDistance();
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the no-tick view distance for this world.
|
||||
+ * <p>
|
||||
+ * No-tick view distance is the view distance where chunks will load, however the chunks and their entities will not
|
||||
+ * be set to tick.
|
||||
+ * </p>
|
||||
+ * @param viewDistance view distance in [2, 32]
|
||||
+ */
|
||||
+ void setNoTickViewDistance(int viewDistance);
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the sending view distance for this world.
|
||||
+ * <p>
|
||||
+ * Sending view distance is the view distance where chunks will load in for players in this world.
|
||||
+ * </p>
|
||||
+ * @return The sending view distance for this world.
|
||||
+ */
|
||||
+ public int getSendViewDistance();
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the sending view distance for this world.
|
||||
+ * <p>
|
||||
+ * Sending view distance is the view distance where chunks will load in for players in this world.
|
||||
+ * </p>
|
||||
+ * @param viewDistance view distance in [2, 32] or -1
|
||||
+ */
|
||||
+ public void setSendViewDistance(int viewDistance);
|
||||
+ // Paper end - view distance api
|
||||
+
|
||||
// Spigot start
|
||||
public class Spigot {
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java
|
||||
index 3fa8a69376cf6d5cc5987fea5cbbce228b1408d1..e0254ef7412b4935edd0c4b9801d8eccca7d4a0c 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Player.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Player.java
|
||||
@@ -1489,6 +1489,62 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
|
||||
* @param affects Whether the player can affect mob spawning
|
||||
*/
|
||||
public void setAffectsSpawning(boolean affects);
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the view distance for this player
|
||||
+ *
|
||||
+ * @return the player's view distance
|
||||
+ * @see org.bukkit.World#getViewDistance()
|
||||
+ * @see org.bukkit.World#getNoTickViewDistance()
|
||||
+ */
|
||||
+ public int getViewDistance();
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the view distance for this player
|
||||
+ *
|
||||
+ * @param viewDistance the player's view distance
|
||||
+ * @see org.bukkit.World#setViewDistance(int)
|
||||
+ * @see org.bukkit.World#setNoTickViewDistance(int)
|
||||
+ */
|
||||
+ public void setViewDistance(int viewDistance);
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the no-ticking view distance for this player.
|
||||
+ * <p>
|
||||
+ * No-tick view distance is the view distance where chunks will load, however the chunks and their entities will not
|
||||
+ * be set to tick.
|
||||
+ * </p>
|
||||
+ * @return The no-tick view distance for this player.
|
||||
+ */
|
||||
+ public int getNoTickViewDistance();
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the no-ticking view distance for this player.
|
||||
+ * <p>
|
||||
+ * No-tick view distance is the view distance where chunks will load, however the chunks and their entities will not
|
||||
+ * be set to tick.
|
||||
+ * </p>
|
||||
+ * @param viewDistance view distance in [2, 32] or -1
|
||||
+ */
|
||||
+ public void setNoTickViewDistance(int viewDistance);
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the sending view distance for this player.
|
||||
+ * <p>
|
||||
+ * Sending view distance is the view distance where chunks will load in for players.
|
||||
+ * </p>
|
||||
+ * @return The sending view distance for this player.
|
||||
+ */
|
||||
+ public int getSendViewDistance();
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the sending view distance for this player.
|
||||
+ * <p>
|
||||
+ * Sending view distance is the view distance where chunks will load in for players.
|
||||
+ * </p>
|
||||
+ * @param viewDistance view distance in [2, 32] or -1
|
||||
+ */
|
||||
+ public void setSendViewDistance(int viewDistance);
|
||||
// Paper end
|
||||
|
||||
/**
|
98
patches/unapplied/api/0014-Add-BeaconEffectEvent.patch
Normal file
98
patches/unapplied/api/0014-Add-BeaconEffectEvent.patch
Normal file
|
@ -0,0 +1,98 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Byteflux <byte@byteflux.net>
|
||||
Date: Mon, 29 Feb 2016 18:09:40 -0600
|
||||
Subject: [PATCH] Add BeaconEffectEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/block/BeaconEffectEvent.java b/src/main/java/com/destroystokyo/paper/event/block/BeaconEffectEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..978813b94a5eae0afccbd3b38b463091a46b56ac
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/block/BeaconEffectEvent.java
|
||||
@@ -0,0 +1,86 @@
|
||||
+package com.destroystokyo.paper.event.block;
|
||||
+
|
||||
+import org.bukkit.block.Block;
|
||||
+import org.bukkit.entity.Player;
|
||||
+import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.block.BlockEvent;
|
||||
+import org.bukkit.potion.PotionEffect;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * Called when a beacon effect is being applied to a player.
|
||||
+ */
|
||||
+public class BeaconEffectEvent extends BlockEvent implements Cancellable {
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+ private boolean cancelled;
|
||||
+ private PotionEffect effect;
|
||||
+ private Player player;
|
||||
+ private boolean primary;
|
||||
+
|
||||
+ public BeaconEffectEvent(@NotNull Block block, @NotNull PotionEffect effect, @NotNull Player player, boolean primary) {
|
||||
+ super(block);
|
||||
+ this.effect = effect;
|
||||
+ this.player = player;
|
||||
+ this.primary = primary;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isCancelled() {
|
||||
+ return cancelled;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setCancelled(boolean cancelled) {
|
||||
+ this.cancelled = cancelled;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the potion effect being applied.
|
||||
+ *
|
||||
+ * @return Potion effect
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public PotionEffect getEffect() {
|
||||
+ return effect;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the potion effect that will be applied.
|
||||
+ *
|
||||
+ * @param effect Potion effect
|
||||
+ */
|
||||
+ public void setEffect(@NotNull PotionEffect effect) {
|
||||
+ this.effect = effect;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the player who the potion effect is being applied to.
|
||||
+ *
|
||||
+ * @return Affected player
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Player getPlayer() {
|
||||
+ return player;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets whether the effect is a primary beacon effect.
|
||||
+ *
|
||||
+ * @return true if this event represents a primary effect
|
||||
+ */
|
||||
+ public boolean isPrimary() {
|
||||
+ return primary;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+}
|
30
patches/unapplied/api/0015-Add-PlayerInitialSpawnEvent.patch
Normal file
30
patches/unapplied/api/0015-Add-PlayerInitialSpawnEvent.patch
Normal file
|
@ -0,0 +1,30 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Steve Anton <anxuiz.nx@gmail.com>
|
||||
Date: Mon, 29 Feb 2016 18:13:58 -0600
|
||||
Subject: [PATCH] Add PlayerInitialSpawnEvent
|
||||
|
||||
For modifying a player's initial spawn location as they join the server
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/player/PlayerInitialSpawnEvent.java b/src/main/java/com/destroystokyo/paper/event/player/PlayerInitialSpawnEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..626e97bbcaa19d55475a0fc8770412d437af2733
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/player/PlayerInitialSpawnEvent.java
|
||||
@@ -0,0 +1,17 @@
|
||||
+package com.destroystokyo.paper.event.player;
|
||||
+
|
||||
+import org.bukkit.Location;
|
||||
+import org.bukkit.entity.Player;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.spigotmc.event.player.PlayerSpawnLocationEvent;
|
||||
+
|
||||
+/**
|
||||
+ * @deprecated Use {@link PlayerSpawnLocationEvent}, Duplicate API
|
||||
+ */
|
||||
+@Deprecated
|
||||
+public class PlayerInitialSpawnEvent extends PlayerSpawnLocationEvent {
|
||||
+
|
||||
+ public PlayerInitialSpawnEvent(@NotNull Player who, @NotNull Location spawnLocation) {
|
||||
+ super(who, spawnLocation);
|
||||
+ }
|
||||
+}
|
|
@ -0,0 +1,21 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 29 Feb 2016 19:45:21 -0600
|
||||
Subject: [PATCH] Automatically disable plugins that fail to load
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
|
||||
index cf2f517765d8f2a23cc4a17d9ee2dcd81f841b1b..a3bc4155536f612ee2ae38ec7f16b974bdd24ab2 100644
|
||||
--- a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
|
||||
+++ b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
|
||||
@@ -335,6 +335,10 @@ public final class JavaPluginLoader implements PluginLoader {
|
||||
jPlugin.setEnabled(true);
|
||||
} catch (Throwable ex) {
|
||||
server.getLogger().log(Level.SEVERE, "Error occurred while enabling " + plugin.getDescription().getFullName() + " (Is it up to date?)", ex);
|
||||
+ // Paper start - Disable plugins that fail to load
|
||||
+ this.server.getPluginManager().disablePlugin(jPlugin);
|
||||
+ return;
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
// Perhaps abort here, rather than continue going, but as it stands,
|
50
patches/unapplied/api/0017-Expose-server-CommandMap.patch
Normal file
50
patches/unapplied/api/0017-Expose-server-CommandMap.patch
Normal file
|
@ -0,0 +1,50 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: kashike <kashike@vq.lc>
|
||||
Date: Mon, 29 Feb 2016 19:48:59 -0600
|
||||
Subject: [PATCH] Expose server CommandMap
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
|
||||
index 06d84ca5ce794d264dc50b83283bc09e550b8cb7..7da8180e4408a233af334a13661ebbc6781318ec 100644
|
||||
--- a/src/main/java/org/bukkit/Bukkit.java
|
||||
+++ b/src/main/java/org/bukkit/Bukkit.java
|
||||
@@ -1855,6 +1855,19 @@ public final class Bukkit {
|
||||
return server.getUnsafe();
|
||||
}
|
||||
|
||||
+
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Gets the active {@link org.bukkit.command.CommandMap}
|
||||
+ *
|
||||
+ * @return the active command map
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public static org.bukkit.command.CommandMap getCommandMap() {
|
||||
+ return server.getCommandMap();
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@NotNull
|
||||
public static Server.Spigot spigot() {
|
||||
return server.spigot();
|
||||
diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
|
||||
index c076053238cd6f1787834ee505497d66a17d3769..ad16ce2f62d6519efe8ec6da94aa2ae255521480 100644
|
||||
--- a/src/main/java/org/bukkit/Server.java
|
||||
+++ b/src/main/java/org/bukkit/Server.java
|
||||
@@ -1424,6 +1424,15 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
|
||||
public double[] getTPS();
|
||||
// Paper end
|
||||
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Gets the active {@link org.bukkit.command.CommandMap}
|
||||
+ *
|
||||
+ * @return the active command map
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ org.bukkit.command.CommandMap getCommandMap();
|
||||
+
|
||||
/**
|
||||
* Get the advancement specified by this key.
|
||||
*
|
|
@ -0,0 +1,124 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <zach.brown@destroystokyo.com>
|
||||
Date: Mon, 29 Feb 2016 19:54:32 -0600
|
||||
Subject: [PATCH] Graduate bungeecord chat API from spigot subclasses
|
||||
|
||||
Change Javadoc to be accurate
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
|
||||
index 574ecfe2e4f576f80b519f04e740fa00530a7cfa..9fca4fb1cbf5a098e023eeba947f7cf4a3151a0d 100644
|
||||
--- a/src/main/java/org/bukkit/Bukkit.java
|
||||
+++ b/src/main/java/org/bukkit/Bukkit.java
|
||||
@@ -319,6 +319,30 @@ public final class Bukkit {
|
||||
return server.broadcastMessage(message);
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Sends the component to all online players.
|
||||
+ *
|
||||
+ * @param component the component to send
|
||||
+ * @deprecated use {@code sendMessage} methods on {@link #getServer()} that accept {@link net.kyori.adventure.text.Component}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ public static void broadcast(@NotNull net.md_5.bungee.api.chat.BaseComponent component) {
|
||||
+ server.broadcast(component);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sends an array of components as a single message to all online players.
|
||||
+ *
|
||||
+ * @param components the components to send
|
||||
+ * @deprecated use {@code sendMessage} methods on {@link #getServer()} that accept {@link net.kyori.adventure.text.Component}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ public static void broadcast(@NotNull net.md_5.bungee.api.chat.BaseComponent... components) {
|
||||
+ server.broadcast(components);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
/**
|
||||
* Gets the name of the update folder. The update folder is used to safely
|
||||
* update plugins at the right moment on a plugin load.
|
||||
diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
|
||||
index 759237106df6cc2798330be22f7bdb8d18e8f427..e654e00c145fb6f0ce2238d88de9be5d31fbfa51 100644
|
||||
--- a/src/main/java/org/bukkit/Server.java
|
||||
+++ b/src/main/java/org/bukkit/Server.java
|
||||
@@ -262,6 +262,30 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
|
||||
@Deprecated // Paper
|
||||
public int broadcastMessage(@NotNull String message);
|
||||
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Sends the component to all online players.
|
||||
+ *
|
||||
+ * @param component the component to send
|
||||
+ * @deprecated use {@code sendMessage} methods that accept {@link net.kyori.adventure.text.Component}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ public default void broadcast(@NotNull net.md_5.bungee.api.chat.BaseComponent component) {
|
||||
+ spigot().broadcast(component);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sends an array of components as a single message to all online players.
|
||||
+ *
|
||||
+ * @param components the components to send
|
||||
+ * @deprecated use {@code sendMessage} methods that accept {@link net.kyori.adventure.text.Component}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ public default void broadcast(@NotNull net.md_5.bungee.api.chat.BaseComponent... components) {
|
||||
+ spigot().broadcast(components);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
/**
|
||||
* Gets the name of the update folder. The update folder is used to safely
|
||||
* update plugins at the right moment on a plugin load.
|
||||
diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java
|
||||
index e0254ef7412b4935edd0c4b9801d8eccca7d4a0c..19b9a14b855a5e15c9a6fc9544873265bdbaf203 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Player.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Player.java
|
||||
@@ -707,6 +707,42 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
|
||||
*/
|
||||
public void sendMap(@NotNull MapView map);
|
||||
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Sends the component to the player
|
||||
+ *
|
||||
+ * @param component the components to send
|
||||
+ * @deprecated use {@code sendMessage} methods that accept {@link net.kyori.adventure.text.Component}
|
||||
+ */
|
||||
+ @Override
|
||||
+ @Deprecated
|
||||
+ public default void sendMessage(@NotNull net.md_5.bungee.api.chat.BaseComponent component) {
|
||||
+ spigot().sendMessage(component);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sends an array of components as a single message to the player
|
||||
+ *
|
||||
+ * @param components the components to send
|
||||
+ * @deprecated use {@code sendMessage} methods that accept {@link net.kyori.adventure.text.Component}
|
||||
+ */
|
||||
+ @Override
|
||||
+ @Deprecated
|
||||
+ public default void sendMessage(@NotNull net.md_5.bungee.api.chat.BaseComponent... components) {
|
||||
+ spigot().sendMessage(components);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sends an array of components as a single message to the specified screen position of this player
|
||||
+ *
|
||||
+ * @param position the screen position
|
||||
+ * @param components the components to send
|
||||
+ */
|
||||
+ public default void sendMessage(net.md_5.bungee.api.ChatMessageType position, net.md_5.bungee.api.chat.BaseComponent... components) {
|
||||
+ spigot().sendMessage(position, components);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
/**
|
||||
* Forces an update of the player's entire inventory.
|
||||
*
|
604
patches/unapplied/api/0019-Add-exception-reporting-event.patch
Normal file
604
patches/unapplied/api/0019-Add-exception-reporting-event.patch
Normal file
|
@ -0,0 +1,604 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <zach.brown@destroystokyo.com>
|
||||
Date: Mon, 29 Feb 2016 20:24:35 -0600
|
||||
Subject: [PATCH] Add exception reporting event
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/server/ServerExceptionEvent.java b/src/main/java/com/destroystokyo/paper/event/server/ServerExceptionEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..2f573299a9a817a98372817a1de8bf641aaca956
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/server/ServerExceptionEvent.java
|
||||
@@ -0,0 +1,43 @@
|
||||
+package com.destroystokyo.paper.event.server;
|
||||
+
|
||||
+import com.google.common.base.Preconditions;
|
||||
+import org.apache.commons.lang.Validate;
|
||||
+import org.bukkit.Bukkit;
|
||||
+import org.bukkit.event.Event;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import com.destroystokyo.paper.exception.ServerException;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * Called whenever an exception is thrown in a recoverable section of the server.
|
||||
+ */
|
||||
+public class ServerExceptionEvent extends Event {
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+ @NotNull private ServerException exception;
|
||||
+
|
||||
+ public ServerExceptionEvent(@NotNull ServerException exception) {
|
||||
+ super(!Bukkit.isPrimaryThread());
|
||||
+ this.exception = Preconditions.checkNotNull(exception, "exception");
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the wrapped exception that was thrown.
|
||||
+ *
|
||||
+ * @return Exception thrown
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ServerException getException() {
|
||||
+ return exception;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/exception/ServerCommandException.java b/src/main/java/com/destroystokyo/paper/exception/ServerCommandException.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..6fb39af0479a818f7f1465bcdfe505ab4ff7da1a
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/exception/ServerCommandException.java
|
||||
@@ -0,0 +1,64 @@
|
||||
+package com.destroystokyo.paper.exception;
|
||||
+
|
||||
+import org.bukkit.command.Command;
|
||||
+import org.bukkit.command.CommandSender;
|
||||
+
|
||||
+import static com.google.common.base.Preconditions.checkNotNull;
|
||||
+
|
||||
+/**
|
||||
+ * Thrown when a command throws an exception
|
||||
+ */
|
||||
+public class ServerCommandException extends ServerException {
|
||||
+
|
||||
+ private final Command command;
|
||||
+ private final CommandSender commandSender;
|
||||
+ private final String[] arguments;
|
||||
+
|
||||
+ public ServerCommandException(String message, Throwable cause, Command command, CommandSender commandSender, String[] arguments) {
|
||||
+ super(message, cause);
|
||||
+ this.commandSender = checkNotNull(commandSender, "commandSender");
|
||||
+ this.arguments = checkNotNull(arguments, "arguments");
|
||||
+ this.command = checkNotNull(command, "command");
|
||||
+ }
|
||||
+
|
||||
+ public ServerCommandException(Throwable cause, Command command, CommandSender commandSender, String[] arguments) {
|
||||
+ super(cause);
|
||||
+ this.commandSender = checkNotNull(commandSender, "commandSender");
|
||||
+ this.arguments = checkNotNull(arguments, "arguments");
|
||||
+ this.command = checkNotNull(command, "command");
|
||||
+ }
|
||||
+
|
||||
+ protected ServerCommandException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace, Command command, CommandSender commandSender, String[] arguments) {
|
||||
+ super(message, cause, enableSuppression, writableStackTrace);
|
||||
+ this.commandSender = checkNotNull(commandSender, "commandSender");
|
||||
+ this.arguments = checkNotNull(arguments, "arguments");
|
||||
+ this.command = checkNotNull(command, "command");
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the command which threw the exception
|
||||
+ *
|
||||
+ * @return exception throwing command
|
||||
+ */
|
||||
+ public Command getCommand() {
|
||||
+ return command;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the command sender which executed the command request
|
||||
+ *
|
||||
+ * @return command sender of exception thrown command request
|
||||
+ */
|
||||
+ public CommandSender getCommandSender() {
|
||||
+ return commandSender;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the arguments which threw the exception for the command
|
||||
+ *
|
||||
+ * @return arguments of exception thrown command request
|
||||
+ */
|
||||
+ public String[] getArguments() {
|
||||
+ return arguments;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/exception/ServerEventException.java b/src/main/java/com/destroystokyo/paper/exception/ServerEventException.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..410b24139535cd5d8439ad581c43c61b5757fbf6
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/exception/ServerEventException.java
|
||||
@@ -0,0 +1,52 @@
|
||||
+package com.destroystokyo.paper.exception;
|
||||
+
|
||||
+import org.bukkit.event.Event;
|
||||
+import org.bukkit.event.Listener;
|
||||
+import org.bukkit.plugin.Plugin;
|
||||
+
|
||||
+import static com.google.common.base.Preconditions.*;
|
||||
+
|
||||
+/**
|
||||
+ * Exception thrown when a server event listener throws an exception
|
||||
+ */
|
||||
+public class ServerEventException extends ServerPluginException {
|
||||
+
|
||||
+ private final Listener listener;
|
||||
+ private final Event event;
|
||||
+
|
||||
+ public ServerEventException(String message, Throwable cause, Plugin responsiblePlugin, Listener listener, Event event) {
|
||||
+ super(message, cause, responsiblePlugin);
|
||||
+ this.listener = checkNotNull(listener, "listener");
|
||||
+ this.event = checkNotNull(event, "event");
|
||||
+ }
|
||||
+
|
||||
+ public ServerEventException(Throwable cause, Plugin responsiblePlugin, Listener listener, Event event) {
|
||||
+ super(cause, responsiblePlugin);
|
||||
+ this.listener = checkNotNull(listener, "listener");
|
||||
+ this.event = checkNotNull(event, "event");
|
||||
+ }
|
||||
+
|
||||
+ protected ServerEventException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace, Plugin responsiblePlugin, Listener listener, Event event) {
|
||||
+ super(message, cause, enableSuppression, writableStackTrace, responsiblePlugin);
|
||||
+ this.listener = checkNotNull(listener, "listener");
|
||||
+ this.event = checkNotNull(event, "event");
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the listener which threw the exception
|
||||
+ *
|
||||
+ * @return event listener
|
||||
+ */
|
||||
+ public Listener getListener() {
|
||||
+ return listener;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the event which caused the exception
|
||||
+ *
|
||||
+ * @return event
|
||||
+ */
|
||||
+ public Event getEvent() {
|
||||
+ return event;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/exception/ServerException.java b/src/main/java/com/destroystokyo/paper/exception/ServerException.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..c06ea3942447d4824b83ff839cb449fb818dede1
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/exception/ServerException.java
|
||||
@@ -0,0 +1,23 @@
|
||||
+package com.destroystokyo.paper.exception;
|
||||
+
|
||||
+/**
|
||||
+ * Wrapper exception for all exceptions that are thrown by the server.
|
||||
+ */
|
||||
+public class ServerException extends Exception {
|
||||
+
|
||||
+ public ServerException(String message) {
|
||||
+ super(message);
|
||||
+ }
|
||||
+
|
||||
+ public ServerException(String message, Throwable cause) {
|
||||
+ super(message, cause);
|
||||
+ }
|
||||
+
|
||||
+ public ServerException(Throwable cause) {
|
||||
+ super(cause);
|
||||
+ }
|
||||
+
|
||||
+ protected ServerException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||
+ super(message, cause, enableSuppression, writableStackTrace);
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/exception/ServerInternalException.java b/src/main/java/com/destroystokyo/paper/exception/ServerInternalException.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..e762ed0dbad51625e65fef2e1898679108459a36
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/exception/ServerInternalException.java
|
||||
@@ -0,0 +1,35 @@
|
||||
+package com.destroystokyo.paper.exception;
|
||||
+
|
||||
+import org.bukkit.Bukkit;
|
||||
+import com.destroystokyo.paper.event.server.ServerExceptionEvent;
|
||||
+
|
||||
+/**
|
||||
+ * Thrown when the internal server throws a recoverable exception.
|
||||
+ */
|
||||
+public class ServerInternalException extends ServerException {
|
||||
+
|
||||
+ public ServerInternalException(String message) {
|
||||
+ super(message);
|
||||
+ }
|
||||
+
|
||||
+ public ServerInternalException(String message, Throwable cause) {
|
||||
+ super(message, cause);
|
||||
+ }
|
||||
+
|
||||
+ public ServerInternalException(Throwable cause) {
|
||||
+ super(cause);
|
||||
+ }
|
||||
+
|
||||
+ protected ServerInternalException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||
+ super(message, cause, enableSuppression, writableStackTrace);
|
||||
+ }
|
||||
+
|
||||
+ public static void reportInternalException(Throwable cause) {
|
||||
+ try {
|
||||
+ Bukkit.getPluginManager().callEvent(new ServerExceptionEvent(new ServerInternalException(cause)));
|
||||
+ ;
|
||||
+ } catch (Throwable t) {
|
||||
+ t.printStackTrace(); // Don't want to rethrow!
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/exception/ServerPluginEnableDisableException.java b/src/main/java/com/destroystokyo/paper/exception/ServerPluginEnableDisableException.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..f016ba3b1b62e554a9bacbb9635f2dbe441b3c4e
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/exception/ServerPluginEnableDisableException.java
|
||||
@@ -0,0 +1,20 @@
|
||||
+package com.destroystokyo.paper.exception;
|
||||
+
|
||||
+import org.bukkit.plugin.Plugin;
|
||||
+
|
||||
+/**
|
||||
+ * Thrown whenever there is an exception with any enabling or disabling of plugins.
|
||||
+ */
|
||||
+public class ServerPluginEnableDisableException extends ServerPluginException {
|
||||
+ public ServerPluginEnableDisableException(String message, Throwable cause, Plugin responsiblePlugin) {
|
||||
+ super(message, cause, responsiblePlugin);
|
||||
+ }
|
||||
+
|
||||
+ public ServerPluginEnableDisableException(Throwable cause, Plugin responsiblePlugin) {
|
||||
+ super(cause, responsiblePlugin);
|
||||
+ }
|
||||
+
|
||||
+ protected ServerPluginEnableDisableException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace, Plugin responsiblePlugin) {
|
||||
+ super(message, cause, enableSuppression, writableStackTrace, responsiblePlugin);
|
||||
+ }
|
||||
+}
|
||||
\ No newline at end of file
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/exception/ServerPluginException.java b/src/main/java/com/destroystokyo/paper/exception/ServerPluginException.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..6defac287d0214fdf99418d979144050cc1e53bc
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/exception/ServerPluginException.java
|
||||
@@ -0,0 +1,38 @@
|
||||
+package com.destroystokyo.paper.exception;
|
||||
+
|
||||
+import com.google.common.base.Preconditions;
|
||||
+import org.apache.commons.lang.Validate;
|
||||
+import org.bukkit.plugin.Plugin;
|
||||
+
|
||||
+import static com.google.common.base.Preconditions.*;
|
||||
+
|
||||
+/**
|
||||
+ * Wrapper exception for all cases to which a plugin can be immediately blamed for
|
||||
+ */
|
||||
+public class ServerPluginException extends ServerException {
|
||||
+ public ServerPluginException(String message, Throwable cause, Plugin responsiblePlugin) {
|
||||
+ super(message, cause);
|
||||
+ this.responsiblePlugin = checkNotNull(responsiblePlugin, "responsiblePlugin");
|
||||
+ }
|
||||
+
|
||||
+ public ServerPluginException(Throwable cause, Plugin responsiblePlugin) {
|
||||
+ super(cause);
|
||||
+ this.responsiblePlugin = checkNotNull(responsiblePlugin, "responsiblePlugin");
|
||||
+ }
|
||||
+
|
||||
+ protected ServerPluginException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace, Plugin responsiblePlugin) {
|
||||
+ super(message, cause, enableSuppression, writableStackTrace);
|
||||
+ this.responsiblePlugin = checkNotNull(responsiblePlugin, "responsiblePlugin");
|
||||
+ }
|
||||
+
|
||||
+ private final Plugin responsiblePlugin;
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the plugin which is directly responsible for the exception being thrown
|
||||
+ *
|
||||
+ * @return plugin which is responsible for the exception throw
|
||||
+ */
|
||||
+ public Plugin getResponsiblePlugin() {
|
||||
+ return responsiblePlugin;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/exception/ServerPluginMessageException.java b/src/main/java/com/destroystokyo/paper/exception/ServerPluginMessageException.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..89e132525cfae0ce979e37b3e2793df781e47227
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/exception/ServerPluginMessageException.java
|
||||
@@ -0,0 +1,64 @@
|
||||
+package com.destroystokyo.paper.exception;
|
||||
+
|
||||
+import org.bukkit.entity.Player;
|
||||
+import org.bukkit.plugin.Plugin;
|
||||
+
|
||||
+import static com.google.common.base.Preconditions.*;
|
||||
+
|
||||
+/**
|
||||
+ * Thrown when an incoming plugin message channel throws an exception
|
||||
+ */
|
||||
+public class ServerPluginMessageException extends ServerPluginException {
|
||||
+
|
||||
+ private final Player player;
|
||||
+ private final String channel;
|
||||
+ private final byte[] data;
|
||||
+
|
||||
+ public ServerPluginMessageException(String message, Throwable cause, Plugin responsiblePlugin, Player player, String channel, byte[] data) {
|
||||
+ super(message, cause, responsiblePlugin);
|
||||
+ this.player = checkNotNull(player, "player");
|
||||
+ this.channel = checkNotNull(channel, "channel");
|
||||
+ this.data = checkNotNull(data, "data");
|
||||
+ }
|
||||
+
|
||||
+ public ServerPluginMessageException(Throwable cause, Plugin responsiblePlugin, Player player, String channel, byte[] data) {
|
||||
+ super(cause, responsiblePlugin);
|
||||
+ this.player = checkNotNull(player, "player");
|
||||
+ this.channel = checkNotNull(channel, "channel");
|
||||
+ this.data = checkNotNull(data, "data");
|
||||
+ }
|
||||
+
|
||||
+ protected ServerPluginMessageException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace, Plugin responsiblePlugin, Player player, String channel, byte[] data) {
|
||||
+ super(message, cause, enableSuppression, writableStackTrace, responsiblePlugin);
|
||||
+ this.player = checkNotNull(player, "player");
|
||||
+ this.channel = checkNotNull(channel, "channel");
|
||||
+ this.data = checkNotNull(data, "data");
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the channel to which the error occurred from recieving data from
|
||||
+ *
|
||||
+ * @return exception channel
|
||||
+ */
|
||||
+ public String getChannel() {
|
||||
+ return channel;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the data to which the error occurred from
|
||||
+ *
|
||||
+ * @return exception data
|
||||
+ */
|
||||
+ public byte[] getData() {
|
||||
+ return data;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the player which the plugin message causing the exception originated from
|
||||
+ *
|
||||
+ * @return exception player
|
||||
+ */
|
||||
+ public Player getPlayer() {
|
||||
+ return player;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/exception/ServerSchedulerException.java b/src/main/java/com/destroystokyo/paper/exception/ServerSchedulerException.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..2d0b2d4a9b3e5bdeec0e4ea7ab69858d86aa3715
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/exception/ServerSchedulerException.java
|
||||
@@ -0,0 +1,37 @@
|
||||
+package com.destroystokyo.paper.exception;
|
||||
+
|
||||
+import org.bukkit.scheduler.BukkitTask;
|
||||
+
|
||||
+import static com.google.common.base.Preconditions.checkNotNull;
|
||||
+
|
||||
+/**
|
||||
+ * Thrown when a plugin's scheduler fails with an exception
|
||||
+ */
|
||||
+public class ServerSchedulerException extends ServerPluginException {
|
||||
+
|
||||
+ private final BukkitTask task;
|
||||
+
|
||||
+ public ServerSchedulerException(String message, Throwable cause, BukkitTask task) {
|
||||
+ super(message, cause, task.getOwner());
|
||||
+ this.task = checkNotNull(task, "task");
|
||||
+ }
|
||||
+
|
||||
+ public ServerSchedulerException(Throwable cause, BukkitTask task) {
|
||||
+ super(cause, task.getOwner());
|
||||
+ this.task = checkNotNull(task, "task");
|
||||
+ }
|
||||
+
|
||||
+ protected ServerSchedulerException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace, BukkitTask task) {
|
||||
+ super(message, cause, enableSuppression, writableStackTrace, task.getOwner());
|
||||
+ this.task = checkNotNull(task, "task");
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the task which threw the exception
|
||||
+ *
|
||||
+ * @return exception throwing task
|
||||
+ */
|
||||
+ public BukkitTask getTask() {
|
||||
+ return task;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/exception/ServerTabCompleteException.java b/src/main/java/com/destroystokyo/paper/exception/ServerTabCompleteException.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..5582999fe94c7a3dac655044ccc6d078cd9521a1
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/exception/ServerTabCompleteException.java
|
||||
@@ -0,0 +1,22 @@
|
||||
+package com.destroystokyo.paper.exception;
|
||||
+
|
||||
+import org.bukkit.command.Command;
|
||||
+import org.bukkit.command.CommandSender;
|
||||
+
|
||||
+/**
|
||||
+ * Called when a tab-complete request throws an exception
|
||||
+ */
|
||||
+public class ServerTabCompleteException extends ServerCommandException {
|
||||
+
|
||||
+ public ServerTabCompleteException(String message, Throwable cause, Command command, CommandSender commandSender, String[] arguments) {
|
||||
+ super(message, cause, command, commandSender, arguments);
|
||||
+ }
|
||||
+
|
||||
+ public ServerTabCompleteException(Throwable cause, Command command, CommandSender commandSender, String[] arguments) {
|
||||
+ super(cause, command, commandSender, arguments);
|
||||
+ }
|
||||
+
|
||||
+ protected ServerTabCompleteException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace, Command command, CommandSender commandSender, String[] arguments) {
|
||||
+ super(message, cause, enableSuppression, writableStackTrace, command, commandSender, arguments);
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/command/SimpleCommandMap.java b/src/main/java/org/bukkit/command/SimpleCommandMap.java
|
||||
index f020cb04eba27a2e70fc7cf799ebbfb434b9d974..adfc7aae2c0f49bbcdd358e83b04a0cf078a7d52 100644
|
||||
--- a/src/main/java/org/bukkit/command/SimpleCommandMap.java
|
||||
+++ b/src/main/java/org/bukkit/command/SimpleCommandMap.java
|
||||
@@ -8,6 +8,10 @@ import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
+
|
||||
+import com.destroystokyo.paper.event.server.ServerExceptionEvent;
|
||||
+import com.destroystokyo.paper.exception.ServerCommandException;
|
||||
+import com.destroystokyo.paper.exception.ServerTabCompleteException;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Server;
|
||||
@@ -155,11 +159,14 @@ public class SimpleCommandMap implements CommandMap {
|
||||
target.execute(sender, sentCommandLabel, Arrays.copyOfRange(args, 1, args.length));
|
||||
} // target.timings.stopTiming(); // Spigot // Paper
|
||||
} catch (CommandException ex) {
|
||||
+ server.getPluginManager().callEvent(new ServerExceptionEvent(new ServerCommandException(ex, target, sender, args))); // Paper
|
||||
//target.timings.stopTiming(); // Spigot // Paper
|
||||
throw ex;
|
||||
} catch (Throwable ex) {
|
||||
//target.timings.stopTiming(); // Spigot // Paper
|
||||
- throw new CommandException("Unhandled exception executing '" + commandLine + "' in " + target, ex);
|
||||
+ String msg = "Unhandled exception executing '" + commandLine + "' in " + target;
|
||||
+ server.getPluginManager().callEvent(new ServerExceptionEvent(new ServerCommandException(ex, target, sender, args))); // Paper
|
||||
+ throw new CommandException(msg, ex);
|
||||
}
|
||||
|
||||
// return true as command was handled
|
||||
@@ -238,7 +245,9 @@ public class SimpleCommandMap implements CommandMap {
|
||||
} catch (CommandException ex) {
|
||||
throw ex;
|
||||
} catch (Throwable ex) {
|
||||
- throw new CommandException("Unhandled exception executing tab-completer for '" + cmdLine + "' in " + target, ex);
|
||||
+ String msg = "Unhandled exception executing tab-completer for '" + cmdLine + "' in " + target;
|
||||
+ server.getPluginManager().callEvent(new ServerExceptionEvent(new ServerTabCompleteException(msg, ex, target, sender, args))); // Paper
|
||||
+ throw new CommandException(msg, ex);
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/plugin/SimplePluginManager.java b/src/main/java/org/bukkit/plugin/SimplePluginManager.java
|
||||
index 7548e40af8043c1b5716f2d7d0122833466854c4..c2c49ee9b5531bc4761d2da54cd707c57fc647bf 100644
|
||||
--- a/src/main/java/org/bukkit/plugin/SimplePluginManager.java
|
||||
+++ b/src/main/java/org/bukkit/plugin/SimplePluginManager.java
|
||||
@@ -23,6 +23,10 @@ import java.util.WeakHashMap;
|
||||
import java.util.logging.Level;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
+
|
||||
+import com.destroystokyo.paper.event.server.ServerExceptionEvent;
|
||||
+import com.destroystokyo.paper.exception.ServerEventException;
|
||||
+import com.destroystokyo.paper.exception.ServerPluginEnableDisableException;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.World;
|
||||
@@ -478,7 +482,8 @@ public final class SimplePluginManager implements PluginManager {
|
||||
try {
|
||||
plugin.getPluginLoader().enablePlugin(plugin);
|
||||
} catch (Throwable ex) {
|
||||
- server.getLogger().log(Level.SEVERE, "Error occurred (in the plugin loader) while enabling " + plugin.getDescription().getFullName() + " (Is it up to date?)", ex);
|
||||
+ handlePluginException("Error occurred (in the plugin loader) while enabling "
|
||||
+ + plugin.getDescription().getFullName() + " (Is it up to date?)", ex, plugin);
|
||||
}
|
||||
|
||||
HandlerList.bakeAll();
|
||||
@@ -499,32 +504,37 @@ public final class SimplePluginManager implements PluginManager {
|
||||
try {
|
||||
plugin.getPluginLoader().disablePlugin(plugin);
|
||||
} catch (Throwable ex) {
|
||||
- server.getLogger().log(Level.SEVERE, "Error occurred (in the plugin loader) while disabling " + plugin.getDescription().getFullName() + " (Is it up to date?)", ex);
|
||||
+ handlePluginException("Error occurred (in the plugin loader) while disabling "
|
||||
+ + plugin.getDescription().getFullName() + " (Is it up to date?)", ex, plugin); // Paper
|
||||
}
|
||||
|
||||
try {
|
||||
server.getScheduler().cancelTasks(plugin);
|
||||
} catch (Throwable ex) {
|
||||
- server.getLogger().log(Level.SEVERE, "Error occurred (in the plugin loader) while cancelling tasks for " + plugin.getDescription().getFullName() + " (Is it up to date?)", ex);
|
||||
+ handlePluginException("Error occurred (in the plugin loader) while cancelling tasks for "
|
||||
+ + plugin.getDescription().getFullName() + " (Is it up to date?)", ex, plugin); // Paper
|
||||
}
|
||||
|
||||
try {
|
||||
server.getServicesManager().unregisterAll(plugin);
|
||||
} catch (Throwable ex) {
|
||||
- server.getLogger().log(Level.SEVERE, "Error occurred (in the plugin loader) while unregistering services for " + plugin.getDescription().getFullName() + " (Is it up to date?)", ex);
|
||||
+ handlePluginException("Error occurred (in the plugin loader) while unregistering services for "
|
||||
+ + plugin.getDescription().getFullName() + " (Is it up to date?)", ex, plugin); // Paper
|
||||
}
|
||||
|
||||
try {
|
||||
HandlerList.unregisterAll(plugin);
|
||||
} catch (Throwable ex) {
|
||||
- server.getLogger().log(Level.SEVERE, "Error occurred (in the plugin loader) while unregistering events for " + plugin.getDescription().getFullName() + " (Is it up to date?)", ex);
|
||||
+ handlePluginException("Error occurred (in the plugin loader) while unregistering events for "
|
||||
+ + plugin.getDescription().getFullName() + " (Is it up to date?)", ex, plugin); // Paper
|
||||
}
|
||||
|
||||
try {
|
||||
server.getMessenger().unregisterIncomingPluginChannel(plugin);
|
||||
server.getMessenger().unregisterOutgoingPluginChannel(plugin);
|
||||
} catch (Throwable ex) {
|
||||
- server.getLogger().log(Level.SEVERE, "Error occurred (in the plugin loader) while unregistering plugin channels for " + plugin.getDescription().getFullName() + " (Is it up to date?)", ex);
|
||||
+ handlePluginException("Error occurred (in the plugin loader) while unregistering plugin channels for "
|
||||
+ + plugin.getDescription().getFullName() + " (Is it up to date?)", ex, plugin); // Paper
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -537,6 +547,13 @@ public final class SimplePluginManager implements PluginManager {
|
||||
}
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ private void handlePluginException(String msg, Throwable ex, Plugin plugin) {
|
||||
+ server.getLogger().log(Level.SEVERE, msg, ex);
|
||||
+ callEvent(new ServerExceptionEvent(new ServerPluginEnableDisableException(msg, ex, plugin)));
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public void clearPlugins() {
|
||||
synchronized (this) {
|
||||
@@ -600,7 +617,13 @@ public final class SimplePluginManager implements PluginManager {
|
||||
));
|
||||
}
|
||||
} catch (Throwable ex) {
|
||||
- server.getLogger().log(Level.SEVERE, "Could not pass event " + event.getEventName() + " to " + registration.getPlugin().getDescription().getFullName(), ex);
|
||||
+ // Paper start - error reporting
|
||||
+ String msg = "Could not pass event " + event.getEventName() + " to " + registration.getPlugin().getDescription().getFullName();
|
||||
+ server.getLogger().log(Level.SEVERE, msg, ex);
|
||||
+ if (!(event instanceof ServerExceptionEvent)) { // We don't want to cause an endless event loop
|
||||
+ callEvent(new ServerExceptionEvent(new ServerEventException(msg, ex, registration.getPlugin(), registration.getListener(), event)));
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
}
|
||||
}
|
577
patches/unapplied/api/0020-Player-Tab-List-and-Title-APIs.patch
Normal file
577
patches/unapplied/api/0020-Player-Tab-List-and-Title-APIs.patch
Normal file
|
@ -0,0 +1,577 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Techcable <Techcable@outlook.com>
|
||||
Date: Mon, 29 Feb 2016 20:02:40 -0600
|
||||
Subject: [PATCH] Player Tab List and Title APIs
|
||||
|
||||
Co-authored-by: Fruxz <cedricspitzer@outlook.de>
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/Title.java b/src/main/java/com/destroystokyo/paper/Title.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..9e90c3df567a65b48a0b9341f784eb902cb35d8c
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/Title.java
|
||||
@@ -0,0 +1,420 @@
|
||||
+package com.destroystokyo.paper;
|
||||
+
|
||||
+import net.md_5.bungee.api.chat.BaseComponent;
|
||||
+import net.md_5.bungee.api.chat.TextComponent;
|
||||
+
|
||||
+import org.bukkit.Bukkit;
|
||||
+import org.bukkit.entity.Player;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
+
|
||||
+import java.util.ArrayList;
|
||||
+import java.util.Arrays;
|
||||
+import java.util.Collection;
|
||||
+import java.util.List;
|
||||
+
|
||||
+import static com.google.common.base.Preconditions.checkArgument;
|
||||
+import static com.google.common.base.Preconditions.checkNotNull;
|
||||
+import static com.google.common.base.Preconditions.checkState;
|
||||
+
|
||||
+/**
|
||||
+ * Represents a title to may be sent to a {@link Player}.
|
||||
+ *
|
||||
+ * <p>A title can be sent without subtitle text.</p>
|
||||
+ *
|
||||
+ * @deprecated use {@link net.kyori.adventure.title.Title}
|
||||
+ */
|
||||
+@Deprecated
|
||||
+public final class Title {
|
||||
+
|
||||
+ /**
|
||||
+ * The default number of ticks for the title to fade in.
|
||||
+ */
|
||||
+ public static final int DEFAULT_FADE_IN = 20;
|
||||
+ /**
|
||||
+ * The default number of ticks for the title to stay.
|
||||
+ */
|
||||
+ public static final int DEFAULT_STAY = 200;
|
||||
+ /**
|
||||
+ * The default number of ticks for the title to fade out.
|
||||
+ */
|
||||
+ public static final int DEFAULT_FADE_OUT = 20;
|
||||
+
|
||||
+ private final BaseComponent[] title;
|
||||
+ private final BaseComponent[] subtitle;
|
||||
+ private final int fadeIn;
|
||||
+ private final int stay;
|
||||
+ private final int fadeOut;
|
||||
+
|
||||
+ /**
|
||||
+ * Create a title with the default time values and no subtitle.
|
||||
+ *
|
||||
+ * <p>Times use default values.</p>
|
||||
+ *
|
||||
+ * @param title the main text of the title
|
||||
+ * @throws NullPointerException if the title is null
|
||||
+ */
|
||||
+ public Title(@NotNull BaseComponent title) {
|
||||
+ this(title, null);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Create a title with the default time values and no subtitle.
|
||||
+ *
|
||||
+ * <p>Times use default values.</p>
|
||||
+ *
|
||||
+ * @param title the main text of the title
|
||||
+ * @throws NullPointerException if the title is null
|
||||
+ */
|
||||
+ public Title(@NotNull BaseComponent[] title) {
|
||||
+ this(title, null);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Create a title with the default time values and no subtitle.
|
||||
+ *
|
||||
+ * <p>Times use default values.</p>
|
||||
+ *
|
||||
+ * @param title the main text of the title
|
||||
+ * @throws NullPointerException if the title is null
|
||||
+ */
|
||||
+ public Title(@NotNull String title) {
|
||||
+ this(title, null);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Create a title with the default time values.
|
||||
+ *
|
||||
+ * <p>Times use default values.</p>
|
||||
+ *
|
||||
+ * @param title the main text of the title
|
||||
+ * @param subtitle the secondary text of the title
|
||||
+ */
|
||||
+ public Title(@NotNull BaseComponent title, @Nullable BaseComponent subtitle) {
|
||||
+ this(title, subtitle, DEFAULT_FADE_IN, DEFAULT_STAY, DEFAULT_FADE_OUT);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Create a title with the default time values.
|
||||
+ *
|
||||
+ * <p>Times use default values.</p>
|
||||
+ *
|
||||
+ * @param title the main text of the title
|
||||
+ * @param subtitle the secondary text of the title
|
||||
+ */
|
||||
+ public Title(@NotNull BaseComponent[] title, @Nullable BaseComponent[] subtitle) {
|
||||
+ this(title, subtitle, DEFAULT_FADE_IN, DEFAULT_STAY, DEFAULT_FADE_OUT);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Create a title with the default time values.
|
||||
+ *
|
||||
+ * <p>Times use default values.</p>
|
||||
+ *
|
||||
+ * @param title the main text of the title
|
||||
+ * @param subtitle the secondary text of the title
|
||||
+ */
|
||||
+ public Title(@NotNull String title, @Nullable String subtitle) {
|
||||
+ this(title, subtitle, DEFAULT_FADE_IN, DEFAULT_STAY, DEFAULT_FADE_OUT);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Creates a new title.
|
||||
+ *
|
||||
+ * @param title the main text of the title
|
||||
+ * @param subtitle the secondary text of the title
|
||||
+ * @param fadeIn the number of ticks for the title to fade in
|
||||
+ * @param stay the number of ticks for the title to stay on screen
|
||||
+ * @param fadeOut the number of ticks for the title to fade out
|
||||
+ * @throws IllegalArgumentException if any of the times are negative
|
||||
+ */
|
||||
+ public Title(@NotNull BaseComponent title, @Nullable BaseComponent subtitle, int fadeIn, int stay, int fadeOut) {
|
||||
+ this(
|
||||
+ new BaseComponent[]{checkNotNull(title, "title")},
|
||||
+ subtitle == null ? null : new BaseComponent[]{subtitle},
|
||||
+ fadeIn,
|
||||
+ stay,
|
||||
+ fadeOut
|
||||
+ );
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Creates a new title.
|
||||
+ *
|
||||
+ * @param title the main text of the title
|
||||
+ * @param subtitle the secondary text of the title
|
||||
+ * @param fadeIn the number of ticks for the title to fade in
|
||||
+ * @param stay the number of ticks for the title to stay on screen
|
||||
+ * @param fadeOut the number of ticks for the title to fade out
|
||||
+ * @throws IllegalArgumentException if any of the times are negative
|
||||
+ */
|
||||
+ public Title(@Nullable BaseComponent[] title, @NotNull BaseComponent[] subtitle, int fadeIn, int stay, int fadeOut) {
|
||||
+ checkArgument(fadeIn >= 0, "Negative fadeIn: %s", fadeIn);
|
||||
+ checkArgument(stay >= 0, "Negative stay: %s", stay);
|
||||
+ checkArgument(fadeOut >= 0, "Negative fadeOut: %s", fadeOut);
|
||||
+ this.title = checkNotNull(title, "title");
|
||||
+ this.subtitle = subtitle;
|
||||
+ this.fadeIn = fadeIn;
|
||||
+ this.stay = stay;
|
||||
+ this.fadeOut = fadeOut;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Creates a new title.
|
||||
+ *
|
||||
+ * <p>It is recommended to the {@link BaseComponent} constrctors.</p>
|
||||
+ *
|
||||
+ * @param title the main text of the title
|
||||
+ * @param subtitle the secondary text of the title
|
||||
+ * @param fadeIn the number of ticks for the title to fade in
|
||||
+ * @param stay the number of ticks for the title to stay on screen
|
||||
+ * @param fadeOut the number of ticks for the title to fade out
|
||||
+ */
|
||||
+ public Title(@NotNull String title, @Nullable String subtitle, int fadeIn, int stay, int fadeOut) {
|
||||
+ this(
|
||||
+ TextComponent.fromLegacyText(checkNotNull(title, "title")),
|
||||
+ subtitle == null ? null : TextComponent.fromLegacyText(subtitle),
|
||||
+ fadeIn,
|
||||
+ stay,
|
||||
+ fadeOut
|
||||
+ );
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the text of this title
|
||||
+ *
|
||||
+ * @return the text
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public BaseComponent[] getTitle() {
|
||||
+ return this.title;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the text of this title's subtitle
|
||||
+ *
|
||||
+ * @return the text
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public BaseComponent[] getSubtitle() {
|
||||
+ return this.subtitle;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the number of ticks to fade in.
|
||||
+ *
|
||||
+ * <p>The returned value is never negative.</p>
|
||||
+ *
|
||||
+ * @return the number of ticks to fade in
|
||||
+ */
|
||||
+ public int getFadeIn() {
|
||||
+ return this.fadeIn;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the number of ticks to stay.
|
||||
+ *
|
||||
+ * <p>The returned value is never negative.</p>
|
||||
+ *
|
||||
+ * @return the number of ticks to stay
|
||||
+ */
|
||||
+ public int getStay() {
|
||||
+ return this.stay;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the number of ticks to fade out.
|
||||
+ *
|
||||
+ * <p>The returned value is never negative.</p>
|
||||
+ *
|
||||
+ * @return the number of ticks to fade out
|
||||
+ */
|
||||
+ public int getFadeOut() {
|
||||
+ return this.fadeOut;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sends the title directly to an player
|
||||
+ *
|
||||
+ * @param player the receiver of the title
|
||||
+ */
|
||||
+ public void send(@NotNull Player player) {
|
||||
+ player.sendTitle(this);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sends the title directly to the defined players
|
||||
+ *
|
||||
+ * @param players the receivers of the title
|
||||
+ */
|
||||
+ public void send(@NotNull Collection<? extends Player> players) {
|
||||
+ for (Player player : players) {
|
||||
+ player.sendTitle(this);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sends the title directly to the defined players
|
||||
+ *
|
||||
+ * @param players the receivers of the title
|
||||
+ */
|
||||
+ public void send(@NotNull Player[] players) {
|
||||
+ for (Player player : players) {
|
||||
+ player.sendTitle(this);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sends the title directly to all online players
|
||||
+ */
|
||||
+ public void broadcast() {
|
||||
+ send(Bukkit.getOnlinePlayers());
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static Builder builder() {
|
||||
+ return new Builder();
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * A builder for creating titles
|
||||
+ */
|
||||
+ public static final class Builder {
|
||||
+
|
||||
+ private BaseComponent[] title;
|
||||
+ private BaseComponent[] subtitle;
|
||||
+ private int fadeIn = DEFAULT_FADE_IN;
|
||||
+ private int stay = DEFAULT_STAY;
|
||||
+ private int fadeOut = DEFAULT_FADE_OUT;
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the title to the given text.
|
||||
+ *
|
||||
+ * @param title the title text
|
||||
+ * @return this builder instance
|
||||
+ * @throws NullPointerException if the title is null
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Builder title(@NotNull BaseComponent title) {
|
||||
+ return this.title(new BaseComponent[]{checkNotNull(title, "title")});
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the title to the given text.
|
||||
+ *
|
||||
+ * @param title the title text
|
||||
+ * @return this builder instance
|
||||
+ * @throws NullPointerException if the title is null
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Builder title(@NotNull BaseComponent[] title) {
|
||||
+ this.title = checkNotNull(title, "title");
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the title to the given text.
|
||||
+ *
|
||||
+ * <p>It is recommended to the {@link BaseComponent} methods.</p>
|
||||
+ *
|
||||
+ * @param title the title text
|
||||
+ * @return this builder instance
|
||||
+ * @throws NullPointerException if the title is null
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Builder title(@NotNull String title) {
|
||||
+ return this.title(TextComponent.fromLegacyText(checkNotNull(title, "title")));
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the subtitle to the given text.
|
||||
+ *
|
||||
+ * @param subtitle the title text
|
||||
+ * @return this builder instance
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Builder subtitle(@Nullable BaseComponent subtitle) {
|
||||
+ return this.subtitle(subtitle == null ? null : new BaseComponent[]{subtitle});
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the subtitle to the given text.
|
||||
+ *
|
||||
+ * @param subtitle the title text
|
||||
+ * @return this builder instance
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Builder subtitle(@Nullable BaseComponent[] subtitle) {
|
||||
+ this.subtitle = subtitle;
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the subtitle to the given text.
|
||||
+ *
|
||||
+ * <p>It is recommended to the {@link BaseComponent} methods.</p>
|
||||
+ *
|
||||
+ * @param subtitle the title text
|
||||
+ * @return this builder instance
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Builder subtitle(@Nullable String subtitle) {
|
||||
+ return this.subtitle(subtitle == null ? null : TextComponent.fromLegacyText(subtitle));
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the number of ticks for the title to fade in
|
||||
+ *
|
||||
+ * @param fadeIn the number of ticks to fade in
|
||||
+ * @return this builder instance
|
||||
+ * @throws IllegalArgumentException if it is negative
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Builder fadeIn(int fadeIn) {
|
||||
+ checkArgument(fadeIn >= 0, "Negative fadeIn: %s", fadeIn);
|
||||
+ this.fadeIn = fadeIn;
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the number of ticks for the title to stay.
|
||||
+ *
|
||||
+ * @param stay the number of ticks to stay
|
||||
+ * @return this builder instance
|
||||
+ * @throws IllegalArgumentException if it is negative
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Builder stay(int stay) {
|
||||
+ checkArgument(stay >= 0, "Negative stay: %s", stay);
|
||||
+ this.stay = stay;
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the number of ticks for the title to fade out.
|
||||
+ *
|
||||
+ * @param fadeOut the number of ticks to fade out
|
||||
+ * @return this builder instance
|
||||
+ * @throws IllegalArgumentException if it is negative
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Builder fadeOut(int fadeOut) {
|
||||
+ checkArgument(fadeOut >= 0, "Negative fadeOut: %s", fadeOut);
|
||||
+ this.fadeOut = fadeOut;
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Create a title based on the values in the builder.
|
||||
+ *
|
||||
+ * @return a title from the values in this builder
|
||||
+ * @throws IllegalStateException if title isn't specified
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Title build() {
|
||||
+ checkState(title != null, "Title not specified");
|
||||
+ return new Title(this.title, this.subtitle, this.fadeIn, this.stay, this.fadeOut);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java
|
||||
index 19b9a14b855a5e15c9a6fc9544873265bdbaf203..9468b955e035e3aa733b62f17417d8e99f37ac9f 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Player.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Player.java
|
||||
@@ -2,6 +2,7 @@ package org.bukkit.entity;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.UUID;
|
||||
+import com.destroystokyo.paper.Title; // Paper
|
||||
import org.bukkit.DyeColor;
|
||||
import org.bukkit.Effect;
|
||||
import org.bukkit.GameMode;
|
||||
@@ -741,6 +742,131 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
|
||||
public default void sendMessage(net.md_5.bungee.api.ChatMessageType position, net.md_5.bungee.api.chat.BaseComponent... components) {
|
||||
spigot().sendMessage(position, components);
|
||||
}
|
||||
+
|
||||
+ /**
|
||||
+ * Set the text displayed in the player list header and footer for this player
|
||||
+ *
|
||||
+ * @param header content for the top of the player list
|
||||
+ * @param footer content for the bottom of the player list
|
||||
+ * @deprecated in favour of {@link #sendPlayerListHeaderAndFooter(net.kyori.adventure.text.Component, net.kyori.adventure.text.Component)}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ public void setPlayerListHeaderFooter(@Nullable net.md_5.bungee.api.chat.BaseComponent[] header, @Nullable net.md_5.bungee.api.chat.BaseComponent[] footer);
|
||||
+
|
||||
+ /**
|
||||
+ * Set the text displayed in the player list header and footer for this player
|
||||
+ *
|
||||
+ * @param header content for the top of the player list
|
||||
+ * @param footer content for the bottom of the player list
|
||||
+ * @deprecated in favour of {@link #sendPlayerListHeaderAndFooter(net.kyori.adventure.text.Component, net.kyori.adventure.text.Component)}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ public void setPlayerListHeaderFooter(@Nullable net.md_5.bungee.api.chat.BaseComponent header, @Nullable net.md_5.bungee.api.chat.BaseComponent footer);
|
||||
+
|
||||
+ /**
|
||||
+ * Update the times for titles displayed to the player
|
||||
+ *
|
||||
+ * @param fadeInTicks ticks to fade-in
|
||||
+ * @param stayTicks ticks to stay visible
|
||||
+ * @param fadeOutTicks ticks to fade-out
|
||||
+ * @deprecated Use {@link #showTitle(net.kyori.adventure.title.Title)} or {@link #sendTitlePart(net.kyori.adventure.title.TitlePart, Object)}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ public void setTitleTimes(int fadeInTicks, int stayTicks, int fadeOutTicks);
|
||||
+
|
||||
+ /**
|
||||
+ * Update the subtitle of titles displayed to the player
|
||||
+ *
|
||||
+ * @param subtitle Subtitle to set
|
||||
+ * @deprecated Use {@link #showTitle(net.kyori.adventure.title.Title)} or {@link #sendTitlePart(net.kyori.adventure.title.TitlePart, Object)}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ public void setSubtitle(net.md_5.bungee.api.chat.BaseComponent[] subtitle);
|
||||
+
|
||||
+ /**
|
||||
+ * Update the subtitle of titles displayed to the player
|
||||
+ *
|
||||
+ * @param subtitle Subtitle to set
|
||||
+ * @deprecated Use {@link #showTitle(net.kyori.adventure.title.Title)} or {@link #sendTitlePart(net.kyori.adventure.title.TitlePart, Object)}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ public void setSubtitle(net.md_5.bungee.api.chat.BaseComponent subtitle);
|
||||
+
|
||||
+ /**
|
||||
+ * Show the given title to the player, along with the last subtitle set, using the last set times
|
||||
+ *
|
||||
+ * @param title Title to set
|
||||
+ * @deprecated Use {@link #showTitle(net.kyori.adventure.title.Title)} or {@link #sendTitlePart(net.kyori.adventure.title.TitlePart, Object)}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ public void showTitle(@Nullable net.md_5.bungee.api.chat.BaseComponent[] title);
|
||||
+
|
||||
+ /**
|
||||
+ * Show the given title to the player, along with the last subtitle set, using the last set times
|
||||
+ *
|
||||
+ * @param title Title to set
|
||||
+ * @deprecated Use {@link #showTitle(net.kyori.adventure.title.Title)} or {@link #sendTitlePart(net.kyori.adventure.title.TitlePart, Object)}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ public void showTitle(@Nullable net.md_5.bungee.api.chat.BaseComponent title);
|
||||
+
|
||||
+ /**
|
||||
+ * Show the given title and subtitle to the player using the given times
|
||||
+ *
|
||||
+ * @param title big text
|
||||
+ * @param subtitle little text under it
|
||||
+ * @param fadeInTicks ticks to fade-in
|
||||
+ * @param stayTicks ticks to stay visible
|
||||
+ * @param fadeOutTicks ticks to fade-out
|
||||
+ * @deprecated Use {@link #showTitle(net.kyori.adventure.title.Title)} or {@link #sendTitlePart(net.kyori.adventure.title.TitlePart, Object)}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ public void showTitle(@Nullable net.md_5.bungee.api.chat.BaseComponent[] title, @Nullable net.md_5.bungee.api.chat.BaseComponent[] subtitle, int fadeInTicks, int stayTicks, int fadeOutTicks);
|
||||
+
|
||||
+ /**
|
||||
+ * Show the given title and subtitle to the player using the given times
|
||||
+ *
|
||||
+ * @param title big text
|
||||
+ * @param subtitle little text under it
|
||||
+ * @param fadeInTicks ticks to fade-in
|
||||
+ * @param stayTicks ticks to stay visible
|
||||
+ * @param fadeOutTicks ticks to fade-out
|
||||
+ * @deprecated Use {@link #showTitle(net.kyori.adventure.title.Title)} or {@link #sendTitlePart(net.kyori.adventure.title.TitlePart, Object)}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ public void showTitle(@Nullable net.md_5.bungee.api.chat.BaseComponent title, @Nullable net.md_5.bungee.api.chat.BaseComponent subtitle, int fadeInTicks, int stayTicks, int fadeOutTicks);
|
||||
+
|
||||
+ /**
|
||||
+ * Show the title to the player, overriding any previously displayed title.
|
||||
+ *
|
||||
+ * <p>This method overrides any previous title, use {@link #updateTitle(Title)} to change the existing one.</p>
|
||||
+ *
|
||||
+ * @param title the title to send
|
||||
+ * @throws NullPointerException if the title is null
|
||||
+ * @deprecated Use {@link #showTitle(net.kyori.adventure.title.Title)} or {@link #sendTitlePart(net.kyori.adventure.title.TitlePart, Object)}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ void sendTitle(@NotNull Title title);
|
||||
+
|
||||
+ /**
|
||||
+ * Show the title to the player, overriding any previously displayed title.
|
||||
+ *
|
||||
+ * <p>This method doesn't override previous titles, but changes their values.</p>
|
||||
+ *
|
||||
+ * @param title the title to send
|
||||
+ * @throws NullPointerException if title is null
|
||||
+ * @deprecated Use {@link #showTitle(net.kyori.adventure.title.Title)} or {@link #sendTitlePart(net.kyori.adventure.title.TitlePart, Object)}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ void updateTitle(@NotNull Title title);
|
||||
+
|
||||
+ /**
|
||||
+ * Hide any title that is currently visible to the player
|
||||
+ *
|
||||
+ * @deprecated use {@link #clearTitle()}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ public void hideTitle();
|
||||
// Paper end
|
||||
|
||||
/**
|
|
@ -0,0 +1,27 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 29 Feb 2016 20:26:39 -0600
|
||||
Subject: [PATCH] Fix ServerListPingEvent flagging as Async
|
||||
|
||||
This event can sometimes fire Async, set the proper boolean
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/event/server/ServerEvent.java b/src/main/java/org/bukkit/event/server/ServerEvent.java
|
||||
index 46b119017a1e3dfcd9ae5fb91b4fe8c20b0d6b86..05167fb34e4c42edc67af6e6700a2a3cc0f92769 100644
|
||||
--- a/src/main/java/org/bukkit/event/server/ServerEvent.java
|
||||
+++ b/src/main/java/org/bukkit/event/server/ServerEvent.java
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.bukkit.event.server;
|
||||
|
||||
+import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.Event;
|
||||
|
||||
/**
|
||||
@@ -8,7 +9,7 @@ import org.bukkit.event.Event;
|
||||
public abstract class ServerEvent extends Event {
|
||||
|
||||
public ServerEvent() {
|
||||
- super();
|
||||
+ super(!Bukkit.isPrimaryThread()); // Paper
|
||||
}
|
||||
|
||||
public ServerEvent(boolean isAsync) {
|
|
@ -0,0 +1,54 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: kashike <kashike@vq.lc>
|
||||
Date: Tue, 8 Mar 2016 13:05:59 -0800
|
||||
Subject: [PATCH] Add BaseComponent sendMessage methods to CommandSender
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/command/CommandSender.java b/src/main/java/org/bukkit/command/CommandSender.java
|
||||
index 7c9a0c85c0e23d6a569c3583e87b005938923d95..39ce012fcf2b22471a2ace9218f4f696ec93f466 100644
|
||||
--- a/src/main/java/org/bukkit/command/CommandSender.java
|
||||
+++ b/src/main/java/org/bukkit/command/CommandSender.java
|
||||
@@ -1,6 +1,9 @@
|
||||
package org.bukkit.command;
|
||||
|
||||
import java.util.UUID;
|
||||
+import net.kyori.adventure.audience.MessageType;
|
||||
+import net.kyori.adventure.identity.Identity;
|
||||
+import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.permissions.Permissible;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -124,5 +127,33 @@ public interface CommandSender extends net.kyori.adventure.audience.Audience, Pe
|
||||
default void sendMessage(final @NotNull net.kyori.adventure.identity.Identity identity, final @NotNull net.kyori.adventure.text.Component message, final @NotNull net.kyori.adventure.audience.MessageType type) {
|
||||
this.sendMessage(org.bukkit.Bukkit.getUnsafe().legacyComponentSerializer().serialize(message));
|
||||
}
|
||||
+
|
||||
+ /**
|
||||
+ * Sends the component to the sender
|
||||
+ *
|
||||
+ * <p>If this sender does not support sending full components then
|
||||
+ * the component will be sent as legacy text.</p>
|
||||
+ *
|
||||
+ * @param component the component to send
|
||||
+ * @deprecated use {@link #sendMessage(Identity, Component, MessageType)} instead
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ default void sendMessage(@NotNull net.md_5.bungee.api.chat.BaseComponent component) {
|
||||
+ this.sendMessage(component.toLegacyText());
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sends an array of components as a single message to the sender
|
||||
+ *
|
||||
+ * <p>If this sender does not support sending full components then
|
||||
+ * the components will be sent as legacy text.</p>
|
||||
+ *
|
||||
+ * @param components the components to send
|
||||
+ * @deprecated use {@link #sendMessage(Identity, Component, MessageType)} instead
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ default void sendMessage(@NotNull net.md_5.bungee.api.chat.BaseComponent... components) {
|
||||
+ this.sendMessage(new net.md_5.bungee.api.chat.TextComponent(components).toLegacyText());
|
||||
+ }
|
||||
// Paper end
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: mrapple <tony@oc.tc>
|
||||
Date: Sun, 25 Nov 2012 13:47:27 -0600
|
||||
Subject: [PATCH] Add methods for working with arrows stuck in living entities
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/entity/LivingEntity.java b/src/main/java/org/bukkit/entity/LivingEntity.java
|
||||
index 5077ec367a5cba88957c6115be27742974f7deec..b41133f23d25f90fc0993499056c4eeaf003a701 100644
|
||||
--- a/src/main/java/org/bukkit/entity/LivingEntity.java
|
||||
+++ b/src/main/java/org/bukkit/entity/LivingEntity.java
|
||||
@@ -612,4 +612,19 @@ public interface LivingEntity extends Attributable, Damageable, ProjectileSource
|
||||
* @return Whether the entity is invisible
|
||||
*/
|
||||
public boolean isInvisible();
|
||||
+
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Get the number of arrows stuck in this entity
|
||||
+ * @return Number of arrows stuck
|
||||
+ */
|
||||
+ int getArrowsStuck();
|
||||
+
|
||||
+ /**
|
||||
+ * Set the number of arrows stuck in this entity
|
||||
+ *
|
||||
+ * @param arrows Number of arrows to stick in this entity
|
||||
+ */
|
||||
+ void setArrowsStuck(int arrows);
|
||||
+ // Paper end
|
||||
}
|
182
patches/unapplied/api/0024-Complete-resource-pack-API.patch
Normal file
182
patches/unapplied/api/0024-Complete-resource-pack-API.patch
Normal file
|
@ -0,0 +1,182 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jedediah Smith <jedediah@silencegreys.com>
|
||||
Date: Sat, 4 Apr 2015 22:59:54 -0400
|
||||
Subject: [PATCH] Complete resource pack API
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java
|
||||
index 12acaa06a00a2a2d0c03e52920bb041af29bc01e..ab25e699ea936e2dae7cce41f850b55a381a6dcb 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Player.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Player.java
|
||||
@@ -1217,7 +1217,9 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
|
||||
* @throws IllegalArgumentException Thrown if the URL is null.
|
||||
* @throws IllegalArgumentException Thrown if the URL is too long. The
|
||||
* length restriction is an implementation specific arbitrary value.
|
||||
+ * @deprecated use {@link #setResourcePack(String, String)}
|
||||
*/
|
||||
+ @Deprecated // Paper
|
||||
public void setResourcePack(@NotNull String url);
|
||||
|
||||
/**
|
||||
@@ -1737,6 +1739,124 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
|
||||
default net.kyori.adventure.text.event.HoverEvent<net.kyori.adventure.text.event.HoverEvent.ShowEntity> asHoverEvent(final @NotNull java.util.function.UnaryOperator<net.kyori.adventure.text.event.HoverEvent.ShowEntity> op) {
|
||||
return net.kyori.adventure.text.event.HoverEvent.showEntity(op.apply(net.kyori.adventure.text.event.HoverEvent.ShowEntity.of(this.getType().getKey(), this.getUniqueId(), this.displayName())));
|
||||
}
|
||||
+
|
||||
+ /**
|
||||
+ * Request that the player's client download and switch resource packs.
|
||||
+ * <p>
|
||||
+ * The player's client will download the new resource pack asynchronously
|
||||
+ * in the background, and will automatically switch to it once the
|
||||
+ * download is complete. If the client has downloaded and cached the same
|
||||
+ * resource pack in the past, it will perform a quick timestamp check
|
||||
+ * over the network to determine if the resource pack has changed and
|
||||
+ * needs to be downloaded again. When this request is sent for the very
|
||||
+ * first time from a given server, the client will first display a
|
||||
+ * confirmation GUI to the player before proceeding with the download.
|
||||
+ * <p>
|
||||
+ * Notes:
|
||||
+ * <ul>
|
||||
+ * <li>Players can disable server resources on their client, in which
|
||||
+ * case this method will have no affect on them.
|
||||
+ * <li>There is no concept of resetting resource packs back to default
|
||||
+ * within Minecraft, so players will have to relog to do so.
|
||||
+ * </ul>
|
||||
+ *
|
||||
+ * @param url The URL from which the client will download the resource
|
||||
+ * pack. The string must contain only US-ASCII characters and should
|
||||
+ * be encoded as per RFC 1738.
|
||||
+ * @param hash A 40 character hexadecimal and lowercase SHA-1 digest of
|
||||
+ * the resource pack file.
|
||||
+ * @throws IllegalArgumentException Thrown if the URL is null.
|
||||
+ * @throws IllegalArgumentException Thrown if the URL is too long. The
|
||||
+ * length restriction is an implementation specific arbitrary value.
|
||||
+ */
|
||||
+ void setResourcePack(@NotNull String url, @NotNull String hash);
|
||||
+
|
||||
+ /**
|
||||
+ * Request that the player's client download and switch resource packs.
|
||||
+ * <p>
|
||||
+ * The player's client will download the new resource pack asynchronously
|
||||
+ * in the background, and will automatically switch to it once the
|
||||
+ * download is complete. If the client has downloaded and cached the same
|
||||
+ * resource pack in the past, it will perform a quick timestamp check
|
||||
+ * over the network to determine if the resource pack has changed and
|
||||
+ * needs to be downloaded again. When this request is sent for the very
|
||||
+ * first time from a given server, the client will first display a
|
||||
+ * confirmation GUI to the player before proceeding with the download.
|
||||
+ * <p>
|
||||
+ * Notes:
|
||||
+ * <ul>
|
||||
+ * <li>Players can disable server resources on their client, in which
|
||||
+ * case this method will have no affect on them.
|
||||
+ * <li>There is no concept of resetting resource packs back to default
|
||||
+ * within Minecraft, so players will have to relog to do so.
|
||||
+ * </ul>
|
||||
+ *
|
||||
+ * @param url The URL from which the client will download the resource
|
||||
+ * pack. The string must contain only US-ASCII characters and should
|
||||
+ * be encoded as per RFC 1738.
|
||||
+ * @param hash A 40 character hexadecimal and lowercase SHA-1 digest of
|
||||
+ * the resource pack file.
|
||||
+ * @param required Marks if the resource pack should be required by the client
|
||||
+ * @throws IllegalArgumentException Thrown if the URL is null.
|
||||
+ * @throws IllegalArgumentException Thrown if the URL is too long. The
|
||||
+ * length restriction is an implementation specific arbitrary value.
|
||||
+ */
|
||||
+ void setResourcePack(@NotNull String url, @NotNull String hash, boolean required);
|
||||
+
|
||||
+ /**
|
||||
+ * Request that the player's client download and switch resource packs.
|
||||
+ * <p>
|
||||
+ * The player's client will download the new resource pack asynchronously
|
||||
+ * in the background, and will automatically switch to it once the
|
||||
+ * download is complete. If the client has downloaded and cached the same
|
||||
+ * resource pack in the past, it will perform a quick timestamp check
|
||||
+ * over the network to determine if the resource pack has changed and
|
||||
+ * needs to be downloaded again. When this request is sent for the very
|
||||
+ * first time from a given server, the client will first display a
|
||||
+ * confirmation GUI to the player before proceeding with the download.
|
||||
+ * <p>
|
||||
+ * Notes:
|
||||
+ * <ul>
|
||||
+ * <li>Players can disable server resources on their client, in which
|
||||
+ * case this method will have no affect on them.
|
||||
+ * <li>There is no concept of resetting resource packs back to default
|
||||
+ * within Minecraft, so players will have to relog to do so.
|
||||
+ * </ul>
|
||||
+ *
|
||||
+ * @param url The URL from which the client will download the resource
|
||||
+ * pack. The string must contain only US-ASCII characters and should
|
||||
+ * be encoded as per RFC 1738.
|
||||
+ * @param hash A 40 character hexadecimal and lowercase SHA-1 digest of
|
||||
+ * the resource pack file.
|
||||
+ * @param required Marks if the resource pack should be required by the client
|
||||
+ * @param resourcePackPrompt A Prompt to be displayed in the client request
|
||||
+ * @throws IllegalArgumentException Thrown if the URL is null.
|
||||
+ * @throws IllegalArgumentException Thrown if the URL is too long. The
|
||||
+ * length restriction is an implementation specific arbitrary value.
|
||||
+ */
|
||||
+ void setResourcePack(@NotNull String url, @NotNull String hash, boolean required, @Nullable net.kyori.adventure.text.Component resourcePackPrompt);
|
||||
+ /**
|
||||
+ * @return the most recent resource pack status received from the player,
|
||||
+ * or null if no status has ever been received from this player.
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ org.bukkit.event.player.PlayerResourcePackStatusEvent.Status getResourcePackStatus();
|
||||
+
|
||||
+ /**
|
||||
+ * @return the most recent resource pack hash received from the player,
|
||||
+ * or null if no hash has ever been received from this player.
|
||||
+ *
|
||||
+ * @deprecated This is no longer sent from the client and will always be null
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ @Deprecated
|
||||
+ String getResourcePackHash();
|
||||
+
|
||||
+ /**
|
||||
+ * @return true if the last resource pack status received from this player
|
||||
+ * was {@link org.bukkit.event.player.PlayerResourcePackStatusEvent.Status#SUCCESSFULLY_LOADED}
|
||||
+ */
|
||||
+ boolean hasResourcePack();
|
||||
// Paper end
|
||||
|
||||
// Spigot start
|
||||
diff --git a/src/main/java/org/bukkit/event/player/PlayerResourcePackStatusEvent.java b/src/main/java/org/bukkit/event/player/PlayerResourcePackStatusEvent.java
|
||||
index b98195650d49d78ec35970ca0376b6289b861e4b..4c2102a11c3d682d98f0db4ccafa35231e66bcdd 100644
|
||||
--- a/src/main/java/org/bukkit/event/player/PlayerResourcePackStatusEvent.java
|
||||
+++ b/src/main/java/org/bukkit/event/player/PlayerResourcePackStatusEvent.java
|
||||
@@ -11,13 +11,32 @@ import org.jetbrains.annotations.NotNull;
|
||||
public class PlayerResourcePackStatusEvent extends PlayerEvent {
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
+ @Deprecated
|
||||
+ private final String hash; // Paper
|
||||
private final Status status;
|
||||
|
||||
public PlayerResourcePackStatusEvent(@NotNull final Player who, @NotNull Status resourcePackStatus) {
|
||||
super(who);
|
||||
+ this.hash = null; // Paper
|
||||
this.status = resourcePackStatus;
|
||||
}
|
||||
|
||||
+ @Deprecated // Paper
|
||||
+ public PlayerResourcePackStatusEvent(final Player who, Status resourcePackStatus, String hash) {
|
||||
+ super(who);
|
||||
+ this.hash = hash; // Paper
|
||||
+ this.status = resourcePackStatus;
|
||||
+ }
|
||||
+
|
||||
+ @Deprecated
|
||||
+ /**
|
||||
+ * @deprecated Hash does not seem to ever be set
|
||||
+ */
|
||||
+ public String getHash() {
|
||||
+ return this.hash;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
/**
|
||||
* Gets the status of this pack.
|
||||
*
|
390
patches/unapplied/api/0025-Use-ASM-for-event-executors.patch
Normal file
390
patches/unapplied/api/0025-Use-ASM-for-event-executors.patch
Normal file
|
@ -0,0 +1,390 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Techcable <Techcable@outlook.com>
|
||||
Date: Thu, 3 Mar 2016 13:20:33 -0700
|
||||
Subject: [PATCH] Use ASM for event executors.
|
||||
|
||||
Uses method handles for private or static methods.
|
||||
|
||||
diff --git a/build.gradle.kts b/build.gradle.kts
|
||||
index 6ebea1d9fafb08ede7e37dfe1b145a676c7aaaf9..533600dfb2e73736857cc2a10525db7dc2452433 100644
|
||||
--- a/build.gradle.kts
|
||||
+++ b/build.gradle.kts
|
||||
@@ -38,6 +38,9 @@ dependencies {
|
||||
apiAndDocs("net.kyori:adventure-text-serializer-legacy")
|
||||
apiAndDocs("net.kyori:adventure-text-serializer-plain")
|
||||
|
||||
+ implementation("org.ow2.asm:asm:9.1")
|
||||
+ implementation("org.ow2.asm:asm-commons:9.1")
|
||||
+
|
||||
compileOnly("org.apache.maven:maven-resolver-provider:3.8.1")
|
||||
compileOnly("org.apache.maven.resolver:maven-resolver-connector-basic:1.7.0")
|
||||
compileOnly("org.apache.maven.resolver:maven-resolver-transport-http:1.7.0")
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/executor/MethodHandleEventExecutor.java b/src/main/java/com/destroystokyo/paper/event/executor/MethodHandleEventExecutor.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..5b28e9b1daba7834af67dbc193dd656bedd9a994
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/executor/MethodHandleEventExecutor.java
|
||||
@@ -0,0 +1,42 @@
|
||||
+package com.destroystokyo.paper.event.executor;
|
||||
+
|
||||
+import java.lang.invoke.MethodHandle;
|
||||
+import java.lang.invoke.MethodHandles;
|
||||
+import java.lang.reflect.Method;
|
||||
+
|
||||
+import com.destroystokyo.paper.util.SneakyThrow;
|
||||
+import org.bukkit.event.Event;
|
||||
+import org.bukkit.event.EventException;
|
||||
+import org.bukkit.event.Listener;
|
||||
+import org.bukkit.plugin.EventExecutor;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+public class MethodHandleEventExecutor implements EventExecutor {
|
||||
+ private final Class<? extends Event> eventClass;
|
||||
+ private final MethodHandle handle;
|
||||
+
|
||||
+ public MethodHandleEventExecutor(@NotNull Class<? extends Event> eventClass, @NotNull MethodHandle handle) {
|
||||
+ this.eventClass = eventClass;
|
||||
+ this.handle = handle;
|
||||
+ }
|
||||
+
|
||||
+ public MethodHandleEventExecutor(@NotNull Class<? extends Event> eventClass, @NotNull Method m) {
|
||||
+ this.eventClass = eventClass;
|
||||
+ try {
|
||||
+ m.setAccessible(true);
|
||||
+ this.handle = MethodHandles.lookup().unreflect(m);
|
||||
+ } catch (IllegalAccessException e) {
|
||||
+ throw new AssertionError("Unable to set accessible", e);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void execute(@NotNull Listener listener, @NotNull Event event) throws EventException {
|
||||
+ if (!eventClass.isInstance(event)) return;
|
||||
+ try {
|
||||
+ handle.invoke(listener, event);
|
||||
+ } catch (Throwable t) {
|
||||
+ SneakyThrow.sneaky(t);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/executor/StaticMethodHandleEventExecutor.java b/src/main/java/com/destroystokyo/paper/event/executor/StaticMethodHandleEventExecutor.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..c83672427324bd068ed52916f700b68446a226f6
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/executor/StaticMethodHandleEventExecutor.java
|
||||
@@ -0,0 +1,43 @@
|
||||
+package com.destroystokyo.paper.event.executor;
|
||||
+
|
||||
+import java.lang.invoke.MethodHandle;
|
||||
+import java.lang.invoke.MethodHandles;
|
||||
+import java.lang.reflect.Method;
|
||||
+import java.lang.reflect.Modifier;
|
||||
+
|
||||
+import com.destroystokyo.paper.util.SneakyThrow;
|
||||
+import com.google.common.base.Preconditions;
|
||||
+
|
||||
+import org.bukkit.Bukkit;
|
||||
+import org.bukkit.event.Event;
|
||||
+import org.bukkit.event.EventException;
|
||||
+import org.bukkit.event.Listener;
|
||||
+import org.bukkit.plugin.EventExecutor;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+public class StaticMethodHandleEventExecutor implements EventExecutor {
|
||||
+ private final Class<? extends Event> eventClass;
|
||||
+ private final MethodHandle handle;
|
||||
+
|
||||
+ public StaticMethodHandleEventExecutor(@NotNull Class<? extends Event> eventClass, @NotNull Method m) {
|
||||
+ Preconditions.checkArgument(Modifier.isStatic(m.getModifiers()), "Not a static method: %s", m);
|
||||
+ Preconditions.checkArgument(eventClass != null, "eventClass is null");
|
||||
+ this.eventClass = eventClass;
|
||||
+ try {
|
||||
+ m.setAccessible(true);
|
||||
+ this.handle = MethodHandles.lookup().unreflect(m);
|
||||
+ } catch (IllegalAccessException e) {
|
||||
+ throw new AssertionError("Unable to set accessible", e);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void execute(@NotNull Listener listener, @NotNull Event event) throws EventException {
|
||||
+ if (!eventClass.isInstance(event)) return;
|
||||
+ try {
|
||||
+ handle.invoke(event);
|
||||
+ } catch (Throwable throwable) {
|
||||
+ SneakyThrow.sneaky(throwable);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/executor/asm/ASMEventExecutorGenerator.java b/src/main/java/com/destroystokyo/paper/event/executor/asm/ASMEventExecutorGenerator.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..b6e7d8ee8d903ebf975d60bec0e08603d9a49fdb
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/executor/asm/ASMEventExecutorGenerator.java
|
||||
@@ -0,0 +1,47 @@
|
||||
+package com.destroystokyo.paper.event.executor.asm;
|
||||
+
|
||||
+import java.lang.reflect.Method;
|
||||
+import java.util.concurrent.atomic.AtomicInteger;
|
||||
+
|
||||
+import org.bukkit.plugin.EventExecutor;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.objectweb.asm.ClassWriter;
|
||||
+import org.objectweb.asm.Type;
|
||||
+import org.objectweb.asm.commons.GeneratorAdapter;
|
||||
+
|
||||
+import static org.objectweb.asm.Opcodes.*;
|
||||
+
|
||||
+public class ASMEventExecutorGenerator {
|
||||
+ @NotNull
|
||||
+ public static byte[] generateEventExecutor(@NotNull Method m, @NotNull String name) {
|
||||
+ ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
|
||||
+ writer.visit(V1_8, ACC_PUBLIC, name.replace('.', '/'), null, Type.getInternalName(Object.class), new String[] {Type.getInternalName(EventExecutor.class)});
|
||||
+ // Generate constructor
|
||||
+ GeneratorAdapter methodGenerator = new GeneratorAdapter(writer.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null), ACC_PUBLIC, "<init>", "()V");
|
||||
+ methodGenerator.loadThis();
|
||||
+ methodGenerator.visitMethodInsn(INVOKESPECIAL, Type.getInternalName(Object.class), "<init>", "()V", false); // Invoke the super class (Object) constructor
|
||||
+ methodGenerator.returnValue();
|
||||
+ methodGenerator.endMethod();
|
||||
+ // Generate the execute method
|
||||
+ methodGenerator = new GeneratorAdapter(writer.visitMethod(ACC_PUBLIC, "execute", "(Lorg/bukkit/event/Listener;Lorg/bukkit/event/Event;)V", null, null), ACC_PUBLIC, "execute", "(Lorg/bukkit/event/Listener;Lorg/bukkit/event/Listener;)V");;
|
||||
+ methodGenerator.loadArg(0);
|
||||
+ methodGenerator.checkCast(Type.getType(m.getDeclaringClass()));
|
||||
+ methodGenerator.loadArg(1);
|
||||
+ methodGenerator.checkCast(Type.getType(m.getParameterTypes()[0]));
|
||||
+ methodGenerator.visitMethodInsn(m.getDeclaringClass().isInterface() ? INVOKEINTERFACE : INVOKEVIRTUAL, Type.getInternalName(m.getDeclaringClass()), m.getName(), Type.getMethodDescriptor(m), m.getDeclaringClass().isInterface());
|
||||
+ if (m.getReturnType() != void.class) {
|
||||
+ methodGenerator.pop();
|
||||
+ }
|
||||
+ methodGenerator.returnValue();
|
||||
+ methodGenerator.endMethod();
|
||||
+ writer.visitEnd();
|
||||
+ return writer.toByteArray();
|
||||
+ }
|
||||
+
|
||||
+ public static AtomicInteger NEXT_ID = new AtomicInteger(1);
|
||||
+ @NotNull
|
||||
+ public static String generateName() {
|
||||
+ int id = NEXT_ID.getAndIncrement();
|
||||
+ return "com.destroystokyo.paper.event.executor.asm.generated.GeneratedEventExecutor" + id;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/executor/asm/ClassDefiner.java b/src/main/java/com/destroystokyo/paper/event/executor/asm/ClassDefiner.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..f79685b48bb581277a6891927988b6f7a4389dc4
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/executor/asm/ClassDefiner.java
|
||||
@@ -0,0 +1,34 @@
|
||||
+package com.destroystokyo.paper.event.executor.asm;
|
||||
+
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+public interface ClassDefiner {
|
||||
+
|
||||
+ /**
|
||||
+ * Returns if the defined classes can bypass access checks
|
||||
+ *
|
||||
+ * @return if classes bypass access checks
|
||||
+ */
|
||||
+ public default boolean isBypassAccessChecks() {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Define a class
|
||||
+ *
|
||||
+ * @param parentLoader the parent classloader
|
||||
+ * @param name the name of the class
|
||||
+ * @param data the class data to load
|
||||
+ * @return the defined class
|
||||
+ * @throws ClassFormatError if the class data is invalid
|
||||
+ * @throws NullPointerException if any of the arguments are null
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Class<?> defineClass(@NotNull ClassLoader parentLoader, @NotNull String name, @NotNull byte[] data);
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static ClassDefiner getInstance() {
|
||||
+ return SafeClassDefiner.INSTANCE;
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/executor/asm/SafeClassDefiner.java b/src/main/java/com/destroystokyo/paper/event/executor/asm/SafeClassDefiner.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..ac99477e9f2c08041aeff31abc1d1edee58d0a67
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/executor/asm/SafeClassDefiner.java
|
||||
@@ -0,0 +1,66 @@
|
||||
+package com.destroystokyo.paper.event.executor.asm;
|
||||
+
|
||||
+import java.util.concurrent.ConcurrentHashMap;
|
||||
+import java.util.concurrent.ConcurrentMap;
|
||||
+
|
||||
+import com.google.common.base.Preconditions;
|
||||
+
|
||||
+import com.google.common.collect.MapMaker;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.objectweb.asm.Type;
|
||||
+
|
||||
+public class SafeClassDefiner implements ClassDefiner {
|
||||
+ /* default */ static final SafeClassDefiner INSTANCE = new SafeClassDefiner();
|
||||
+
|
||||
+ private SafeClassDefiner() {}
|
||||
+
|
||||
+ private final ConcurrentMap<ClassLoader, GeneratedClassLoader> loaders = new MapMaker().weakKeys().makeMap();
|
||||
+
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public Class<?> defineClass(@NotNull ClassLoader parentLoader, @NotNull String name, @NotNull byte[] data) {
|
||||
+ GeneratedClassLoader loader = loaders.computeIfAbsent(parentLoader, GeneratedClassLoader::new);
|
||||
+ synchronized (loader.getClassLoadingLock(name)) {
|
||||
+ Preconditions.checkState(!loader.hasClass(name), "%s already defined", name);
|
||||
+ Class<?> c = loader.define(name, data);
|
||||
+ assert c.getName().equals(name);
|
||||
+ return c;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private static class GeneratedClassLoader extends ClassLoader {
|
||||
+ static {
|
||||
+ ClassLoader.registerAsParallelCapable();
|
||||
+ }
|
||||
+
|
||||
+ protected GeneratedClassLoader(@NotNull ClassLoader parent) {
|
||||
+ super(parent);
|
||||
+ }
|
||||
+
|
||||
+ private Class<?> define(@NotNull String name, byte[] data) {
|
||||
+ synchronized (getClassLoadingLock(name)) {
|
||||
+ assert !hasClass(name);
|
||||
+ Class<?> c = defineClass(name, data, 0, data.length);
|
||||
+ resolveClass(c);
|
||||
+ return c;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ @NotNull
|
||||
+ public Object getClassLoadingLock(@NotNull String name) {
|
||||
+ return super.getClassLoadingLock(name);
|
||||
+ }
|
||||
+
|
||||
+ public boolean hasClass(@NotNull String name) {
|
||||
+ synchronized (getClassLoadingLock(name)) {
|
||||
+ try {
|
||||
+ Class.forName(name);
|
||||
+ return true;
|
||||
+ } catch (ClassNotFoundException e) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/plugin/EventExecutor.java b/src/main/java/org/bukkit/plugin/EventExecutor.java
|
||||
index a850f0780de05463fc0d3f9e15ff7f19d88b2aed..9026e108ccd3a88aee1267ee275137befa646455 100644
|
||||
--- a/src/main/java/org/bukkit/plugin/EventExecutor.java
|
||||
+++ b/src/main/java/org/bukkit/plugin/EventExecutor.java
|
||||
@@ -5,9 +5,75 @@ import org.bukkit.event.EventException;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
+// Paper start
|
||||
+import java.lang.reflect.Method;
|
||||
+import java.lang.reflect.Modifier;
|
||||
+import java.util.concurrent.ConcurrentHashMap;
|
||||
+import java.util.concurrent.ConcurrentMap;
|
||||
+import java.util.function.Function;
|
||||
+
|
||||
+import com.destroystokyo.paper.event.executor.MethodHandleEventExecutor;
|
||||
+import com.destroystokyo.paper.event.executor.StaticMethodHandleEventExecutor;
|
||||
+import com.destroystokyo.paper.event.executor.asm.ASMEventExecutorGenerator;
|
||||
+import com.destroystokyo.paper.event.executor.asm.ClassDefiner;
|
||||
+import com.google.common.base.Preconditions;
|
||||
+// Paper end
|
||||
+
|
||||
/**
|
||||
* Interface which defines the class for event call backs to plugins
|
||||
*/
|
||||
public interface EventExecutor {
|
||||
public void execute(@NotNull Listener listener, @NotNull Event event) throws EventException;
|
||||
+
|
||||
+ // Paper start
|
||||
+ ConcurrentMap<Method, Class<? extends EventExecutor>> eventExecutorMap = new ConcurrentHashMap<Method, Class<? extends EventExecutor>>() {
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public Class<? extends EventExecutor> computeIfAbsent(@NotNull Method key, @NotNull Function<? super Method, ? extends Class<? extends EventExecutor>> mappingFunction) {
|
||||
+ Class<? extends EventExecutor> executorClass = get(key);
|
||||
+ if (executorClass != null)
|
||||
+ return executorClass;
|
||||
+
|
||||
+ //noinspection SynchronizationOnLocalVariableOrMethodParameter
|
||||
+ synchronized (key) {
|
||||
+ executorClass = get(key);
|
||||
+ if (executorClass != null)
|
||||
+ return executorClass;
|
||||
+
|
||||
+ return super.computeIfAbsent(key, mappingFunction);
|
||||
+ }
|
||||
+ }
|
||||
+ };
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static EventExecutor create(@NotNull Method m, @NotNull Class<? extends Event> eventClass) {
|
||||
+ Preconditions.checkNotNull(m, "Null method");
|
||||
+ Preconditions.checkArgument(m.getParameterCount() != 0, "Incorrect number of arguments %s", m.getParameterCount());
|
||||
+ Preconditions.checkArgument(m.getParameterTypes()[0] == eventClass, "First parameter %s doesn't match event class %s", m.getParameterTypes()[0], eventClass);
|
||||
+ ClassDefiner definer = ClassDefiner.getInstance();
|
||||
+ if (Modifier.isStatic(m.getModifiers())) {
|
||||
+ return new StaticMethodHandleEventExecutor(eventClass, m);
|
||||
+ } else if (definer.isBypassAccessChecks() || Modifier.isPublic(m.getDeclaringClass().getModifiers()) && Modifier.isPublic(m.getModifiers())) {
|
||||
+ // get the existing generated EventExecutor class for the Method or generate one
|
||||
+ Class<? extends EventExecutor> executorClass = eventExecutorMap.computeIfAbsent(m, (__) -> {
|
||||
+ String name = ASMEventExecutorGenerator.generateName();
|
||||
+ byte[] classData = ASMEventExecutorGenerator.generateEventExecutor(m, name);
|
||||
+ return definer.defineClass(m.getDeclaringClass().getClassLoader(), name, classData).asSubclass(EventExecutor.class);
|
||||
+ });
|
||||
+
|
||||
+ try {
|
||||
+ EventExecutor asmExecutor = executorClass.newInstance();
|
||||
+ // Define a wrapper to conform to bukkit stupidity (passing in events that don't match and wrapper exception)
|
||||
+ return (listener, event) -> {
|
||||
+ if (!eventClass.isInstance(event)) return;
|
||||
+ asmExecutor.execute(listener, event);
|
||||
+ };
|
||||
+ } catch (InstantiationException | IllegalAccessException e) {
|
||||
+ throw new AssertionError("Unable to initialize generated event executor", e);
|
||||
+ }
|
||||
+ } else {
|
||||
+ return new MethodHandleEventExecutor(eventClass, m);
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
|
||||
index 2e306c7b984a02e12a74fac14589bf29ab6488bf..79ac529017aac059d13fe342f279e9c8faeba599 100644
|
||||
--- a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
|
||||
+++ b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
|
||||
@@ -291,21 +291,7 @@ public final class JavaPluginLoader implements PluginLoader {
|
||||
}
|
||||
}
|
||||
|
||||
- EventExecutor executor = new co.aikar.timings.TimedEventExecutor(new EventExecutor() { // Paper
|
||||
- @Override
|
||||
- public void execute(@NotNull Listener listener, @NotNull Event event) throws EventException { // Paper
|
||||
- try {
|
||||
- if (!eventClass.isAssignableFrom(event.getClass())) {
|
||||
- return;
|
||||
- }
|
||||
- method.invoke(listener, event);
|
||||
- } catch (InvocationTargetException ex) {
|
||||
- throw new EventException(ex.getCause());
|
||||
- } catch (Throwable t) {
|
||||
- throw new EventException(t);
|
||||
- }
|
||||
- }
|
||||
- }, plugin, method, eventClass); // Paper
|
||||
+ EventExecutor executor = new co.aikar.timings.TimedEventExecutor(EventExecutor.create(method, eventClass), plugin, method, eventClass); // Paper // Paper (Yes.) - Use factory method `EventExecutor.create()`
|
||||
if (false) { // Spigot - RL handles useTimings check now
|
||||
eventSet.add(new TimedRegisteredListener(listener, executor, eh.priority(), plugin, eh.ignoreCancelled()));
|
||||
} else {
|
34
patches/unapplied/api/0026-Add-a-call-helper-to-Event.patch
Normal file
34
patches/unapplied/api/0026-Add-a-call-helper-to-Event.patch
Normal file
|
@ -0,0 +1,34 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sun, 19 May 2013 20:36:58 -0400
|
||||
Subject: [PATCH] Add a call helper to Event
|
||||
|
||||
Reduces diff in Server patches
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/event/Event.java b/src/main/java/org/bukkit/event/Event.java
|
||||
index 18d0636b749913bfdcea8eebc7d0840d192fb071..8ec56cd6b8e0f5c5dd8c7c88b4671e18dcf109d0 100644
|
||||
--- a/src/main/java/org/bukkit/event/Event.java
|
||||
+++ b/src/main/java/org/bukkit/event/Event.java
|
||||
@@ -35,6 +35,22 @@ public abstract class Event {
|
||||
this.async = isAsync;
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Calls the event and tests if cancelled.
|
||||
+ *
|
||||
+ * @return false if event was cancelled, if cancellable. otherwise true.
|
||||
+ */
|
||||
+ public boolean callEvent() {
|
||||
+ org.bukkit.Bukkit.getPluginManager().callEvent(this);
|
||||
+ if (this instanceof Cancellable) {
|
||||
+ return !((Cancellable) this).isCancelled();
|
||||
+ } else {
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
/**
|
||||
* Convenience method for providing a user-friendly identifier. By
|
||||
* default, it is the event's class's {@linkplain Class#getSimpleName()
|
|
@ -0,0 +1,43 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Wed, 22 Jul 2015 18:50:41 -0400
|
||||
Subject: [PATCH] Add sender name to commands.yml replacement
|
||||
|
||||
This allows you to use $sender in commands.yml definitions to make
|
||||
commands that auto target self.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/command/FormattedCommandAlias.java b/src/main/java/org/bukkit/command/FormattedCommandAlias.java
|
||||
index a6ad94ef98a1df1d2842635d850bc990b0137849..9d4f553c04784cca63901a56a7aea62a5cae1d72 100644
|
||||
--- a/src/main/java/org/bukkit/command/FormattedCommandAlias.java
|
||||
+++ b/src/main/java/org/bukkit/command/FormattedCommandAlias.java
|
||||
@@ -1,6 +1,9 @@
|
||||
package org.bukkit.command;
|
||||
|
||||
import java.util.ArrayList;
|
||||
+import java.util.regex.Matcher; // Paper
|
||||
+import java.util.regex.Pattern; // Paper
|
||||
+
|
||||
import org.bukkit.Bukkit;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -19,7 +22,7 @@ public class FormattedCommandAlias extends Command {
|
||||
ArrayList<String> commands = new ArrayList<String>();
|
||||
for (String formatString : formatStrings) {
|
||||
try {
|
||||
- commands.add(buildCommand(formatString, args));
|
||||
+ commands.add(buildCommand(sender, formatString, args)); // Paper
|
||||
} catch (Throwable throwable) {
|
||||
if (throwable instanceof IllegalArgumentException) {
|
||||
sender.sendMessage(throwable.getMessage());
|
||||
@@ -37,7 +40,10 @@ public class FormattedCommandAlias extends Command {
|
||||
return result;
|
||||
}
|
||||
|
||||
- private String buildCommand(@NotNull String formatString, @NotNull String[] args) {
|
||||
+ private String buildCommand(@NotNull CommandSender sender, @NotNull String formatString, @NotNull String[] args) { // Paper
|
||||
+ if (formatString.contains("$sender")) { // Paper
|
||||
+ formatString = formatString.replaceAll(Pattern.quote("$sender"), Matcher.quoteReplacement(sender.getName())); // Paper
|
||||
+ } // Paper
|
||||
int index = formatString.indexOf('$');
|
||||
while (index != -1) {
|
||||
int start = index;
|
|
@ -0,0 +1,104 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: William <admin@domnian.com>
|
||||
Date: Fri, 18 Mar 2016 03:28:07 -0400
|
||||
Subject: [PATCH] Add command to reload permissions.yml and require confirm to
|
||||
reload
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
|
||||
index 0b6299a586e25f97eb734e650728e50d19ad16ce..308d9cd655c37e8a00bb053ecd2ba2450555158f 100644
|
||||
--- a/src/main/java/org/bukkit/Bukkit.java
|
||||
+++ b/src/main/java/org/bukkit/Bukkit.java
|
||||
@@ -1890,6 +1890,13 @@ public final class Bukkit {
|
||||
public static org.bukkit.command.CommandMap getCommandMap() {
|
||||
return server.getCommandMap();
|
||||
}
|
||||
+
|
||||
+ /**
|
||||
+ * Reload the Permissions in permissions.yml
|
||||
+ */
|
||||
+ public static void reloadPermissions() {
|
||||
+ server.reloadPermissions();
|
||||
+ }
|
||||
// Paper end
|
||||
|
||||
@NotNull
|
||||
diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
|
||||
index 797ff4d2b16fba1a423c8dc247fde0ad9199b5c1..51d7ec1b9ede6a1fe11d1bddc7a58213add72cbc 100644
|
||||
--- a/src/main/java/org/bukkit/Server.java
|
||||
+++ b/src/main/java/org/bukkit/Server.java
|
||||
@@ -1670,4 +1670,6 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
|
||||
@NotNull
|
||||
Spigot spigot();
|
||||
// Spigot end
|
||||
+
|
||||
+ void reloadPermissions(); // Paper
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/command/defaults/ReloadCommand.java b/src/main/java/org/bukkit/command/defaults/ReloadCommand.java
|
||||
index 50cc311be7904cc8fc6070a21c8e4de3a489fd20..c62da4131b17e66892678e8b618fb9ba3de93b56 100644
|
||||
--- a/src/main/java/org/bukkit/command/defaults/ReloadCommand.java
|
||||
+++ b/src/main/java/org/bukkit/command/defaults/ReloadCommand.java
|
||||
@@ -13,15 +13,35 @@ public class ReloadCommand extends BukkitCommand {
|
||||
public ReloadCommand(@NotNull String name) {
|
||||
super(name);
|
||||
this.description = "Reloads the server configuration and plugins";
|
||||
- this.usageMessage = "/reload";
|
||||
+ this.usageMessage = "/reload [permissions]"; // Paper
|
||||
this.setPermission("bukkit.command.reload");
|
||||
this.setAliases(Arrays.asList("rl"));
|
||||
}
|
||||
|
||||
@Override
|
||||
- public boolean execute(@NotNull CommandSender sender, @NotNull String currentAlias, @NotNull String[] args) {
|
||||
+ public boolean execute(@NotNull CommandSender sender, @NotNull String currentAlias, @NotNull String[] args) { // Paper
|
||||
if (!testPermission(sender)) return true;
|
||||
|
||||
+ // Paper start - Reload permissions.yml & require confirm
|
||||
+ boolean confirmed = System.getProperty("LetMeReload") != null;
|
||||
+ if (args.length == 1) {
|
||||
+ if (args[0].equalsIgnoreCase("permissions")) {
|
||||
+ Bukkit.getServer().reloadPermissions();
|
||||
+ Command.broadcastCommandMessage(sender, ChatColor.GREEN + "Permissions successfully reloaded.");
|
||||
+ return true;
|
||||
+ } else if ("confirm".equalsIgnoreCase(args[0])) {
|
||||
+ confirmed = true;
|
||||
+ } else {
|
||||
+ Command.broadcastCommandMessage(sender, ChatColor.RED + "Usage: " + usageMessage);
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+ if (!confirmed) {
|
||||
+ Command.broadcastCommandMessage(sender, ChatColor.RED + "Are you sure you wish to reload your server? Doing so may cause bugs and memory leaks. It is recommended to restart instead of using /reload. To confirm, please type " + ChatColor.YELLOW + "/reload confirm");
|
||||
+ return true;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
Command.broadcastCommandMessage(sender, ChatColor.RED + "Please note that this command is not supported and may cause issues when using some plugins.");
|
||||
Command.broadcastCommandMessage(sender, ChatColor.RED + "If you encounter any issues please use the /stop command to restart your server.");
|
||||
Bukkit.reload();
|
||||
@@ -33,6 +53,6 @@ public class ReloadCommand extends BukkitCommand {
|
||||
@NotNull
|
||||
@Override
|
||||
public List<String> tabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException {
|
||||
- return Collections.emptyList();
|
||||
+ return java.util.Collections.singletonList("permissions"); // Paper
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/plugin/SimplePluginManager.java b/src/main/java/org/bukkit/plugin/SimplePluginManager.java
|
||||
index c2c49ee9b5531bc4761d2da54cd707c57fc647bf..2d27dfb859c312d46a14d0356c7c3f227e965a67 100644
|
||||
--- a/src/main/java/org/bukkit/plugin/SimplePluginManager.java
|
||||
+++ b/src/main/java/org/bukkit/plugin/SimplePluginManager.java
|
||||
@@ -895,4 +895,13 @@ public final class SimplePluginManager implements PluginManager {
|
||||
public void useTimings(boolean use) {
|
||||
co.aikar.timings.Timings.setTimingsEnabled(use); // Paper
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ public void clearPermissions() {
|
||||
+ permissions.clear();
|
||||
+ defaultPerms.get(true).clear();
|
||||
+ defaultPerms.get(false).clear();
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jedediah Smith <jedediah@silencegreys.com>
|
||||
Date: Sun, 21 Jun 2015 15:05:21 -0400
|
||||
Subject: [PATCH] Custom replacement for eaten items
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/event/player/PlayerItemConsumeEvent.java b/src/main/java/org/bukkit/event/player/PlayerItemConsumeEvent.java
|
||||
index c2793f3ef01c1246c130971c17e1c2bf8f551435..373f4b5b5185aa81ff728da89c9cc4e0ccf87889 100644
|
||||
--- a/src/main/java/org/bukkit/event/player/PlayerItemConsumeEvent.java
|
||||
+++ b/src/main/java/org/bukkit/event/player/PlayerItemConsumeEvent.java
|
||||
@@ -22,6 +22,7 @@ public class PlayerItemConsumeEvent extends PlayerEvent implements Cancellable {
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private boolean isCancelled = false;
|
||||
private ItemStack item;
|
||||
+ @Nullable private ItemStack replacement; // Paper
|
||||
|
||||
/**
|
||||
* @param player the player consuming
|
||||
@@ -58,6 +59,29 @@ public class PlayerItemConsumeEvent extends PlayerEvent implements Cancellable {
|
||||
}
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Return the custom item stack that will replace the consumed item, or null if no
|
||||
+ * custom replacement has been set (which means the default replacement will be used).
|
||||
+ *
|
||||
+ * @return The custom item stack that will replace the consumed item or null
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public ItemStack getReplacement() {
|
||||
+ return this.replacement;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Set a custom item stack to replace the consumed item. Pass null to clear any custom
|
||||
+ * stack that has been set and use the default replacement.
|
||||
+ *
|
||||
+ * @param replacement Replacement item to set, null to clear any custom stack and use default
|
||||
+ */
|
||||
+ public void setReplacement(@Nullable ItemStack replacement) {
|
||||
+ this.replacement = replacement;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return this.isCancelled;
|
|
@ -0,0 +1,79 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 28 Mar 2016 20:26:34 -0400
|
||||
Subject: [PATCH] Entity AddTo/RemoveFrom World Events
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/EntityAddToWorldEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/EntityAddToWorldEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..07660202e41ee86f1b66bad3335cf6fe126e7f9c
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/entity/EntityAddToWorldEvent.java
|
||||
@@ -0,0 +1,32 @@
|
||||
+package com.destroystokyo.paper.event.entity;
|
||||
+
|
||||
+import org.bukkit.entity.Entity;
|
||||
+import org.bukkit.event.Event;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.entity.EntityEvent;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * Fired any time an entity is being added to the world for any reason.
|
||||
+ *
|
||||
+ * Not to be confused with {@link org.bukkit.event.entity.CreatureSpawnEvent}
|
||||
+ * This will fire anytime a chunk is reloaded too.
|
||||
+ */
|
||||
+public class EntityAddToWorldEvent extends EntityEvent {
|
||||
+
|
||||
+ public EntityAddToWorldEvent(@NotNull Entity entity) {
|
||||
+ super(entity);
|
||||
+ }
|
||||
+
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+
|
||||
+ @NotNull
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/EntityRemoveFromWorldEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/EntityRemoveFromWorldEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..e5dbbd660409bae0d3b96e83390511d3a423a52e
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/entity/EntityRemoveFromWorldEvent.java
|
||||
@@ -0,0 +1,29 @@
|
||||
+package com.destroystokyo.paper.event.entity;
|
||||
+
|
||||
+import org.bukkit.entity.Entity;
|
||||
+import org.bukkit.event.Event;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.entity.EntityEvent;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * Fired any time an entity is being removed from a world for any reason
|
||||
+ */
|
||||
+public class EntityRemoveFromWorldEvent extends EntityEvent {
|
||||
+
|
||||
+ public EntityRemoveFromWorldEvent(@NotNull Entity entity) {
|
||||
+ super(entity);
|
||||
+ }
|
||||
+
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+
|
||||
+ @NotNull
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+}
|
95
patches/unapplied/api/0031-EntityPathfindEvent.patch
Normal file
95
patches/unapplied/api/0031-EntityPathfindEvent.patch
Normal file
|
@ -0,0 +1,95 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 28 Mar 2016 21:15:34 -0400
|
||||
Subject: [PATCH] EntityPathfindEvent
|
||||
|
||||
Fires when an Entity decides to start moving to a location.
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/EntityPathfindEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/EntityPathfindEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..63e46b2fb1b12b36fcb1e98b178cf29dd2e3d1b5
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/entity/EntityPathfindEvent.java
|
||||
@@ -0,0 +1,82 @@
|
||||
+package com.destroystokyo.paper.event.entity;
|
||||
+
|
||||
+import org.bukkit.Location;
|
||||
+import org.bukkit.entity.Entity;
|
||||
+import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.entity.EntityEvent;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
+
|
||||
+/**
|
||||
+ * Fired when an Entity decides to start moving towards a location.
|
||||
+ *
|
||||
+ * This event does not fire for the entities actual movement. Only when it
|
||||
+ * is choosing to start moving to a location.
|
||||
+ */
|
||||
+public class EntityPathfindEvent extends EntityEvent implements Cancellable {
|
||||
+ @Nullable private final Entity targetEntity;
|
||||
+ @NotNull private final Location loc;
|
||||
+
|
||||
+ public EntityPathfindEvent(@NotNull Entity entity, @NotNull Location loc, @Nullable Entity targetEntity) {
|
||||
+ super(entity);
|
||||
+ this.targetEntity = targetEntity;
|
||||
+ this.loc = loc;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * The Entity that is pathfinding.
|
||||
+ * @return The Entity that is pathfinding.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Entity getEntity() {
|
||||
+ return entity;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * If the Entity is trying to pathfind to an entity, this is the entity in relation.
|
||||
+ *
|
||||
+ * Otherwise this will return null.
|
||||
+ *
|
||||
+ * @return The entity target or null
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public Entity getTargetEntity() {
|
||||
+ return targetEntity;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * The Location of where the entity is about to move to.
|
||||
+ *
|
||||
+ * Note that if the target happened to of been an entity
|
||||
+ * @return Location of where the entity is trying to pathfind to.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Location getLoc() {
|
||||
+ return loc;
|
||||
+ }
|
||||
+
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+
|
||||
+ @NotNull
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ private boolean cancelled = false;
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isCancelled() {
|
||||
+ return cancelled;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setCancelled(boolean cancel) {
|
||||
+ cancelled = cancel;
|
||||
+ }
|
||||
+}
|
|
@ -0,0 +1,90 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: crast <contact@jamescrasta.com>
|
||||
Date: Sat, 1 Jun 2013 13:52:30 -0600
|
||||
Subject: [PATCH] Reduce thread synchronization in MetadataStoreBase
|
||||
|
||||
Use ConcurrentHashMap to allow thread-safe access methods and very
|
||||
limited synchronized portions to allow much higher concurrency in
|
||||
MetadataStore as well as far less locking, especially on reads
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/metadata/MetadataStoreBase.java b/src/main/java/org/bukkit/metadata/MetadataStoreBase.java
|
||||
index baf850226aed8545a5794deba6dff9603953b4b2..d363d517c05b3335101d829ce4ec22d049059c24 100644
|
||||
--- a/src/main/java/org/bukkit/metadata/MetadataStoreBase.java
|
||||
+++ b/src/main/java/org/bukkit/metadata/MetadataStoreBase.java
|
||||
@@ -12,7 +12,7 @@ import org.bukkit.plugin.Plugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public abstract class MetadataStoreBase<T> {
|
||||
- private Map<String, Map<Plugin, MetadataValue>> metadataMap = new HashMap<String, Map<Plugin, MetadataValue>>();
|
||||
+ private Map<String, Map<Plugin, MetadataValue>> metadataMap = new java.util.concurrent.ConcurrentHashMap<String, Map<Plugin, MetadataValue>>(); // Paper
|
||||
|
||||
/**
|
||||
* Adds a metadata value to an object. Each metadata value is owned by a
|
||||
@@ -46,7 +46,9 @@ public abstract class MetadataStoreBase<T> {
|
||||
entry = new WeakHashMap<Plugin, MetadataValue>(1);
|
||||
metadataMap.put(key, entry);
|
||||
}
|
||||
- entry.put(owningPlugin, newMetadataValue);
|
||||
+ synchronized (entry) {
|
||||
+ entry.put(owningPlugin, newMetadataValue);
|
||||
+ }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -60,10 +62,11 @@ public abstract class MetadataStoreBase<T> {
|
||||
* @see MetadataStore#getMetadata(Object, String)
|
||||
*/
|
||||
@NotNull
|
||||
- public synchronized List<MetadataValue> getMetadata(@NotNull T subject, @NotNull String metadataKey) {
|
||||
+ public List<MetadataValue> getMetadata(@NotNull T subject, @NotNull String metadataKey) { // Paper
|
||||
String key = disambiguate(subject, metadataKey);
|
||||
- if (metadataMap.containsKey(key)) {
|
||||
- Collection<MetadataValue> values = metadataMap.get(key).values();
|
||||
+ Map<Plugin, MetadataValue> entry = metadataMap.get(key);
|
||||
+ if (entry != null) {
|
||||
+ Collection<MetadataValue> values = entry.values();
|
||||
return Collections.unmodifiableList(new ArrayList<MetadataValue>(values));
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
@@ -78,7 +81,7 @@ public abstract class MetadataStoreBase<T> {
|
||||
* @param metadataKey the unique metadata key being queried.
|
||||
* @return the existence of the metadataKey within subject.
|
||||
*/
|
||||
- public synchronized boolean hasMetadata(@NotNull T subject, @NotNull String metadataKey) {
|
||||
+ public boolean hasMetadata(@NotNull T subject, @NotNull String metadataKey) { // Paper
|
||||
String key = disambiguate(subject, metadataKey);
|
||||
return metadataMap.containsKey(key);
|
||||
}
|
||||
@@ -94,17 +97,18 @@ public abstract class MetadataStoreBase<T> {
|
||||
* @see MetadataStore#removeMetadata(Object, String,
|
||||
* org.bukkit.plugin.Plugin)
|
||||
*/
|
||||
- public synchronized void removeMetadata(@NotNull T subject, @NotNull String metadataKey, @NotNull Plugin owningPlugin) {
|
||||
+ public void removeMetadata(@NotNull T subject, @NotNull String metadataKey, @NotNull Plugin owningPlugin) { // Paper
|
||||
Validate.notNull(owningPlugin, "Plugin cannot be null");
|
||||
String key = disambiguate(subject, metadataKey);
|
||||
Map<Plugin, MetadataValue> entry = metadataMap.get(key);
|
||||
if (entry == null) {
|
||||
return;
|
||||
}
|
||||
-
|
||||
- entry.remove(owningPlugin);
|
||||
- if (entry.isEmpty()) {
|
||||
- metadataMap.remove(key);
|
||||
+ synchronized (entry) {
|
||||
+ entry.remove(owningPlugin);
|
||||
+ if (entry.isEmpty()) {
|
||||
+ metadataMap.remove(key);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,7 +121,7 @@ public abstract class MetadataStoreBase<T> {
|
||||
* @throws IllegalArgumentException If plugin is null
|
||||
* @see MetadataStore#invalidateAll(org.bukkit.plugin.Plugin)
|
||||
*/
|
||||
- public synchronized void invalidateAll(@NotNull Plugin owningPlugin) {
|
||||
+ public void invalidateAll(@NotNull Plugin owningPlugin) { // Paper
|
||||
Validate.notNull(owningPlugin, "Plugin cannot be null");
|
||||
for (Map<Plugin, MetadataValue> values : metadataMap.values()) {
|
||||
if (values.containsKey(owningPlugin)) {
|
|
@ -0,0 +1,46 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 16 Jul 2013 21:26:50 -0400
|
||||
Subject: [PATCH] Add MetadataStoreBase.removeAll(Plugin)
|
||||
|
||||
So that on reload, metadata will be cleared
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/metadata/MetadataStoreBase.java b/src/main/java/org/bukkit/metadata/MetadataStoreBase.java
|
||||
index d363d517c05b3335101d829ce4ec22d049059c24..abbe545af572687a0399c2387434863cd2b70f68 100644
|
||||
--- a/src/main/java/org/bukkit/metadata/MetadataStoreBase.java
|
||||
+++ b/src/main/java/org/bukkit/metadata/MetadataStoreBase.java
|
||||
@@ -4,6 +4,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
+import java.util.Iterator; // Paper
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
@@ -130,6 +131,26 @@ public abstract class MetadataStoreBase<T> {
|
||||
}
|
||||
}
|
||||
|
||||
+ /**
|
||||
+ * Removes all metadata in the metadata store that originates from the
|
||||
+ * given plugin.
|
||||
+ *
|
||||
+ * @param owningPlugin the plugin requesting the invalidation.
|
||||
+ * @throws IllegalArgumentException If plugin is null
|
||||
+ */
|
||||
+ public void removeAll(@NotNull Plugin owningPlugin) {
|
||||
+ Validate.notNull(owningPlugin, "Plugin cannot be null");
|
||||
+ for (Iterator<Map<Plugin, MetadataValue>> iterator = metadataMap.values().iterator(); iterator.hasNext(); ) {
|
||||
+ Map<Plugin, MetadataValue> values = iterator.next();
|
||||
+ if (values.containsKey(owningPlugin)) {
|
||||
+ values.remove(owningPlugin);
|
||||
+ }
|
||||
+ if (values.isEmpty()) {
|
||||
+ iterator.remove();
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
/**
|
||||
* Creates a unique name for the object receiving metadata by combining
|
||||
* unique data from the subject with a metadataKey.
|
|
@ -0,0 +1,58 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jedediah Smith <jedediah@silencegreys.com>
|
||||
Date: Sat, 2 Apr 2016 05:08:36 -0400
|
||||
Subject: [PATCH] Add PlayerUseUnknownEntityEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/player/PlayerUseUnknownEntityEvent.java b/src/main/java/com/destroystokyo/paper/event/player/PlayerUseUnknownEntityEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..09cfdf48ead8f03f3497646537292174241b0868
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/player/PlayerUseUnknownEntityEvent.java
|
||||
@@ -0,0 +1,46 @@
|
||||
+package com.destroystokyo.paper.event.player;
|
||||
+
|
||||
+import org.bukkit.entity.Player;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.player.PlayerEvent;
|
||||
+import org.bukkit.inventory.EquipmentSlot;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+public class PlayerUseUnknownEntityEvent extends PlayerEvent {
|
||||
+
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+ private final int entityId;
|
||||
+ private final boolean attack;
|
||||
+ @NotNull private final EquipmentSlot hand;
|
||||
+
|
||||
+ public PlayerUseUnknownEntityEvent(@NotNull Player who, int entityId, boolean attack, @NotNull EquipmentSlot hand) {
|
||||
+ super(who);
|
||||
+ this.entityId = entityId;
|
||||
+ this.attack = attack;
|
||||
+ this.hand = hand;
|
||||
+ }
|
||||
+
|
||||
+ public int getEntityId() {
|
||||
+ return this.entityId;
|
||||
+ }
|
||||
+
|
||||
+ public boolean isAttack() {
|
||||
+ return this.attack;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public EquipmentSlot getHand() {
|
||||
+ return this.hand;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+}
|
|
@ -0,0 +1,290 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: kashike <kashike@vq.lc>
|
||||
Date: Wed, 13 Apr 2016 20:20:18 -0700
|
||||
Subject: [PATCH] Add handshake event to allow plugins to handle client
|
||||
handshaking logic themselves
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/player/PlayerHandshakeEvent.java b/src/main/java/com/destroystokyo/paper/event/player/PlayerHandshakeEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..a077962fa786a3291849abfa823c7f0ec4664fce
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/player/PlayerHandshakeEvent.java
|
||||
@@ -0,0 +1,277 @@
|
||||
+package com.destroystokyo.paper.event.player;
|
||||
+
|
||||
+import net.kyori.adventure.text.Component;
|
||||
+import net.kyori.adventure.text.format.NamedTextColor;
|
||||
+import org.apache.commons.lang.Validate;
|
||||
+import org.bukkit.Bukkit;
|
||||
+import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.event.Event;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+
|
||||
+import java.util.UUID;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
+
|
||||
+/**
|
||||
+ * This event is fired during a player handshake.
|
||||
+ *
|
||||
+ * <p>If there are no listeners listening to this event, the logic default
|
||||
+ * to your server platform will be ran.</p>
|
||||
+ *
|
||||
+ * <p>WARNING: TAMPERING WITH THIS EVENT CAN BE DANGEROUS</p>
|
||||
+ */
|
||||
+public class PlayerHandshakeEvent extends Event implements Cancellable {
|
||||
+
|
||||
+ private static final HandlerList HANDLERS = new HandlerList();
|
||||
+ @NotNull private final String originalHandshake;
|
||||
+ @NotNull private final String originalSocketAddressHostname;
|
||||
+ private boolean cancelled;
|
||||
+ @Nullable private String serverHostname;
|
||||
+ @Nullable private String socketAddressHostname;
|
||||
+ @Nullable private UUID uniqueId;
|
||||
+ @Nullable private String propertiesJson;
|
||||
+ private boolean failed;
|
||||
+ private Component failMessage = Component.text("If you wish to use IP forwarding, please enable it in your BungeeCord config as well!", NamedTextColor.YELLOW);
|
||||
+
|
||||
+ /**
|
||||
+ * Creates a new {@link PlayerHandshakeEvent}.
|
||||
+ *
|
||||
+ * @param originalHandshake the original handshake string
|
||||
+ * @param cancelled if this event is enabled
|
||||
+ *
|
||||
+ * @deprecated in favour of {@link PlayerHandshakeEvent(String, String, boolean)}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ public PlayerHandshakeEvent(@NotNull String originalHandshake, boolean cancelled) {
|
||||
+ this(originalHandshake, "127.0.0.1", cancelled);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Creates a new {@link PlayerHandshakeEvent}.
|
||||
+ *
|
||||
+ * @param originalHandshake the original handshake string
|
||||
+ * @param originalSocketAddressHostname the original socket address hostname
|
||||
+ * @param cancelled if this event is enabled
|
||||
+ */
|
||||
+ public PlayerHandshakeEvent(@NotNull String originalHandshake, @NotNull String originalSocketAddressHostname, boolean cancelled) {
|
||||
+ super(true);
|
||||
+ this.originalHandshake = originalHandshake;
|
||||
+ this.originalSocketAddressHostname = originalSocketAddressHostname;
|
||||
+ this.cancelled = cancelled;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Determines if this event is cancelled.
|
||||
+ *
|
||||
+ * <p>When this event is cancelled, custom handshake logic will not
|
||||
+ * be processed.</p>
|
||||
+ *
|
||||
+ * @return {@code true} if this event is cancelled, {@code false} otherwise
|
||||
+ */
|
||||
+ @Override
|
||||
+ public boolean isCancelled() {
|
||||
+ return this.cancelled;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets if this event is cancelled.
|
||||
+ *
|
||||
+ * <p>When this event is cancelled, custom handshake logic will not
|
||||
+ * be processed.</p>
|
||||
+ *
|
||||
+ * @param cancelled {@code true} if this event is cancelled, {@code false} otherwise
|
||||
+ */
|
||||
+ @Override
|
||||
+ public void setCancelled(boolean cancelled) {
|
||||
+ this.cancelled = cancelled;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the original handshake string.
|
||||
+ *
|
||||
+ * @return the original handshake string
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public String getOriginalHandshake() {
|
||||
+ return this.originalHandshake;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the original socket address hostname.
|
||||
+ *
|
||||
+ * <p>This does not include the port.</p>
|
||||
+ * <p>In cases where this event is manually fired and the plugin wasn't updated yet, the default is {@code "127.0.0.1"}.</p>
|
||||
+ *
|
||||
+ * @return the original socket address hostname
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public String getOriginalSocketAddressHostname() {
|
||||
+ return this.originalSocketAddressHostname;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the server hostname string.
|
||||
+ *
|
||||
+ * <p>This should not include the port.</p>
|
||||
+ *
|
||||
+ * @return the server hostname string
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public String getServerHostname() {
|
||||
+ return this.serverHostname;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the server hostname string.
|
||||
+ *
|
||||
+ * <p>This should not include the port.</p>
|
||||
+ *
|
||||
+ * @param serverHostname the server hostname string
|
||||
+ */
|
||||
+ public void setServerHostname(@NotNull String serverHostname) {
|
||||
+ this.serverHostname = serverHostname;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the socket address hostname string.
|
||||
+ *
|
||||
+ * <p>This should not include the port.</p>
|
||||
+ *
|
||||
+ * @return the socket address hostname string
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public String getSocketAddressHostname() {
|
||||
+ return this.socketAddressHostname;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the socket address hostname string.
|
||||
+ *
|
||||
+ * <p>This should not include the port.</p>
|
||||
+ *
|
||||
+ * @param socketAddressHostname the socket address hostname string
|
||||
+ */
|
||||
+ public void setSocketAddressHostname(@NotNull String socketAddressHostname) {
|
||||
+ this.socketAddressHostname = socketAddressHostname;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the unique id.
|
||||
+ *
|
||||
+ * @return the unique id
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public UUID getUniqueId() {
|
||||
+ return this.uniqueId;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the unique id.
|
||||
+ *
|
||||
+ * @param uniqueId the unique id
|
||||
+ */
|
||||
+ public void setUniqueId(@NotNull UUID uniqueId) {
|
||||
+ this.uniqueId = uniqueId;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the profile properties.
|
||||
+ *
|
||||
+ * <p>This should be a valid JSON string.</p>
|
||||
+ *
|
||||
+ * @return the profile properties, as JSON
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public String getPropertiesJson() {
|
||||
+ return this.propertiesJson;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Determines if authentication failed.
|
||||
+ *
|
||||
+ * <p>When {@code true}, the client connecting will be disconnected
|
||||
+ * with the {@link #getFailMessage() fail message}.</p>
|
||||
+ *
|
||||
+ * @return {@code true} if authentication failed, {@code false} otherwise
|
||||
+ */
|
||||
+ public boolean isFailed() {
|
||||
+ return this.failed;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets if authentication failed and the client should be disconnected.
|
||||
+ *
|
||||
+ * <p>When {@code true}, the client connecting will be disconnected
|
||||
+ * with the {@link #getFailMessage() fail message}.</p>
|
||||
+ *
|
||||
+ * @param failed {@code true} if authentication failed, {@code false} otherwise
|
||||
+ */
|
||||
+ public void setFailed(boolean failed) {
|
||||
+ this.failed = failed;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the profile properties.
|
||||
+ *
|
||||
+ * <p>This should be a valid JSON string.</p>
|
||||
+ *
|
||||
+ * @param propertiesJson the profile properties, as JSON
|
||||
+ */
|
||||
+ public void setPropertiesJson(@NotNull String propertiesJson) {
|
||||
+ this.propertiesJson = propertiesJson;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the message to display to the client when authentication fails.
|
||||
+ *
|
||||
+ * @return the message to display to the client
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Component failMessage() {
|
||||
+ return this.failMessage;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the message to display to the client when authentication fails.
|
||||
+ *
|
||||
+ * @param failMessage the message to display to the client
|
||||
+ */
|
||||
+ public void failMessage(@NotNull Component failMessage) {
|
||||
+ this.failMessage = failMessage;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the message to display to the client when authentication fails.
|
||||
+ *
|
||||
+ * @return the message to display to the client
|
||||
+ * @deprecated use {@link #failMessage()}
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ @Deprecated
|
||||
+ public String getFailMessage() {
|
||||
+ return Bukkit.getUnsafe().legacyComponentSerializer().serialize(this.failMessage());
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the message to display to the client when authentication fails.
|
||||
+ *
|
||||
+ * @param failMessage the message to display to the client
|
||||
+ * @deprecated use {@link #failMessage(Component)}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ public void setFailMessage(@NotNull String failMessage) {
|
||||
+ Validate.notEmpty(failMessage, "fail message cannot be null or empty");
|
||||
+ this.failMessage(Bukkit.getUnsafe().legacyComponentSerializer().deserialize(failMessage));
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return HANDLERS;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return HANDLERS;
|
||||
+ }
|
||||
+}
|
49
patches/unapplied/api/0036-Arrow-pickup-rule-API.patch
Normal file
49
patches/unapplied/api/0036-Arrow-pickup-rule-API.patch
Normal file
|
@ -0,0 +1,49 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jedediah Smith <jedediah@silencegreys.com>
|
||||
Date: Fri, 4 Mar 2016 03:13:18 -0500
|
||||
Subject: [PATCH] Arrow pickup rule API
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/entity/AbstractArrow.java b/src/main/java/org/bukkit/entity/AbstractArrow.java
|
||||
index 5b50a4e10e8ace8cc53ad3c8d7c3185f88d5c8db..e8e56e89e32d84af0639fe2e9b0eeabd747b6007 100644
|
||||
--- a/src/main/java/org/bukkit/entity/AbstractArrow.java
|
||||
+++ b/src/main/java/org/bukkit/entity/AbstractArrow.java
|
||||
@@ -141,4 +141,38 @@ public interface AbstractArrow extends Projectile {
|
||||
*/
|
||||
CREATIVE_ONLY
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Gets the {@link PickupRule} for this arrow.
|
||||
+ *
|
||||
+ * <p>This is generally {@link PickupRule#ALLOWED} only if the arrow was
|
||||
+ * <b>not</b> fired from a bow with the infinity enchantment.</p>
|
||||
+ *
|
||||
+ * @return The pickup rule
|
||||
+ * @deprecated Use {@link Arrow#getPickupStatus()} as an upstream compatible replacement for this function
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ default PickupRule getPickupRule() {
|
||||
+ return PickupRule.valueOf(this.getPickupStatus().name());
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Set the rule for which players can pickup this arrow as an item.
|
||||
+ *
|
||||
+ * @param rule The pickup rule
|
||||
+ * @deprecated Use {@link Arrow#setPickupStatus(PickupStatus)} with {@link PickupStatus} as an upstream compatible replacement for this function
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ default void setPickupRule(PickupRule rule) {
|
||||
+ this.setPickupStatus(PickupStatus.valueOf(rule.name()));
|
||||
+ }
|
||||
+
|
||||
+ @Deprecated
|
||||
+ enum PickupRule {
|
||||
+ DISALLOWED,
|
||||
+ ALLOWED,
|
||||
+ CREATIVE_ONLY;
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <zach.brown@destroystokyo.com>
|
||||
Date: Fri, 22 Apr 2016 01:43:11 -0500
|
||||
Subject: [PATCH] EntityRegainHealthEvent isFastRegen API
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/event/entity/EntityRegainHealthEvent.java b/src/main/java/org/bukkit/event/entity/EntityRegainHealthEvent.java
|
||||
index 8feb6698f9630f099be99e52d1149cd6bc615197..d51d2ec1d04d9ea8a25a70d0d856f2355ebfcb4a 100644
|
||||
--- a/src/main/java/org/bukkit/event/entity/EntityRegainHealthEvent.java
|
||||
+++ b/src/main/java/org/bukkit/event/entity/EntityRegainHealthEvent.java
|
||||
@@ -13,12 +13,31 @@ public class EntityRegainHealthEvent extends EntityEvent implements Cancellable
|
||||
private boolean cancelled;
|
||||
private double amount;
|
||||
private final RegainReason regainReason;
|
||||
+ private final boolean isFastRegen; // Paper
|
||||
|
||||
public EntityRegainHealthEvent(@NotNull final Entity entity, final double amount, @NotNull final RegainReason regainReason) {
|
||||
+ // Paper start - Forward
|
||||
+ this(entity, amount, regainReason, false);
|
||||
+ }
|
||||
+
|
||||
+ public EntityRegainHealthEvent(@NotNull final Entity entity, final double amount, @NotNull final RegainReason regainReason, boolean isFastRegen) {
|
||||
+ // Paper end
|
||||
super(entity);
|
||||
this.amount = amount;
|
||||
this.regainReason = regainReason;
|
||||
+ this.isFastRegen = isFastRegen; // Paper
|
||||
+ }
|
||||
+
|
||||
+ // Paper start - Add getter for isFastRegen
|
||||
+ /**
|
||||
+ * Is this event a result of the fast regeneration mechanic
|
||||
+ *
|
||||
+ * @return Whether the event is the result of a fast regeneration mechanic
|
||||
+ */
|
||||
+ public boolean isFastRegen() {
|
||||
+ return isFastRegen;
|
||||
}
|
||||
+ // Paper end
|
||||
|
||||
/**
|
||||
* Gets the amount of regained health
|
402
patches/unapplied/api/0038-LootTable-API.patch
Normal file
402
patches/unapplied/api/0038-LootTable-API.patch
Normal file
|
@ -0,0 +1,402 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sun, 1 May 2016 15:19:49 -0400
|
||||
Subject: [PATCH] LootTable API
|
||||
|
||||
Provides API to control what Loot Table an object uses.
|
||||
|
||||
Also provides an Event to control if a lootable inventory should
|
||||
auto replenish for a player.
|
||||
|
||||
Provides methods to determine players looted state for an object
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/loottable/LootableBlockInventory.java b/src/main/java/com/destroystokyo/paper/loottable/LootableBlockInventory.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..92d7b853a2ccaae5afa8ac141bead840942944ef
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/loottable/LootableBlockInventory.java
|
||||
@@ -0,0 +1,17 @@
|
||||
+package com.destroystokyo.paper.loottable;
|
||||
+
|
||||
+import org.bukkit.block.Block;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * Represents an Inventory that can generate loot, such as Chests inside of Fortresses and Mineshafts
|
||||
+ */
|
||||
+public interface LootableBlockInventory extends LootableInventory {
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the block that is lootable
|
||||
+ * @return The Block
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ Block getBlock();
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/loottable/LootableEntityInventory.java b/src/main/java/com/destroystokyo/paper/loottable/LootableEntityInventory.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..b387894fe8001edb41ad2ad2b70ebabe065b682e
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/loottable/LootableEntityInventory.java
|
||||
@@ -0,0 +1,17 @@
|
||||
+package com.destroystokyo.paper.loottable;
|
||||
+
|
||||
+import org.bukkit.entity.Entity;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * Represents an Inventory that can generate loot, such as Minecarts inside of Mineshafts
|
||||
+ */
|
||||
+public interface LootableEntityInventory extends LootableInventory {
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the entity that is lootable
|
||||
+ * @return The Entity
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ Entity getEntity();
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/loottable/LootableInventory.java b/src/main/java/com/destroystokyo/paper/loottable/LootableInventory.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..97815eeb231cf0706b34fa47a4f7d1bb786305b4
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/loottable/LootableInventory.java
|
||||
@@ -0,0 +1,116 @@
|
||||
+package com.destroystokyo.paper.loottable;
|
||||
+
|
||||
+import org.bukkit.entity.Player;
|
||||
+import org.bukkit.loot.Lootable;
|
||||
+
|
||||
+import java.util.UUID;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
+
|
||||
+/**
|
||||
+ * Represents an Inventory that contains a Loot Table associated to it that will
|
||||
+ * automatically fill on first open.
|
||||
+ *
|
||||
+ * A new feature and API is provided to support automatically refreshing the contents
|
||||
+ * of the inventory based on that Loot Table after a configurable amount of time has passed.
|
||||
+ *
|
||||
+ * The behavior of how the Inventory is filled based on the loot table may vary based
|
||||
+ * on Minecraft versions and the Loot Table feature.
|
||||
+ */
|
||||
+public interface LootableInventory extends Lootable {
|
||||
+
|
||||
+ /**
|
||||
+ * Server owners have to enable whether or not an object in a world should refill
|
||||
+ *
|
||||
+ * @return If the world this inventory is currently in has Replenishable Lootables enabled
|
||||
+ */
|
||||
+ boolean isRefillEnabled();
|
||||
+
|
||||
+ /**
|
||||
+ * Whether or not this object has ever been filled
|
||||
+ * @return Has ever been filled
|
||||
+ */
|
||||
+ boolean hasBeenFilled();
|
||||
+
|
||||
+ /**
|
||||
+ * Has this player ever looted this block
|
||||
+ * @param player The player to check
|
||||
+ * @return Whether or not this player has looted this block
|
||||
+ */
|
||||
+ default boolean hasPlayerLooted(@NotNull Player player) {
|
||||
+ return hasPlayerLooted(player.getUniqueId());
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Has this player ever looted this block
|
||||
+ * @param player The player to check
|
||||
+ * @return Whether or not this player has looted this block
|
||||
+ */
|
||||
+ boolean hasPlayerLooted(@NotNull UUID player);
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the timestamp, in milliseconds, of when the player last looted this object
|
||||
+ *
|
||||
+ * @param player The player to check
|
||||
+ * @return Timestamp last looted, or null if player has not looted this object
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ default Long getLastLooted(@NotNull Player player) {
|
||||
+ return getLastLooted(player.getUniqueId());
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the timestamp, in milliseconds, of when the player last looted this object
|
||||
+ *
|
||||
+ * @param player The player to check
|
||||
+ * @return Timestamp last looted, or null if player has not looted this object
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ Long getLastLooted(@NotNull UUID player);
|
||||
+
|
||||
+ /**
|
||||
+ * Change the state of whether or not a player has looted this block
|
||||
+ * @param player The player to change state for
|
||||
+ * @param looted true to add player to looted list, false to remove
|
||||
+ * @return The previous state of whether the player had looted this or not
|
||||
+ */
|
||||
+ default boolean setHasPlayerLooted(@NotNull Player player, boolean looted) {
|
||||
+ return setHasPlayerLooted(player.getUniqueId(), looted);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Change the state of whether or not a player has looted this block
|
||||
+ * @param player The player to change state for
|
||||
+ * @param looted true to add player to looted list, false to remove
|
||||
+ * @return The previous state of whether the player had looted this or not
|
||||
+ */
|
||||
+ boolean setHasPlayerLooted(@NotNull UUID player, boolean looted);
|
||||
+
|
||||
+ /**
|
||||
+ * Returns Whether or not this object has been filled and now has a pending refill
|
||||
+ * @return Has pending refill
|
||||
+ */
|
||||
+ boolean hasPendingRefill();
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the timestamp in milliseconds that the Lootable object was last refilled
|
||||
+ *
|
||||
+ * @return -1 if it was never refilled, or timestamp in milliseconds
|
||||
+ */
|
||||
+ long getLastFilled();
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the timestamp in milliseconds that the Lootable object will refill
|
||||
+ *
|
||||
+ * @return -1 if it is not scheduled for refill, or timestamp in milliseconds
|
||||
+ */
|
||||
+ long getNextRefill();
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the timestamp in milliseconds of the next refill for this object
|
||||
+ *
|
||||
+ * @param refillAt timestamp in milliseconds. -1 to clear next refill
|
||||
+ * @return The previous scheduled time to refill, or -1 if was not scheduled
|
||||
+ */
|
||||
+ long setNextRefill(long refillAt);
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/loottable/LootableInventoryReplenishEvent.java b/src/main/java/com/destroystokyo/paper/loottable/LootableInventoryReplenishEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..fd184f13f5e8ee5cf829fff4f44696e1f760430b
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/loottable/LootableInventoryReplenishEvent.java
|
||||
@@ -0,0 +1,45 @@
|
||||
+package com.destroystokyo.paper.loottable;
|
||||
+
|
||||
+import org.bukkit.entity.Player;
|
||||
+import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.player.PlayerEvent;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+public class LootableInventoryReplenishEvent extends PlayerEvent implements Cancellable {
|
||||
+ @NotNull private final LootableInventory inventory;
|
||||
+
|
||||
+ public LootableInventoryReplenishEvent(@NotNull Player player, @NotNull LootableInventory inventory) {
|
||||
+ super(player);
|
||||
+ this.inventory = inventory;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public LootableInventory getInventory() {
|
||||
+ return inventory;
|
||||
+ }
|
||||
+
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+
|
||||
+ @NotNull
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ private boolean cancelled = false;
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isCancelled() {
|
||||
+ return cancelled;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setCancelled(boolean cancel) {
|
||||
+ cancelled = cancel;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/block/Chest.java b/src/main/java/org/bukkit/block/Chest.java
|
||||
index b451191312e4fb19f2131c2d0a0c0337953f6c7c..db6affbc78106b2d93b41953b624a0bca0ca1d72 100644
|
||||
--- a/src/main/java/org/bukkit/block/Chest.java
|
||||
+++ b/src/main/java/org/bukkit/block/Chest.java
|
||||
@@ -1,5 +1,7 @@
|
||||
package org.bukkit.block;
|
||||
|
||||
+import com.destroystokyo.paper.loottable.LootableBlockInventory; // Paper
|
||||
+import org.bukkit.Nameable; // Paper
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.loot.Lootable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -7,7 +9,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
/**
|
||||
* Represents a captured state of a chest.
|
||||
*/
|
||||
-public interface Chest extends Container, Lootable, Lidded {
|
||||
+public interface Chest extends Container, LootableBlockInventory, Lidded { // Paper
|
||||
|
||||
/**
|
||||
* Gets the inventory of the chest block represented by this block state.
|
||||
diff --git a/src/main/java/org/bukkit/block/Dispenser.java b/src/main/java/org/bukkit/block/Dispenser.java
|
||||
index 74cd194c9a98245dc52e7e352d7d6c046e1e5cf3..07af1a3f011d4b96275f919d302ac367198e923e 100644
|
||||
--- a/src/main/java/org/bukkit/block/Dispenser.java
|
||||
+++ b/src/main/java/org/bukkit/block/Dispenser.java
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.bukkit.block;
|
||||
|
||||
+import com.destroystokyo.paper.loottable.LootableBlockInventory;
|
||||
import org.bukkit.Nameable;
|
||||
import org.bukkit.loot.Lootable;
|
||||
import org.bukkit.projectiles.BlockProjectileSource;
|
||||
@@ -8,7 +9,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
/**
|
||||
* Represents a captured state of a dispenser.
|
||||
*/
|
||||
-public interface Dispenser extends Container, Nameable, Lootable {
|
||||
+public interface Dispenser extends Container, Nameable, LootableBlockInventory { // Paper
|
||||
|
||||
/**
|
||||
* Gets the BlockProjectileSource object for the dispenser.
|
||||
diff --git a/src/main/java/org/bukkit/block/Dropper.java b/src/main/java/org/bukkit/block/Dropper.java
|
||||
index 424392fb5ed4628199b0e73689522aa3c90740cb..c76202321e29ad67597ca3017eb8d9baf6787383 100644
|
||||
--- a/src/main/java/org/bukkit/block/Dropper.java
|
||||
+++ b/src/main/java/org/bukkit/block/Dropper.java
|
||||
@@ -1,11 +1,12 @@
|
||||
package org.bukkit.block;
|
||||
|
||||
+import com.destroystokyo.paper.loottable.LootableBlockInventory;
|
||||
import org.bukkit.loot.Lootable;
|
||||
|
||||
/**
|
||||
* Represents a captured state of a dropper.
|
||||
*/
|
||||
-public interface Dropper extends Container, Lootable {
|
||||
+public interface Dropper extends Container, LootableBlockInventory { // Paper
|
||||
|
||||
/**
|
||||
* Tries to drop a randomly selected item from the dropper's inventory,
|
||||
diff --git a/src/main/java/org/bukkit/block/Hopper.java b/src/main/java/org/bukkit/block/Hopper.java
|
||||
index 58e493099810fb8d4705ecd49b4a5e1e1949b87b..7ade312f180b7e30871d3a3240c76325cc369c26 100644
|
||||
--- a/src/main/java/org/bukkit/block/Hopper.java
|
||||
+++ b/src/main/java/org/bukkit/block/Hopper.java
|
||||
@@ -1,8 +1,9 @@
|
||||
package org.bukkit.block;
|
||||
|
||||
+import com.destroystokyo.paper.loottable.LootableBlockInventory;
|
||||
import org.bukkit.loot.Lootable;
|
||||
|
||||
/**
|
||||
* Represents a captured state of a hopper.
|
||||
*/
|
||||
-public interface Hopper extends Container, Lootable { }
|
||||
+public interface Hopper extends Container, LootableBlockInventory { } // Paper
|
||||
diff --git a/src/main/java/org/bukkit/block/ShulkerBox.java b/src/main/java/org/bukkit/block/ShulkerBox.java
|
||||
index 387b2892886e1ccb2bd928e5111fb9bd41d777ab..5dc5318b0a451937228a8a059dfec1cd9de389a6 100644
|
||||
--- a/src/main/java/org/bukkit/block/ShulkerBox.java
|
||||
+++ b/src/main/java/org/bukkit/block/ShulkerBox.java
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.bukkit.block;
|
||||
|
||||
+import com.destroystokyo.paper.loottable.LootableBlockInventory;
|
||||
import org.bukkit.DyeColor;
|
||||
import org.bukkit.loot.Lootable;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -7,7 +8,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
/**
|
||||
* Represents a captured state of a ShulkerBox.
|
||||
*/
|
||||
-public interface ShulkerBox extends Container, Lootable, Lidded {
|
||||
+public interface ShulkerBox extends Container, LootableBlockInventory, Lidded { // Paper
|
||||
|
||||
/**
|
||||
* Get the {@link DyeColor} corresponding to this ShulkerBox
|
||||
diff --git a/src/main/java/org/bukkit/entity/minecart/HopperMinecart.java b/src/main/java/org/bukkit/entity/minecart/HopperMinecart.java
|
||||
index 937b99f8734d71b2ad33af142afbc251b81d9745..db69687a7ad4b18d17ab1677cae5d8dd4dcd3678 100644
|
||||
--- a/src/main/java/org/bukkit/entity/minecart/HopperMinecart.java
|
||||
+++ b/src/main/java/org/bukkit/entity/minecart/HopperMinecart.java
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.bukkit.entity.minecart;
|
||||
|
||||
+import com.destroystokyo.paper.loottable.LootableEntityInventory;
|
||||
import org.bukkit.entity.Minecart;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.bukkit.loot.Lootable;
|
||||
@@ -7,7 +8,7 @@ import org.bukkit.loot.Lootable;
|
||||
/**
|
||||
* Represents a Minecart with a Hopper inside it
|
||||
*/
|
||||
-public interface HopperMinecart extends Minecart, InventoryHolder, Lootable {
|
||||
+public interface HopperMinecart extends Minecart, InventoryHolder, LootableEntityInventory {
|
||||
|
||||
/**
|
||||
* Checks whether or not this Minecart will pick up
|
||||
diff --git a/src/main/java/org/bukkit/entity/minecart/StorageMinecart.java b/src/main/java/org/bukkit/entity/minecart/StorageMinecart.java
|
||||
index 9ea403e6fd8e960d017660e0aec118abeda2c42b..238d118f7788b13cd86b7e9ea3a0fc38e2e09715 100644
|
||||
--- a/src/main/java/org/bukkit/entity/minecart/StorageMinecart.java
|
||||
+++ b/src/main/java/org/bukkit/entity/minecart/StorageMinecart.java
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.bukkit.entity.minecart;
|
||||
|
||||
+import com.destroystokyo.paper.loottable.LootableEntityInventory;
|
||||
import org.bukkit.entity.Minecart;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.bukkit.loot.Lootable;
|
||||
@@ -9,5 +10,5 @@ import org.bukkit.loot.Lootable;
|
||||
* minecarts} have their own inventory that can be accessed using methods
|
||||
* from the {@link InventoryHolder} interface.
|
||||
*/
|
||||
-public interface StorageMinecart extends Minecart, InventoryHolder, Lootable {
|
||||
+public interface StorageMinecart extends Minecart, InventoryHolder, LootableEntityInventory { // Paper
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/loot/Lootable.java b/src/main/java/org/bukkit/loot/Lootable.java
|
||||
index 24a3d989db3bc67e7afe8459a3d4bb132f448ea7..901db852498e0658c79a57582508dab29bf0a798 100644
|
||||
--- a/src/main/java/org/bukkit/loot/Lootable.java
|
||||
+++ b/src/main/java/org/bukkit/loot/Lootable.java
|
||||
@@ -36,6 +36,34 @@ public interface Lootable {
|
||||
@Nullable
|
||||
LootTable getLootTable();
|
||||
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Set the loot table and seed for a container or entity at the same time.
|
||||
+ *
|
||||
+ * @param table the Loot Table this {@link org.bukkit.block.Container} or {@link org.bukkit.entity.Mob} will have.
|
||||
+ * @param seed the seed to used to generate loot. Default is 0.
|
||||
+ */
|
||||
+ default void setLootTable(@Nullable LootTable table, long seed) {
|
||||
+ setLootTable(table);
|
||||
+ setSeed(seed);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Returns whether or not this object has a Loot Table
|
||||
+ * @return Has a loot table
|
||||
+ */
|
||||
+ default boolean hasLootTable() {
|
||||
+ return getLootTable() != null;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Clears the associated Loot Table to this object
|
||||
+ */
|
||||
+ default void clearLootTable() {
|
||||
+ setLootTable(null);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
/**
|
||||
* Set the seed used when this Loot Table generates loot.
|
||||
*
|
123
patches/unapplied/api/0039-Add-EntityZapEvent.patch
Normal file
123
patches/unapplied/api/0039-Add-EntityZapEvent.patch
Normal file
|
@ -0,0 +1,123 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: AlphaBlend <whizkid3000@hotmail.com>
|
||||
Date: Sun, 16 Oct 2016 23:19:34 -0700
|
||||
Subject: [PATCH] Add EntityZapEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/EntityZapEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/EntityZapEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..3b725a489008d333630af166d2be5fc48168a6b9
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/entity/EntityZapEvent.java
|
||||
@@ -0,0 +1,65 @@
|
||||
+package com.destroystokyo.paper.event.entity;
|
||||
+
|
||||
+import org.apache.commons.lang.Validate;
|
||||
+import org.bukkit.entity.Entity;
|
||||
+import org.bukkit.entity.LightningStrike;
|
||||
+import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.entity.EntityEvent;
|
||||
+import org.bukkit.event.entity.EntityTransformEvent;
|
||||
+
|
||||
+import java.util.Collections;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * Fired when lightning strikes an entity
|
||||
+ */
|
||||
+public class EntityZapEvent extends EntityTransformEvent implements Cancellable {
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+ private boolean cancelled;
|
||||
+ @NotNull private final LightningStrike bolt;
|
||||
+
|
||||
+ public EntityZapEvent(@NotNull final Entity entity, @NotNull final LightningStrike bolt, @NotNull final Entity replacementEntity) {
|
||||
+ super(entity, Collections.singletonList(replacementEntity), TransformReason.LIGHTNING);
|
||||
+ Validate.notNull(bolt);
|
||||
+ Validate.notNull(replacementEntity);
|
||||
+ this.bolt = bolt;
|
||||
+ }
|
||||
+
|
||||
+ public boolean isCancelled() {
|
||||
+ return cancelled;
|
||||
+ }
|
||||
+
|
||||
+ public void setCancelled(boolean cancel) {
|
||||
+ this.cancelled = cancel;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the lightning bolt that is striking the entity.
|
||||
+ * @return The lightning bolt responsible for this event
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public LightningStrike getBolt() {
|
||||
+ return bolt;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the entity that will replace the struck entity.
|
||||
+ * @return The entity that will replace the struck entity
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Entity getReplacementEntity() {
|
||||
+ return getTransformedEntity();
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/event/entity/PigZapEvent.java b/src/main/java/org/bukkit/event/entity/PigZapEvent.java
|
||||
index 0e0ed93b568fd2c0d8f6e359c31dc29cb0fa71c2..d3949edfc736b3d67a627ef378748b374769e183 100644
|
||||
--- a/src/main/java/org/bukkit/event/entity/PigZapEvent.java
|
||||
+++ b/src/main/java/org/bukkit/event/entity/PigZapEvent.java
|
||||
@@ -2,6 +2,7 @@ package org.bukkit.event.entity;
|
||||
|
||||
import java.util.Collections;
|
||||
import org.bukkit.entity.Entity;
|
||||
+import com.destroystokyo.paper.event.entity.EntityZapEvent;
|
||||
import org.bukkit.entity.LightningStrike;
|
||||
import org.bukkit.entity.Pig;
|
||||
import org.bukkit.entity.PigZombie;
|
||||
@@ -12,14 +13,14 @@ import org.jetbrains.annotations.NotNull;
|
||||
/**
|
||||
* Stores data for pigs being zapped
|
||||
*/
|
||||
-public class PigZapEvent extends EntityTransformEvent implements Cancellable {
|
||||
- private static final HandlerList handlers = new HandlerList();
|
||||
+public class PigZapEvent extends EntityZapEvent implements Cancellable {
|
||||
+ //private static final HandlerList handlers = new HandlerList();
|
||||
private boolean canceled;
|
||||
private final PigZombie pigzombie;
|
||||
private final LightningStrike bolt;
|
||||
|
||||
public PigZapEvent(@NotNull final Pig pig, @NotNull final LightningStrike bolt, @NotNull final PigZombie pigzombie) {
|
||||
- super(pig, Collections.singletonList((Entity) pigzombie), TransformReason.LIGHTNING);
|
||||
+ super(pig, bolt, pigzombie);
|
||||
this.bolt = bolt;
|
||||
this.pigzombie = pigzombie;
|
||||
}
|
||||
@@ -63,6 +64,8 @@ public class PigZapEvent extends EntityTransformEvent implements Cancellable {
|
||||
return pigzombie;
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ /*
|
||||
@NotNull
|
||||
@Override
|
||||
public HandlerList getHandlers() {
|
||||
@@ -73,4 +76,6 @@ public class PigZapEvent extends EntityTransformEvent implements Cancellable {
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
+ */
|
||||
+ // Paper end
|
||||
}
|
46
patches/unapplied/api/0040-Misc-Utils.patch
Normal file
46
patches/unapplied/api/0040-Misc-Utils.patch
Normal file
|
@ -0,0 +1,46 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: vemacs <d@nkmem.es>
|
||||
Date: Wed, 23 Nov 2016 12:53:43 -0500
|
||||
Subject: [PATCH] Misc Utils
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/utils/CachedSizeConcurrentLinkedQueue.java b/src/main/java/com/destroystokyo/paper/utils/CachedSizeConcurrentLinkedQueue.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..5bb677ce585b856b3d3e589e29786a29619c56a7
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/utils/CachedSizeConcurrentLinkedQueue.java
|
||||
@@ -0,0 +1,34 @@
|
||||
+package com.destroystokyo.paper.utils;
|
||||
+
|
||||
+import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
+import java.util.concurrent.atomic.LongAdder;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
+
|
||||
+public class CachedSizeConcurrentLinkedQueue<E> extends ConcurrentLinkedQueue<E> {
|
||||
+ private final LongAdder cachedSize = new LongAdder();
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean add(@NotNull E e) {
|
||||
+ boolean result = super.add(e);
|
||||
+ if (result) {
|
||||
+ cachedSize.increment();
|
||||
+ }
|
||||
+ return result;
|
||||
+ }
|
||||
+
|
||||
+ @Nullable
|
||||
+ @Override
|
||||
+ public E poll() {
|
||||
+ E result = super.poll();
|
||||
+ if (result != null) {
|
||||
+ cachedSize.decrement();
|
||||
+ }
|
||||
+ return result;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int size() {
|
||||
+ return cachedSize.intValue();
|
||||
+ }
|
||||
+}
|
|
@ -0,0 +1,108 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: willies952002 <admin@domnian.com>
|
||||
Date: Mon, 28 Nov 2016 10:16:39 -0500
|
||||
Subject: [PATCH] Allow Reloading of Command Aliases
|
||||
|
||||
Reload the aliases stored in commands.yml
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
|
||||
index 308d9cd655c37e8a00bb053ecd2ba2450555158f..356a270e9f831e21dc7fd947c2bec72e0840145a 100644
|
||||
--- a/src/main/java/org/bukkit/Bukkit.java
|
||||
+++ b/src/main/java/org/bukkit/Bukkit.java
|
||||
@@ -1897,6 +1897,15 @@ public final class Bukkit {
|
||||
public static void reloadPermissions() {
|
||||
server.reloadPermissions();
|
||||
}
|
||||
+
|
||||
+ /**
|
||||
+ * Reload the Command Aliases in commands.yml
|
||||
+ *
|
||||
+ * @return Whether the reload was successful
|
||||
+ */
|
||||
+ public static boolean reloadCommandAliases() {
|
||||
+ return server.reloadCommandAliases();
|
||||
+ }
|
||||
// Paper end
|
||||
|
||||
@NotNull
|
||||
diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
|
||||
index 51d7ec1b9ede6a1fe11d1bddc7a58213add72cbc..c0bd764744b101856ef4fa068b5218688b156ecf 100644
|
||||
--- a/src/main/java/org/bukkit/Server.java
|
||||
+++ b/src/main/java/org/bukkit/Server.java
|
||||
@@ -1672,4 +1672,6 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
|
||||
// Spigot end
|
||||
|
||||
void reloadPermissions(); // Paper
|
||||
+
|
||||
+ boolean reloadCommandAliases(); // Paper
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/command/CommandMap.java b/src/main/java/org/bukkit/command/CommandMap.java
|
||||
index bd2c7a6964722412148fae39e1b4951fc0002b9b..864c263bbd4dd6dd7c37a74b39b1a40a884d0731 100644
|
||||
--- a/src/main/java/org/bukkit/command/CommandMap.java
|
||||
+++ b/src/main/java/org/bukkit/command/CommandMap.java
|
||||
@@ -128,4 +128,14 @@ public interface CommandMap {
|
||||
*/
|
||||
@Nullable
|
||||
public List<String> tabComplete(@NotNull CommandSender sender, @NotNull String cmdLine, @Nullable Location location) throws IllegalArgumentException;
|
||||
+
|
||||
+ // Paper start - Expose Known Commands
|
||||
+ /**
|
||||
+ * Return a Map of known commands
|
||||
+ *
|
||||
+ * @return known commands
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public java.util.Map<String, Command> getKnownCommands();
|
||||
+ // Paper end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/command/SimpleCommandMap.java b/src/main/java/org/bukkit/command/SimpleCommandMap.java
|
||||
index adfc7aae2c0f49bbcdd358e83b04a0cf078a7d52..460fda05a62b12db2edcfb7ea8b2a5dd8e4b110d 100644
|
||||
--- a/src/main/java/org/bukkit/command/SimpleCommandMap.java
|
||||
+++ b/src/main/java/org/bukkit/command/SimpleCommandMap.java
|
||||
@@ -297,4 +297,11 @@ public class SimpleCommandMap implements CommandMap {
|
||||
}
|
||||
}
|
||||
}
|
||||
+
|
||||
+ // Paper start - Expose Known Commands
|
||||
+ @NotNull
|
||||
+ public Map<String, Command> getKnownCommands() {
|
||||
+ return knownCommands;
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/command/defaults/ReloadCommand.java b/src/main/java/org/bukkit/command/defaults/ReloadCommand.java
|
||||
index c62da4131b17e66892678e8b618fb9ba3de93b56..0c7ba0718de2b93d013968ca0fec34ffd423990f 100644
|
||||
--- a/src/main/java/org/bukkit/command/defaults/ReloadCommand.java
|
||||
+++ b/src/main/java/org/bukkit/command/defaults/ReloadCommand.java
|
||||
@@ -13,7 +13,7 @@ public class ReloadCommand extends BukkitCommand {
|
||||
public ReloadCommand(@NotNull String name) {
|
||||
super(name);
|
||||
this.description = "Reloads the server configuration and plugins";
|
||||
- this.usageMessage = "/reload [permissions]"; // Paper
|
||||
+ this.usageMessage = "/reload [permissions|commands|confirm]"; // Paper
|
||||
this.setPermission("bukkit.command.reload");
|
||||
this.setAliases(Arrays.asList("rl"));
|
||||
}
|
||||
@@ -29,6 +29,13 @@ public class ReloadCommand extends BukkitCommand {
|
||||
Bukkit.getServer().reloadPermissions();
|
||||
Command.broadcastCommandMessage(sender, ChatColor.GREEN + "Permissions successfully reloaded.");
|
||||
return true;
|
||||
+ } else if ("commands".equalsIgnoreCase(args[0])) {
|
||||
+ if (Bukkit.getServer().reloadCommandAliases()) {
|
||||
+ Command.broadcastCommandMessage(sender, ChatColor.GREEN + "Command aliases successfully reloaded.");
|
||||
+ } else {
|
||||
+ Command.broadcastCommandMessage(sender, ChatColor.RED + "An error occurred while trying to reload command aliases.");
|
||||
+ }
|
||||
+ return true;
|
||||
} else if ("confirm".equalsIgnoreCase(args[0])) {
|
||||
confirmed = true;
|
||||
} else {
|
||||
@@ -53,6 +60,6 @@ public class ReloadCommand extends BukkitCommand {
|
||||
@NotNull
|
||||
@Override
|
||||
public List<String> tabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException {
|
||||
- return java.util.Collections.singletonList("permissions"); // Paper
|
||||
+ return com.google.common.collect.Lists.newArrayList("permissions", "commands"); // Paper
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: AlphaBlend <whizkid3000@hotmail.com>
|
||||
Date: Thu, 8 Sep 2016 08:47:08 -0700
|
||||
Subject: [PATCH] Add source to PlayerExpChangeEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/event/player/PlayerExpChangeEvent.java b/src/main/java/org/bukkit/event/player/PlayerExpChangeEvent.java
|
||||
index c99c9281e98e4b510dddb711b8785bcd56b3b92f..7c340f539c31a431d7d9204a8135e0bfc31863a8 100644
|
||||
--- a/src/main/java/org/bukkit/event/player/PlayerExpChangeEvent.java
|
||||
+++ b/src/main/java/org/bukkit/event/player/PlayerExpChangeEvent.java
|
||||
@@ -1,21 +1,43 @@
|
||||
package org.bukkit.event.player;
|
||||
|
||||
+import org.bukkit.entity.Entity; // Paper
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
+import org.jetbrains.annotations.Nullable; // Paper
|
||||
+
|
||||
/**
|
||||
* Called when a players experience changes naturally
|
||||
*/
|
||||
public class PlayerExpChangeEvent extends PlayerEvent {
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
+ // Paper start
|
||||
+ @Nullable
|
||||
+ private final Entity source;
|
||||
private int exp;
|
||||
|
||||
public PlayerExpChangeEvent(@NotNull final Player player, final int expAmount) {
|
||||
+ this(player, null, expAmount);
|
||||
+ }
|
||||
+
|
||||
+ public PlayerExpChangeEvent(@NotNull final Player player, @Nullable final Entity sourceEntity, final int expAmount) {
|
||||
super(player);
|
||||
+ source = sourceEntity;
|
||||
exp = expAmount;
|
||||
}
|
||||
|
||||
+ /**
|
||||
+ * Get the source that provided the experience.
|
||||
+ *
|
||||
+ * @return The source of the experience
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public Entity getSource() {
|
||||
+ return source;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
/**
|
||||
* Get the amount of experience the player will receive
|
||||
*
|
79
patches/unapplied/api/0043-Add-ProjectileCollideEvent.patch
Normal file
79
patches/unapplied/api/0043-Add-ProjectileCollideEvent.patch
Normal file
|
@ -0,0 +1,79 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Techcable <Techcable@outlook.com>
|
||||
Date: Fri, 16 Dec 2016 21:25:39 -0600
|
||||
Subject: [PATCH] Add ProjectileCollideEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/ProjectileCollideEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/ProjectileCollideEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..453663893021768ae21d4980ce17ffba55d9e129
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/entity/ProjectileCollideEvent.java
|
||||
@@ -0,0 +1,67 @@
|
||||
+package com.destroystokyo.paper.event.entity;
|
||||
+
|
||||
+import org.bukkit.entity.Entity;
|
||||
+import org.bukkit.entity.Projectile;
|
||||
+import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.entity.EntityEvent;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * Called when an projectile collides with an entity
|
||||
+ * <p>
|
||||
+ * This event is called <b>before</b> {@link org.bukkit.event.entity.EntityDamageByEntityEvent}, and cancelling it will allow the projectile to continue flying
|
||||
+ */
|
||||
+public class ProjectileCollideEvent extends EntityEvent implements Cancellable {
|
||||
+ @NotNull private final Entity collidedWith;
|
||||
+
|
||||
+ /**
|
||||
+ * Get the entity the projectile collided with
|
||||
+ *
|
||||
+ * @return the entity collided with
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Entity getCollidedWith() {
|
||||
+ return collidedWith;
|
||||
+ }
|
||||
+
|
||||
+ public ProjectileCollideEvent(@NotNull Projectile what, @NotNull Entity collidedWith) {
|
||||
+ super(what);
|
||||
+ this.collidedWith = collidedWith;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Get the projectile that collided
|
||||
+ *
|
||||
+ * @return the projectile that collided
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Projectile getEntity() {
|
||||
+ return (Projectile) super.getEntity();
|
||||
+ }
|
||||
+
|
||||
+ private static final HandlerList handlerList = new HandlerList();
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlerList;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlerList;
|
||||
+ }
|
||||
+
|
||||
+ private boolean cancelled = false;
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isCancelled() {
|
||||
+ return cancelled;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setCancelled(boolean cancel) {
|
||||
+ this.cancelled = cancel;
|
||||
+ }
|
||||
+}
|
|
@ -0,0 +1,86 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 20 Dec 2016 15:55:55 -0500
|
||||
Subject: [PATCH] Add String based Action Bar API
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java
|
||||
index ab25e699ea936e2dae7cce41f850b55a381a6dcb..82e4b89bf280ad3f99d94c9aaa6075449737932a 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Player.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Player.java
|
||||
@@ -3,6 +3,7 @@ package org.bukkit.entity;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.UUID;
|
||||
import com.destroystokyo.paper.Title; // Paper
|
||||
+import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.DyeColor;
|
||||
import org.bukkit.Effect;
|
||||
import org.bukkit.GameMode;
|
||||
@@ -709,6 +710,39 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
|
||||
public void sendMap(@NotNull MapView map);
|
||||
|
||||
// Paper start
|
||||
+
|
||||
+ /**
|
||||
+ * Sends an Action Bar message to the client.
|
||||
+ *
|
||||
+ * Use Section symbols for legacy color codes to send formatting.
|
||||
+ *
|
||||
+ * @param message The message to send
|
||||
+ * @deprecated use {@link #sendActionBar(Component)}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ public void sendActionBar(@NotNull String message);
|
||||
+
|
||||
+ /**
|
||||
+ * Sends an Action Bar message to the client.
|
||||
+ *
|
||||
+ * Use supplied alternative character to the section symbol to represent legacy color codes.
|
||||
+ *
|
||||
+ * @param alternateChar Alternate symbol such as '&'
|
||||
+ * @param message The message to send
|
||||
+ * @deprecated use {@link #sendActionBar(Component)}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ public void sendActionBar(char alternateChar, @NotNull String message);
|
||||
+
|
||||
+ /**
|
||||
+ * Sends an Action Bar message to the client.
|
||||
+ *
|
||||
+ * @param message The components to send
|
||||
+ * @deprecated use {@link #sendActionBar(Component)}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ public void sendActionBar(@NotNull net.md_5.bungee.api.chat.BaseComponent... message);
|
||||
+
|
||||
/**
|
||||
* Sends the component to the player
|
||||
*
|
||||
@@ -736,9 +770,11 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
|
||||
/**
|
||||
* Sends an array of components as a single message to the specified screen position of this player
|
||||
*
|
||||
+ * @deprecated This is unlikely the API you want to use. See {@link #sendActionBar(String)} for a more proper Action Bar API. This deprecated API may send unsafe items to the client.
|
||||
* @param position the screen position
|
||||
* @param components the components to send
|
||||
*/
|
||||
+ @Deprecated
|
||||
public default void sendMessage(net.md_5.bungee.api.ChatMessageType position, net.md_5.bungee.api.chat.BaseComponent... components) {
|
||||
spigot().sendMessage(position, components);
|
||||
}
|
||||
@@ -1928,6 +1964,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
|
||||
/**
|
||||
* Sends the component to the specified screen position of this player
|
||||
*
|
||||
+ * @deprecated This is unlikely the API you want to use. See {@link #sendActionBar(String)} for a more proper Action Bar API. This deprecated API may send unsafe items to the client.
|
||||
* @param position the screen position
|
||||
* @param component the components to send
|
||||
* @deprecated use {@code sendMessage} methods that accept {@link net.kyori.adventure.text.Component}
|
||||
@@ -1940,6 +1977,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
|
||||
/**
|
||||
* Sends an array of components as a single message to the specified screen position of this player
|
||||
*
|
||||
+ * @deprecated This is unlikely the API you want to use. See {@link #sendActionBar(String)} for a more proper Action Bar API. This deprecated API may send unsafe items to the client.
|
||||
* @param position the screen position
|
||||
* @param components the components to send
|
||||
* @deprecated use {@code sendMessage} methods that accept {@link net.kyori.adventure.text.Component}
|
|
@ -0,0 +1,32 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: kashike <kashike@vq.lc>
|
||||
Date: Wed, 21 Dec 2016 11:47:25 -0600
|
||||
Subject: [PATCH] Add API methods to control if armour stands can move
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/entity/ArmorStand.java b/src/main/java/org/bukkit/entity/ArmorStand.java
|
||||
index dc604d6ab9dcf67fa0791539d18c2f890a814ed8..91fc11dda99de506be83d40df8929bf7cd8e8d85 100644
|
||||
--- a/src/main/java/org/bukkit/entity/ArmorStand.java
|
||||
+++ b/src/main/java/org/bukkit/entity/ArmorStand.java
|
||||
@@ -344,4 +344,21 @@ public interface ArmorStand extends LivingEntity {
|
||||
*/
|
||||
ADDING;
|
||||
}
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Tests if this armor stand can move.
|
||||
+ *
|
||||
+ * <p>The default value is {@code true}.</p>
|
||||
+ *
|
||||
+ * @return {@code true} if this armour stand can move, {@code false} otherwise
|
||||
+ */
|
||||
+ boolean canMove();
|
||||
+
|
||||
+ /**
|
||||
+ * Sets if this armor stand can move.
|
||||
+ *
|
||||
+ * @param move {@code true} if this armour stand can move, {@code false} otherwise
|
||||
+ */
|
||||
+ void setCanMove(boolean move);
|
||||
+ // Paper end
|
||||
}
|
89
patches/unapplied/api/0046-IllegalPacketEvent.patch
Normal file
89
patches/unapplied/api/0046-IllegalPacketEvent.patch
Normal file
|
@ -0,0 +1,89 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sun, 4 Dec 2016 01:19:14 -0500
|
||||
Subject: [PATCH] IllegalPacketEvent
|
||||
|
||||
Fire an event when an illegal packet is received to let plugins handle it
|
||||
|
||||
Lets plugins change the kick message and if it should kick or not.
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/player/IllegalPacketEvent.java b/src/main/java/com/destroystokyo/paper/event/player/IllegalPacketEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..8d8e9b16f2a6707d2af7567c7682dfc5db51a737
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/player/IllegalPacketEvent.java
|
||||
@@ -0,0 +1,74 @@
|
||||
+package com.destroystokyo.paper.event.player;
|
||||
+
|
||||
+import org.bukkit.Bukkit;
|
||||
+import org.bukkit.entity.Player;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.player.PlayerEvent;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
+
|
||||
+/**
|
||||
+ * @deprecated Not used
|
||||
+ */
|
||||
+@Deprecated
|
||||
+public class IllegalPacketEvent extends PlayerEvent {
|
||||
+ @Nullable private final String type;
|
||||
+ @Nullable private final String ex;
|
||||
+ @Nullable private String kickMessage;
|
||||
+ private boolean shouldKick = true;
|
||||
+
|
||||
+ public IllegalPacketEvent(@NotNull Player player, @Nullable String type, @Nullable String kickMessage, @NotNull Exception e) {
|
||||
+ super(player);
|
||||
+ this.type = type;
|
||||
+ this.kickMessage = kickMessage;
|
||||
+ this.ex = e.getMessage();
|
||||
+ }
|
||||
+
|
||||
+ public boolean isShouldKick() {
|
||||
+ return shouldKick;
|
||||
+ }
|
||||
+
|
||||
+ public void setShouldKick(boolean shouldKick) {
|
||||
+ this.shouldKick = shouldKick;
|
||||
+ }
|
||||
+
|
||||
+ @Nullable
|
||||
+ public String getKickMessage() {
|
||||
+ return kickMessage;
|
||||
+ }
|
||||
+
|
||||
+ public void setKickMessage(@Nullable String kickMessage) {
|
||||
+ this.kickMessage = kickMessage;
|
||||
+ }
|
||||
+
|
||||
+ @Nullable
|
||||
+ public String getType() {
|
||||
+ return type;
|
||||
+ }
|
||||
+
|
||||
+ @Nullable
|
||||
+ public String getExceptionMessage() {
|
||||
+ return ex;
|
||||
+ }
|
||||
+
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+
|
||||
+ @NotNull
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ public static void process(@NotNull Player player, @Nullable String type, @Nullable String kickMessage, @NotNull Exception exception) {
|
||||
+ IllegalPacketEvent event = new IllegalPacketEvent(player, type, kickMessage, exception);
|
||||
+ event.callEvent();
|
||||
+ if (event.shouldKick) {
|
||||
+ player.kickPlayer(kickMessage);
|
||||
+ }
|
||||
+ Bukkit.getLogger().severe(player.getName() + "/" + type + ": " + exception.getMessage());
|
||||
+ }
|
||||
+}
|
28
patches/unapplied/api/0047-Fireworks-API-s.patch
Normal file
28
patches/unapplied/api/0047-Fireworks-API-s.patch
Normal file
|
@ -0,0 +1,28 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Wed, 28 Dec 2016 01:18:55 -0500
|
||||
Subject: [PATCH] Fireworks API's
|
||||
|
||||
Get the Entity being boosted
|
||||
Get the firework launcher
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/entity/Firework.java b/src/main/java/org/bukkit/entity/Firework.java
|
||||
index 05e86cb9d826cdf14490fa649348d46c51adbfdb..d616d5941b3c7b85e350e845901da798601b9a3c 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Firework.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Firework.java
|
||||
@@ -43,4 +43,15 @@ public interface Firework extends Projectile {
|
||||
* @param shotAtAngle the new shotAtAngle
|
||||
*/
|
||||
void setShotAtAngle(boolean shotAtAngle);
|
||||
+
|
||||
+ // Paper start
|
||||
+ @org.jetbrains.annotations.Nullable
|
||||
+ public java.util.UUID getSpawningEntity();
|
||||
+ /**
|
||||
+ * If this firework is boosting an entity, return it
|
||||
+ * @return The entity being boosted
|
||||
+ */
|
||||
+ @org.jetbrains.annotations.Nullable
|
||||
+ public LivingEntity getBoostedEntity();
|
||||
+ // Paper end
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sat, 31 Dec 2016 20:29:33 -0500
|
||||
Subject: [PATCH] PlayerTeleportEndGatewayEvent
|
||||
|
||||
Allows you to access the Gateway being used in a teleport event
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/player/PlayerTeleportEndGatewayEvent.java b/src/main/java/com/destroystokyo/paper/event/player/PlayerTeleportEndGatewayEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..b64ab6eecd8bc4ca9c109b9d83c82861d6260793
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/player/PlayerTeleportEndGatewayEvent.java
|
||||
@@ -0,0 +1,29 @@
|
||||
+package com.destroystokyo.paper.event.player;
|
||||
+
|
||||
+import org.bukkit.Location;
|
||||
+import org.bukkit.block.EndGateway;
|
||||
+import org.bukkit.entity.Player;
|
||||
+import org.bukkit.event.player.PlayerTeleportEvent;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * Fired when a teleport is triggered for an End Gateway
|
||||
+ */
|
||||
+public class PlayerTeleportEndGatewayEvent extends PlayerTeleportEvent {
|
||||
+ @NotNull private final EndGateway gateway;
|
||||
+
|
||||
+ public PlayerTeleportEndGatewayEvent(@NotNull Player player, @NotNull Location from, @NotNull Location to, @NotNull EndGateway gateway) {
|
||||
+ super(player, from, to, PlayerTeleportEvent.TeleportCause.END_GATEWAY);
|
||||
+ this.gateway = gateway;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * The gateway triggering the teleport
|
||||
+ *
|
||||
+ * @return EndGateway used
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public EndGateway getGateway() {
|
||||
+ return gateway;
|
||||
+ }
|
||||
+}
|
|
@ -0,0 +1,46 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sat, 7 Jan 2017 15:23:03 -0500
|
||||
Subject: [PATCH] Provide E/TE/Chunk count stat methods
|
||||
|
||||
Provides counts without the ineffeciency of using .getEntities().size()
|
||||
which creates copy of the collections.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java
|
||||
index 49be21d2676a93c384f37c09fe84eba2ffc11781..98c74a6b4f126f2a3e65f95e55561f652c10c4b9 100644
|
||||
--- a/src/main/java/org/bukkit/World.java
|
||||
+++ b/src/main/java/org/bukkit/World.java
|
||||
@@ -40,6 +40,33 @@ import org.jetbrains.annotations.Nullable;
|
||||
*/
|
||||
public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient, Metadatable, net.kyori.adventure.audience.ForwardingAudience { // Paper
|
||||
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * @return The amount of Entities in this world
|
||||
+ */
|
||||
+ int getEntityCount();
|
||||
+
|
||||
+ /**
|
||||
+ * @return The amount of Tile Entities in this world
|
||||
+ */
|
||||
+ int getTileEntityCount();
|
||||
+
|
||||
+ /**
|
||||
+ * @return The amount of Tickable Tile Entities in this world
|
||||
+ */
|
||||
+ int getTickableTileEntityCount();
|
||||
+
|
||||
+ /**
|
||||
+ * @return The amount of Chunks in this world
|
||||
+ */
|
||||
+ int getChunkCount();
|
||||
+
|
||||
+ /**
|
||||
+ * @return The amount of Players in this world
|
||||
+ */
|
||||
+ int getPlayerCount();
|
||||
+ // Paper end
|
||||
+
|
||||
/**
|
||||
* Gets the {@link Block} at the given coordinates
|
||||
*
|
|
@ -0,0 +1,122 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 19 Dec 2017 16:28:32 -0500
|
||||
Subject: [PATCH] ExperienceOrbs API for Reason/Source/Triggering player
|
||||
|
||||
Adds lots of information about why this orb exists.
|
||||
|
||||
Replaces isFromBottle() with logic that persists entity reloads too.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/entity/ExperienceOrb.java b/src/main/java/org/bukkit/entity/ExperienceOrb.java
|
||||
index c286edfd827e185a76e44c44faace19a80325d7a..dec70bbfaf73a9d525b2c45682b804c684e1645b 100644
|
||||
--- a/src/main/java/org/bukkit/entity/ExperienceOrb.java
|
||||
+++ b/src/main/java/org/bukkit/entity/ExperienceOrb.java
|
||||
@@ -1,5 +1,8 @@
|
||||
package org.bukkit.entity;
|
||||
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable; // Paper
|
||||
+
|
||||
/**
|
||||
* Represents an Experience Orb.
|
||||
*/
|
||||
@@ -18,4 +21,99 @@ public interface ExperienceOrb extends Entity {
|
||||
* @param value Amount of experience
|
||||
*/
|
||||
public void setExperience(int value);
|
||||
+
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Check if this orb was spawned from a {@link ThrownExpBottle}
|
||||
+ *
|
||||
+ * @return if orb was spawned from a bottle
|
||||
+ * @deprecated Use getSpawnReason() == EXP_BOTTLE
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ default boolean isFromBottle() {
|
||||
+ return getSpawnReason() == SpawnReason.EXP_BOTTLE;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Reasons for why this Experience Orb was spawned
|
||||
+ */
|
||||
+ enum SpawnReason {
|
||||
+ /**
|
||||
+ * Spawned by a player dying
|
||||
+ */
|
||||
+ PLAYER_DEATH,
|
||||
+ /**
|
||||
+ * Spawned by an entity dying after being damaged by a player
|
||||
+ */
|
||||
+ ENTITY_DEATH,
|
||||
+ /**
|
||||
+ * Spawned by player using a furnace
|
||||
+ */
|
||||
+ FURNACE,
|
||||
+ /**
|
||||
+ * Spawned by player breeding animals
|
||||
+ */
|
||||
+ BREED,
|
||||
+ /**
|
||||
+ * Spawned by player trading with a villager
|
||||
+ */
|
||||
+ VILLAGER_TRADE,
|
||||
+ /**
|
||||
+ * Spawned by player fishing
|
||||
+ */
|
||||
+ FISHING,
|
||||
+ /**
|
||||
+ * Spawned by player breaking a block that gives experience points such as Diamond Ore
|
||||
+ */
|
||||
+ BLOCK_BREAK,
|
||||
+ /**
|
||||
+ * Spawned by Bukkit API
|
||||
+ */
|
||||
+ CUSTOM,
|
||||
+ /**
|
||||
+ * Spawned by a player throwing an experience points bottle
|
||||
+ */
|
||||
+ EXP_BOTTLE,
|
||||
+ /**
|
||||
+ * Spawned by a player using a grindstone
|
||||
+ */
|
||||
+ GRINDSTONE,
|
||||
+ /**
|
||||
+ * We do not know why it was spawned
|
||||
+ */
|
||||
+ UNKNOWN
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * If this experience orb was triggered to be spawned by
|
||||
+ * an entity such as a player, due to events such as killing entity,
|
||||
+ * breaking blocks, smelting in a furnace, etc, this will return the UUID
|
||||
+ * of the entity that triggered this orb to drop.
|
||||
+ *
|
||||
+ * In the case of an entity being killed, this will be the killers UUID.
|
||||
+ *
|
||||
+ * @return UUID of the player that triggered this orb to drop, or null if unknown/no triggering entity
|
||||
+ */
|
||||
+ @Nullable java.util.UUID getTriggerEntityId();
|
||||
+
|
||||
+ /**
|
||||
+ * If this experience orb was spawned in relation to another
|
||||
+ * entity, such as a player or other living entity death, or breeding,
|
||||
+ * return the source entity UUID.
|
||||
+ *
|
||||
+ * In the case of breeding, this will be the new baby entities UUID.
|
||||
+ * In the case of an entity being killed, this will be the dead entities UUID.
|
||||
+ *
|
||||
+ * @return The UUID of the entity that sourced this experience orb
|
||||
+ */
|
||||
+ @Nullable java.util.UUID getSourceEntityId();
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the reason that this experience orb was spawned. For any case that we
|
||||
+ * do not know, such as orbs spawned before this API was added, UNKNOWN is returned.
|
||||
+ * @return The reason for this orb being spawned.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ SpawnReason getSpawnReason();
|
||||
+ // Paper end
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <zach.brown@destroystokyo.com>
|
||||
Date: Sat, 21 Jan 2017 17:03:10 -0600
|
||||
Subject: [PATCH] Expose WorldBorder#isInBounds(Location) check
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/WorldBorder.java b/src/main/java/org/bukkit/WorldBorder.java
|
||||
index 7e8f5649ce0eb0090899514b1e228601eb644613..afb7b136b461202026290624836446cff9f9e45d 100644
|
||||
--- a/src/main/java/org/bukkit/WorldBorder.java
|
||||
+++ b/src/main/java/org/bukkit/WorldBorder.java
|
||||
@@ -117,4 +117,18 @@ public interface WorldBorder {
|
||||
* @return if this location is inside the border or not
|
||||
*/
|
||||
public boolean isInside(@NotNull Location location);
|
||||
+
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Checks if the location is within the boundaries of this border.
|
||||
+ *
|
||||
+ * @param location specific location to check
|
||||
+ * @return true if the location is within the bounds of this border, false otherwise.
|
||||
+ * @deprecated use {@link #isInside(Location)} for an upstream compatible replacement
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ public default boolean isInBounds(@NotNull Location location) {
|
||||
+ return this.isInside(location);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: kashike <kashike@vq.lc>
|
||||
Date: Fri, 9 Jun 2017 07:24:24 -0700
|
||||
Subject: [PATCH] Add configuration option to prevent player names from being
|
||||
suggested
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
|
||||
index 356a270e9f831e21dc7fd947c2bec72e0840145a..282bd71697aff52d43bce0a3543a3ec50a5b7b1b 100644
|
||||
--- a/src/main/java/org/bukkit/Bukkit.java
|
||||
+++ b/src/main/java/org/bukkit/Bukkit.java
|
||||
@@ -1906,6 +1906,16 @@ public final class Bukkit {
|
||||
public static boolean reloadCommandAliases() {
|
||||
return server.reloadCommandAliases();
|
||||
}
|
||||
+
|
||||
+ /**
|
||||
+ * Checks if player names should be suggested when a command returns {@code null} as
|
||||
+ * their tab completion result.
|
||||
+ *
|
||||
+ * @return true if player names should be suggested
|
||||
+ */
|
||||
+ public static boolean suggestPlayerNamesWhenNullTabCompletions() {
|
||||
+ return server.suggestPlayerNamesWhenNullTabCompletions();
|
||||
+ }
|
||||
// Paper end
|
||||
|
||||
@NotNull
|
||||
diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
|
||||
index c0bd764744b101856ef4fa068b5218688b156ecf..2de18d69ad80fe872b36a4975b354cb144b3a302 100644
|
||||
--- a/src/main/java/org/bukkit/Server.java
|
||||
+++ b/src/main/java/org/bukkit/Server.java
|
||||
@@ -1674,4 +1674,14 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
|
||||
void reloadPermissions(); // Paper
|
||||
|
||||
boolean reloadCommandAliases(); // Paper
|
||||
+
|
||||
+ // Paper start - allow preventing player name suggestions by default
|
||||
+ /**
|
||||
+ * Checks if player names should be suggested when a command returns {@code null} as
|
||||
+ * their tab completion result.
|
||||
+ *
|
||||
+ * @return true if player names should be suggested
|
||||
+ */
|
||||
+ boolean suggestPlayerNamesWhenNullTabCompletions();
|
||||
+ // Paper end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/command/Command.java b/src/main/java/org/bukkit/command/Command.java
|
||||
index c4dcafac892169a7bfcc065701fffb43c6cfdf44..b1152f4dede61383232cc6713d448840612eac13 100644
|
||||
--- a/src/main/java/org/bukkit/command/Command.java
|
||||
+++ b/src/main/java/org/bukkit/command/Command.java
|
||||
@@ -99,7 +99,7 @@ public abstract class Command {
|
||||
Validate.notNull(args, "Arguments cannot be null");
|
||||
Validate.notNull(alias, "Alias cannot be null");
|
||||
|
||||
- if (args.length == 0) {
|
||||
+ if (args.length == 0 || !sender.getServer().suggestPlayerNamesWhenNullTabCompletions()) { // Paper - allow preventing player name suggestions by default) {
|
||||
return ImmutableList.of();
|
||||
}
|
||||
|
116
patches/unapplied/api/0053-Fix-upstream-javadocs.patch
Normal file
116
patches/unapplied/api/0053-Fix-upstream-javadocs.patch
Normal file
|
@ -0,0 +1,116 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <zach.brown@destroystokyo.com>
|
||||
Date: Sat, 10 Jun 2017 16:59:40 -0500
|
||||
Subject: [PATCH] Fix upstream javadocs
|
||||
|
||||
Upstream still refuses to use Java 8 with the API so they are likely unaware these are even issues.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
|
||||
index 282bd71697aff52d43bce0a3543a3ec50a5b7b1b..fa3cd5395ec29d7c51c792720acbb2394f238c45 100644
|
||||
--- a/src/main/java/org/bukkit/Bukkit.java
|
||||
+++ b/src/main/java/org/bukkit/Bukkit.java
|
||||
@@ -1163,6 +1163,8 @@ public final class Bukkit {
|
||||
|
||||
/**
|
||||
* Gets every player that has ever played on this server.
|
||||
+ * <p>
|
||||
+ * <b>This method can be expensive as it loads all the player data files from the disk.</b>
|
||||
*
|
||||
* @return an array containing all previous players
|
||||
*/
|
||||
diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
|
||||
index 2de18d69ad80fe872b36a4975b354cb144b3a302..d1e5e679e0a7482a87a9a049ed0ce5c1b9891c90 100644
|
||||
--- a/src/main/java/org/bukkit/Server.java
|
||||
+++ b/src/main/java/org/bukkit/Server.java
|
||||
@@ -980,6 +980,8 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
|
||||
|
||||
/**
|
||||
* Gets every player that has ever played on this server.
|
||||
+ * <p>
|
||||
+ * <b>This method can be expensive as it loads all the player data files from the disk.</b>
|
||||
*
|
||||
* @return an array containing all previous players
|
||||
*/
|
||||
diff --git a/src/main/java/org/bukkit/entity/ArmorStand.java b/src/main/java/org/bukkit/entity/ArmorStand.java
|
||||
index 91fc11dda99de506be83d40df8929bf7cd8e8d85..7dc631ebd009f5f5c3ac1699c3f3515c47609c05 100644
|
||||
--- a/src/main/java/org/bukkit/entity/ArmorStand.java
|
||||
+++ b/src/main/java/org/bukkit/entity/ArmorStand.java
|
||||
@@ -360,5 +360,8 @@ public interface ArmorStand extends LivingEntity {
|
||||
* @param move {@code true} if this armour stand can move, {@code false} otherwise
|
||||
*/
|
||||
void setCanMove(boolean move);
|
||||
+
|
||||
+ @Override
|
||||
+ org.bukkit.inventory.@NotNull EntityEquipment getEquipment();
|
||||
// Paper end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/entity/HumanEntity.java b/src/main/java/org/bukkit/entity/HumanEntity.java
|
||||
index db4ba67618d29f72d695c66c27d771795565a1d0..0ab94ddd3b88eee8040233a89823bd2fadc78d55 100644
|
||||
--- a/src/main/java/org/bukkit/entity/HumanEntity.java
|
||||
+++ b/src/main/java/org/bukkit/entity/HumanEntity.java
|
||||
@@ -21,6 +21,11 @@ import org.jetbrains.annotations.Nullable;
|
||||
*/
|
||||
public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder {
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ org.bukkit.inventory.@NotNull EntityEquipment getEquipment();
|
||||
+ // Paper end
|
||||
+
|
||||
/**
|
||||
* Returns the name of this player
|
||||
*
|
||||
diff --git a/src/main/java/org/bukkit/entity/Mob.java b/src/main/java/org/bukkit/entity/Mob.java
|
||||
index be9334a8b5fba9181ad63c211697e798be63da25..0514a141cb93a650be38c63d4336d46e4304f4b6 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Mob.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Mob.java
|
||||
@@ -8,6 +8,10 @@ import org.jetbrains.annotations.Nullable;
|
||||
*/
|
||||
public interface Mob extends LivingEntity, Lootable {
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ org.bukkit.inventory.@org.jetbrains.annotations.NotNull EntityEquipment getEquipment();
|
||||
+ // Paper end
|
||||
/**
|
||||
* Instructs this Mob to set the specified LivingEntity as its target.
|
||||
* <p>
|
||||
diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java
|
||||
index 82e4b89bf280ad3f99d94c9aaa6075449737932a..4771a1537646217ad0836f7d5ed62940339b44c6 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Player.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Player.java
|
||||
@@ -727,7 +727,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
|
||||
*
|
||||
* Use supplied alternative character to the section symbol to represent legacy color codes.
|
||||
*
|
||||
- * @param alternateChar Alternate symbol such as '&'
|
||||
+ * @param alternateChar Alternate symbol such as '&'
|
||||
* @param message The message to send
|
||||
* @deprecated use {@link #sendActionBar(Component)}
|
||||
*/
|
||||
diff --git a/src/main/java/org/bukkit/event/player/PlayerMoveEvent.java b/src/main/java/org/bukkit/event/player/PlayerMoveEvent.java
|
||||
index 1b2267f4e8ebded198773ec80e2bff2c861c7084..1a58734d919fae247eeb85dd785fd59990856505 100644
|
||||
--- a/src/main/java/org/bukkit/event/player/PlayerMoveEvent.java
|
||||
+++ b/src/main/java/org/bukkit/event/player/PlayerMoveEvent.java
|
||||
@@ -78,7 +78,7 @@ public class PlayerMoveEvent extends PlayerEvent implements Cancellable {
|
||||
*
|
||||
* @return Location the player moved to
|
||||
*/
|
||||
- @Nullable
|
||||
+ @NotNull // Paper
|
||||
public Location getTo() {
|
||||
return to;
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/inventory/PlayerInventory.java b/src/main/java/org/bukkit/inventory/PlayerInventory.java
|
||||
index 99d900b2394b6c210ccf845768dae72864f32270..515587a958041e94f03c48ae87812abc39e1791c 100644
|
||||
--- a/src/main/java/org/bukkit/inventory/PlayerInventory.java
|
||||
+++ b/src/main/java/org/bukkit/inventory/PlayerInventory.java
|
||||
@@ -106,7 +106,7 @@ public interface PlayerInventory extends Inventory {
|
||||
*
|
||||
* @return the ItemStack in the given slot
|
||||
*/
|
||||
- @NotNull
|
||||
+ @Nullable
|
||||
public ItemStack getItem(@NotNull EquipmentSlot slot);
|
||||
|
||||
/**
|
31
patches/unapplied/api/0054-Item-canEntityPickup.patch
Normal file
31
patches/unapplied/api/0054-Item-canEntityPickup.patch
Normal file
|
@ -0,0 +1,31 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Fri, 5 May 2017 03:57:08 -0500
|
||||
Subject: [PATCH] Item#canEntityPickup
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/entity/Item.java b/src/main/java/org/bukkit/entity/Item.java
|
||||
index 3f2736fbddd8661e764bc2f8d0499bd13ca91df5..c404a5b8efea7c780db5ddae19456753808abb3d 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Item.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Item.java
|
||||
@@ -75,4 +75,20 @@ public interface Item extends Entity {
|
||||
*/
|
||||
@Nullable
|
||||
public UUID getThrower();
|
||||
+
|
||||
+ // Paper Start
|
||||
+ /**
|
||||
+ * Gets if non-player entities can pick this Item up
|
||||
+ *
|
||||
+ * @return True if non-player entities can pickup
|
||||
+ */
|
||||
+ public boolean canMobPickup();
|
||||
+
|
||||
+ /**
|
||||
+ * Sets if non-player entities can pick this Item up
|
||||
+ *
|
||||
+ * @param canMobPickup True to allow non-player entity pickup
|
||||
+ */
|
||||
+ public void setCanMobPickup(boolean canMobPickup);
|
||||
+ // Paper end
|
||||
}
|
102
patches/unapplied/api/0055-PlayerAttemptPickupItemEvent.patch
Normal file
102
patches/unapplied/api/0055-PlayerAttemptPickupItemEvent.patch
Normal file
|
@ -0,0 +1,102 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Sun, 11 Jun 2017 16:30:37 -0500
|
||||
Subject: [PATCH] PlayerAttemptPickupItemEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/event/player/PlayerAttemptPickupItemEvent.java b/src/main/java/org/bukkit/event/player/PlayerAttemptPickupItemEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0788153a9641e75da565d2e6eee37eeee1cbc61e
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/org/bukkit/event/player/PlayerAttemptPickupItemEvent.java
|
||||
@@ -0,0 +1,90 @@
|
||||
+package org.bukkit.event.player;
|
||||
+
|
||||
+import org.bukkit.entity.Item;
|
||||
+import org.bukkit.entity.Player;
|
||||
+import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * Thrown when a player attempts to pick an item up from the ground
|
||||
+ */
|
||||
+public class PlayerAttemptPickupItemEvent extends PlayerEvent implements Cancellable {
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+ @NotNull private final Item item;
|
||||
+ private final int remaining;
|
||||
+ private boolean flyAtPlayer = true;
|
||||
+ private boolean isCancelled = false;
|
||||
+
|
||||
+ @Deprecated // Remove in 1.13 // Remove in 1.14?
|
||||
+ public PlayerAttemptPickupItemEvent(@NotNull final Player player, @NotNull final Item item) {
|
||||
+ this(player, item, 0);
|
||||
+ }
|
||||
+
|
||||
+ public PlayerAttemptPickupItemEvent(@NotNull final Player player, @NotNull final Item item, final int remaining) {
|
||||
+ super(player);
|
||||
+ this.item = item;
|
||||
+ this.remaining = remaining;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the Item attempted by the player.
|
||||
+ *
|
||||
+ * @return Item
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Item getItem() {
|
||||
+ return item;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the amount that will remain on the ground, if any
|
||||
+ *
|
||||
+ * @return amount that will remain on the ground
|
||||
+ */
|
||||
+ public int getRemaining() {
|
||||
+ return remaining;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Set if the item will fly at the player
|
||||
+ * <p>Cancelling the event will set this value to false.</p>
|
||||
+ *
|
||||
+ * @param flyAtPlayer True for item to fly at player
|
||||
+ */
|
||||
+ public void setFlyAtPlayer(boolean flyAtPlayer) {
|
||||
+ this.flyAtPlayer = flyAtPlayer;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets if the item will fly at the player
|
||||
+ *
|
||||
+ * @return True if the item will fly at the player
|
||||
+ */
|
||||
+ public boolean getFlyAtPlayer() {
|
||||
+ return this.flyAtPlayer;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isCancelled() {
|
||||
+ return this.isCancelled;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setCancelled(boolean cancel) {
|
||||
+ this.isCancelled = cancel;
|
||||
+ this.flyAtPlayer = !cancel;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+}
|
126
patches/unapplied/api/0056-Add-UnknownCommandEvent.patch
Normal file
126
patches/unapplied/api/0056-Add-UnknownCommandEvent.patch
Normal file
|
@ -0,0 +1,126 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Sweepyoface <github@sweepy.pw>
|
||||
Date: Sat, 17 Jun 2017 18:48:06 -0400
|
||||
Subject: [PATCH] Add UnknownCommandEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/event/command/UnknownCommandEvent.java b/src/main/java/org/bukkit/event/command/UnknownCommandEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..d5632d352590dec6982a372b285a8d4a332fa589
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/org/bukkit/event/command/UnknownCommandEvent.java
|
||||
@@ -0,0 +1,114 @@
|
||||
+package org.bukkit.event.command;
|
||||
+
|
||||
+import net.kyori.adventure.text.Component;
|
||||
+import org.bukkit.Bukkit;
|
||||
+import org.bukkit.command.CommandSender;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.Event;
|
||||
+
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
+
|
||||
+/**
|
||||
+ * Thrown when a player executes a command that is not defined
|
||||
+ */
|
||||
+public class UnknownCommandEvent extends Event {
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+ @NotNull private CommandSender sender;
|
||||
+ @NotNull private String commandLine;
|
||||
+ @Nullable private Component message;
|
||||
+
|
||||
+ @Deprecated
|
||||
+ public UnknownCommandEvent(@NotNull final CommandSender sender, @NotNull final String commandLine, @Nullable final String message) {
|
||||
+ this(sender, commandLine, message == null ? null : Bukkit.getUnsafe().legacyComponentSerializer().deserialize(message));
|
||||
+ }
|
||||
+
|
||||
+ public UnknownCommandEvent(@NotNull final CommandSender sender, @NotNull final String commandLine, @Nullable final Component message) {
|
||||
+ super(false);
|
||||
+ this.sender = sender;
|
||||
+ this.commandLine = commandLine;
|
||||
+ this.message = message;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the CommandSender or ConsoleCommandSender
|
||||
+ * <p>
|
||||
+ *
|
||||
+ * @return Sender of the command
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public CommandSender getSender() {
|
||||
+ return sender;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the command that was send
|
||||
+ * <p>
|
||||
+ *
|
||||
+ * @return Command sent
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public String getCommandLine() {
|
||||
+ return commandLine;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets message that will be returned
|
||||
+ * <p>
|
||||
+ *
|
||||
+ * @return Unknown command message
|
||||
+ * @deprecated use {@link #message()}
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ @Deprecated
|
||||
+ public String getMessage() {
|
||||
+ return this.message == null ? null : Bukkit.getUnsafe().legacyComponentSerializer().serialize(this.message);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets message that will be returned
|
||||
+ * <p>
|
||||
+ * Set to null to avoid any message being sent
|
||||
+ *
|
||||
+ * @param message the message to be returned, or null
|
||||
+ * @deprecated use {@link #message(Component)}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ public void setMessage(@Nullable String message) {
|
||||
+ this.message(message == null ? null : Bukkit.getUnsafe().legacyComponentSerializer().deserialize(message));
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets message that will be returned
|
||||
+ * <p>
|
||||
+ *
|
||||
+ * @return Unknown command message
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public Component message() {
|
||||
+ return this.message;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets message that will be returned
|
||||
+ * <p>
|
||||
+ * Set to null to avoid any message being sent
|
||||
+ *
|
||||
+ * @param message the message to be returned, or null
|
||||
+ */
|
||||
+ public void message(@Nullable Component message) {
|
||||
+ this.message = message;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+}
|
||||
+
|
351
patches/unapplied/api/0057-Basic-PlayerProfile-API.patch
Normal file
351
patches/unapplied/api/0057-Basic-PlayerProfile-API.patch
Normal file
|
@ -0,0 +1,351 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 15 Jan 2018 21:46:46 -0500
|
||||
Subject: [PATCH] Basic PlayerProfile API
|
||||
|
||||
Provides basic elements of a PlayerProfile to be used by future API/events
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/profile/PlayerProfile.java b/src/main/java/com/destroystokyo/paper/profile/PlayerProfile.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..2ef9a7bd55e2c9cf8cb20d5f77282676ae11181f
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/profile/PlayerProfile.java
|
||||
@@ -0,0 +1,177 @@
|
||||
+package com.destroystokyo.paper.profile;
|
||||
+
|
||||
+import java.util.Collection;
|
||||
+import java.util.Set;
|
||||
+import java.util.UUID;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
+
|
||||
+/**
|
||||
+ * Represents a players profile for the game, such as UUID, Name, and textures.
|
||||
+ */
|
||||
+public interface PlayerProfile {
|
||||
+
|
||||
+ /**
|
||||
+ * @return The players name, if set
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ String getName();
|
||||
+
|
||||
+ /**
|
||||
+ * Sets this profiles Name
|
||||
+ *
|
||||
+ * @param name The new Name
|
||||
+ * @return The previous Name
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ String setName(@Nullable String name);
|
||||
+
|
||||
+ /**
|
||||
+ * @return The players unique identifier, if set
|
||||
+ */
|
||||
+ @Nullable UUID getId();
|
||||
+
|
||||
+ /**
|
||||
+ * Sets this profiles UUID
|
||||
+ *
|
||||
+ * @param uuid The new UUID
|
||||
+ * @return The previous UUID
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ UUID setId(@Nullable UUID uuid);
|
||||
+
|
||||
+ /**
|
||||
+ * @return A Mutable set of this players properties, such as textures.
|
||||
+ * Values specified here are subject to implementation details.
|
||||
+ */
|
||||
+ @NotNull Set<ProfileProperty> getProperties();
|
||||
+
|
||||
+ /**
|
||||
+ * Check if the Profile has the specified property
|
||||
+ * @param property Property name to check
|
||||
+ * @return If the property is set
|
||||
+ */
|
||||
+ boolean hasProperty(@Nullable String property);
|
||||
+
|
||||
+ /**
|
||||
+ * Sets a property. If the property already exists, the previous one will be replaced
|
||||
+ * @param property Property to set.
|
||||
+ */
|
||||
+ void setProperty(@NotNull ProfileProperty property);
|
||||
+
|
||||
+ /**
|
||||
+ * Sets multiple properties. If any of the set properties already exist, it will be replaced
|
||||
+ * @param properties The properties to set
|
||||
+ */
|
||||
+ void setProperties(@NotNull Collection<ProfileProperty> properties);
|
||||
+
|
||||
+ /**
|
||||
+ * Removes a specific property from this profile
|
||||
+ * @param property The property to remove
|
||||
+ * @return If a property was removed
|
||||
+ */
|
||||
+ boolean removeProperty(@Nullable String property);
|
||||
+
|
||||
+ /**
|
||||
+ * Removes a specific property from this profile
|
||||
+ * @param property The property to remove
|
||||
+ * @return If a property was removed
|
||||
+ */
|
||||
+ default boolean removeProperty(@NotNull ProfileProperty property) {
|
||||
+ return removeProperty(property.getName());
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Removes all properties in the collection
|
||||
+ * @param properties The properties to remove
|
||||
+ * @return If any property was removed
|
||||
+ */
|
||||
+ default boolean removeProperties(@NotNull Collection<ProfileProperty> properties) {
|
||||
+ boolean removed = false;
|
||||
+ for (ProfileProperty property : properties) {
|
||||
+ if (removeProperty(property)) {
|
||||
+ removed = true;
|
||||
+ }
|
||||
+ }
|
||||
+ return removed;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Clears all properties on this profile
|
||||
+ */
|
||||
+ void clearProperties();
|
||||
+
|
||||
+ /**
|
||||
+ * @return If the profile is now complete (has UUID and Name)
|
||||
+ */
|
||||
+ boolean isComplete();
|
||||
+
|
||||
+ /**
|
||||
+ * Like {@link #complete(boolean)} but will try only from cache, and not make network calls
|
||||
+ * Does not account for textures.
|
||||
+ *
|
||||
+ * @return If the profile is now complete (has UUID and Name)
|
||||
+ */
|
||||
+ boolean completeFromCache();
|
||||
+
|
||||
+ /**
|
||||
+ * Like {@link #complete(boolean)} but will try only from cache, and not make network calls
|
||||
+ * Does not account for textures.
|
||||
+ *
|
||||
+ * @param onlineMode Treat this as online mode or not
|
||||
+ * @return If the profile is now complete (has UUID and Name)
|
||||
+ */
|
||||
+ boolean completeFromCache(boolean onlineMode);
|
||||
+
|
||||
+ /**
|
||||
+ * Like {@link #complete(boolean)} but will try only from cache, and not make network calls
|
||||
+ * Does not account for textures.
|
||||
+ *
|
||||
+ * @param lookupUUID If only name is supplied, should we do a UUID lookup
|
||||
+ * @param onlineMode Treat this as online mode or not
|
||||
+ * @return If the profile is now complete (has UUID and Name)
|
||||
+ */
|
||||
+ boolean completeFromCache(boolean lookupUUID, boolean onlineMode);
|
||||
+
|
||||
+ /**
|
||||
+ * If this profile is not complete, then make the API call to complete it.
|
||||
+ * This is a blocking operation and should be done asynchronously.
|
||||
+ *
|
||||
+ * This will also complete textures. If you do not want to load textures, use {{@link #complete(boolean)}}
|
||||
+ * @return If the profile is now complete (has UUID and Name) (if you get rate limited, this operation may fail)
|
||||
+ */
|
||||
+ default boolean complete() {
|
||||
+ return complete(true);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * If this profile is not complete, then make the API call to complete it.
|
||||
+ * This is a blocking operation and should be done asynchronously.
|
||||
+ *
|
||||
+ * Optionally will also fill textures.
|
||||
+ *
|
||||
+ * Online mode will be automatically determined
|
||||
+ * @param textures controls if we should fill the profile with texture properties
|
||||
+ * @return If the profile is now complete (has UUID and Name) (if you get rate limited, this operation may fail)
|
||||
+ */
|
||||
+ boolean complete(boolean textures);
|
||||
+
|
||||
+ /**
|
||||
+ * If this profile is not complete, then make the API call to complete it.
|
||||
+ * This is a blocking operation and should be done asynchronously.
|
||||
+ *
|
||||
+ * Optionally will also fill textures.
|
||||
+ * @param textures controls if we should fill the profile with texture properties
|
||||
+ * @param onlineMode Treat this server as online mode or not
|
||||
+ * @return If the profile is now complete (has UUID and Name) (if you get rate limited, this operation may fail)
|
||||
+ */
|
||||
+ boolean complete(boolean textures, boolean onlineMode);
|
||||
+
|
||||
+ /**
|
||||
+ * Whether or not this Profile has textures associated to it
|
||||
+ * @return If has a textures property
|
||||
+ */
|
||||
+ default boolean hasTextures() {
|
||||
+ return hasProperty("textures");
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/profile/ProfileProperty.java b/src/main/java/com/destroystokyo/paper/profile/ProfileProperty.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..7b3b6ef533d32169fbeca389bd61cfc6b0e0faee
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/profile/ProfileProperty.java
|
||||
@@ -0,0 +1,72 @@
|
||||
+package com.destroystokyo.paper.profile;
|
||||
+
|
||||
+import com.google.common.base.Preconditions;
|
||||
+
|
||||
+import java.util.Objects;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
+
|
||||
+/**
|
||||
+ * Represents a property on a {@link PlayerProfile}
|
||||
+ */
|
||||
+public class ProfileProperty {
|
||||
+ private final String name;
|
||||
+ private final String value;
|
||||
+ private final String signature;
|
||||
+
|
||||
+ public ProfileProperty(@NotNull String name, @NotNull String value) {
|
||||
+ this(name, value, null);
|
||||
+ }
|
||||
+
|
||||
+ public ProfileProperty(@NotNull String name, @NotNull String value, @Nullable String signature) {
|
||||
+ this.name = Preconditions.checkNotNull(name, "ProfileProperty name can not be null");
|
||||
+ this.value = Preconditions.checkNotNull(value, "ProfileProperty value can not be null");
|
||||
+ this.signature = signature;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return The property name, ie "textures"
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public String getName() {
|
||||
+ return name;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return The property value, likely to be base64 encoded
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public String getValue() {
|
||||
+ return value;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return A signature from Mojang for signed properties
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public String getSignature() {
|
||||
+ return signature;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return If this property has a signature or not
|
||||
+ */
|
||||
+ public boolean isSigned() {
|
||||
+ return this.signature != null;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean equals(Object o) {
|
||||
+ if (this == o) return true;
|
||||
+ if (o == null || getClass() != o.getClass()) return false;
|
||||
+ ProfileProperty that = (ProfileProperty) o;
|
||||
+ return Objects.equals(name, that.name) &&
|
||||
+ Objects.equals(value, that.value) &&
|
||||
+ Objects.equals(signature, that.signature);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int hashCode() {
|
||||
+ return Objects.hash(name);
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
|
||||
index fa3cd5395ec29d7c51c792720acbb2394f238c45..6c7b1e172a9acc881ecade6543245e8a64e251f6 100644
|
||||
--- a/src/main/java/org/bukkit/Bukkit.java
|
||||
+++ b/src/main/java/org/bukkit/Bukkit.java
|
||||
@@ -1918,6 +1918,40 @@ public final class Bukkit {
|
||||
public static boolean suggestPlayerNamesWhenNullTabCompletions() {
|
||||
return server.suggestPlayerNamesWhenNullTabCompletions();
|
||||
}
|
||||
+
|
||||
+ /**
|
||||
+ * Creates a PlayerProfile for the specified uuid, with name as null
|
||||
+ * @param uuid UUID to create profile for
|
||||
+ * @return A PlayerProfile object
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public static com.destroystokyo.paper.profile.PlayerProfile createProfile(@NotNull UUID uuid) {
|
||||
+ return server.createProfile(uuid);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Creates a PlayerProfile for the specified name, with UUID as null
|
||||
+ * @param name Name to create profile for
|
||||
+ * @return A PlayerProfile object
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public static com.destroystokyo.paper.profile.PlayerProfile createProfile(@NotNull String name) {
|
||||
+ return server.createProfile(name);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Creates a PlayerProfile for the specified name/uuid
|
||||
+ *
|
||||
+ * Both UUID and Name can not be null at same time. One must be supplied.
|
||||
+ *
|
||||
+ * @param uuid UUID to create profile for
|
||||
+ * @param name Name to create profile for
|
||||
+ * @return A PlayerProfile object
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public static com.destroystokyo.paper.profile.PlayerProfile createProfile(@Nullable UUID uuid, @Nullable String name) {
|
||||
+ return server.createProfile(uuid, name);
|
||||
+ }
|
||||
// Paper end
|
||||
|
||||
@NotNull
|
||||
diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
|
||||
index d1e5e679e0a7482a87a9a049ed0ce5c1b9891c90..8021598d78170ea1676cf21bac63858528398f53 100644
|
||||
--- a/src/main/java/org/bukkit/Server.java
|
||||
+++ b/src/main/java/org/bukkit/Server.java
|
||||
@@ -1685,5 +1685,33 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
|
||||
* @return true if player names should be suggested
|
||||
*/
|
||||
boolean suggestPlayerNamesWhenNullTabCompletions();
|
||||
+
|
||||
+ /**
|
||||
+ * Creates a PlayerProfile for the specified uuid, with name as null
|
||||
+ * @param uuid UUID to create profile for
|
||||
+ * @return A PlayerProfile object
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ com.destroystokyo.paper.profile.PlayerProfile createProfile(@NotNull UUID uuid);
|
||||
+
|
||||
+ /**
|
||||
+ * Creates a PlayerProfile for the specified name, with UUID as null
|
||||
+ * @param name Name to create profile for
|
||||
+ * @return A PlayerProfile object
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ com.destroystokyo.paper.profile.PlayerProfile createProfile(@NotNull String name);
|
||||
+
|
||||
+ /**
|
||||
+ * Creates a PlayerProfile for the specified name/uuid
|
||||
+ *
|
||||
+ * Both UUID and Name can not be null at same time. One must be supplied.
|
||||
+ *
|
||||
+ * @param uuid UUID to create profile for
|
||||
+ * @param name Name to create profile for
|
||||
+ * @return A PlayerProfile object
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ com.destroystokyo.paper.profile.PlayerProfile createProfile(@Nullable UUID uuid, @Nullable String name);
|
||||
// Paper end
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Sun, 7 May 2017 06:26:01 -0500
|
||||
Subject: [PATCH] PlayerPickupItemEvent#setFlyAtPlayer
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/event/player/PlayerPickupItemEvent.java b/src/main/java/org/bukkit/event/player/PlayerPickupItemEvent.java
|
||||
index 951ea2cc763973655beedcba3c75332d3f297313..18d82c111f30e0279c10a174a51bac018185cd38 100644
|
||||
--- a/src/main/java/org/bukkit/event/player/PlayerPickupItemEvent.java
|
||||
+++ b/src/main/java/org/bukkit/event/player/PlayerPickupItemEvent.java
|
||||
@@ -17,6 +17,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
public class PlayerPickupItemEvent extends PlayerEvent implements Cancellable {
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private final Item item;
|
||||
+ private boolean flyAtPlayer = true; // Paper
|
||||
private boolean cancel = false;
|
||||
private final int remaining;
|
||||
|
||||
@@ -45,6 +46,27 @@ public class PlayerPickupItemEvent extends PlayerEvent implements Cancellable {
|
||||
return remaining;
|
||||
}
|
||||
|
||||
+ // Paper Start
|
||||
+ /**
|
||||
+ * Set if the item will fly at the player
|
||||
+ * <p>Cancelling the event will set this value to false.</p>
|
||||
+ *
|
||||
+ * @param flyAtPlayer True for item to fly at player
|
||||
+ */
|
||||
+ public void setFlyAtPlayer(boolean flyAtPlayer) {
|
||||
+ this.flyAtPlayer = flyAtPlayer;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets if the item will fly at the player
|
||||
+ *
|
||||
+ * @return True if the item will fly at the player
|
||||
+ */
|
||||
+ public boolean getFlyAtPlayer() {
|
||||
+ return flyAtPlayer;
|
||||
+ }
|
||||
+ // Paper End
|
||||
+
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return cancel;
|
||||
@@ -53,6 +75,7 @@ public class PlayerPickupItemEvent extends PlayerEvent implements Cancellable {
|
||||
@Override
|
||||
public void setCancelled(boolean cancel) {
|
||||
this.cancel = cancel;
|
||||
+ this.flyAtPlayer = !cancel; // Paper
|
||||
}
|
||||
|
||||
@NotNull
|
|
@ -0,0 +1,37 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sat, 17 Jun 2017 15:04:51 -0400
|
||||
Subject: [PATCH] Shoulder Entities Release API
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/entity/HumanEntity.java b/src/main/java/org/bukkit/entity/HumanEntity.java
|
||||
index 0ab94ddd3b88eee8040233a89823bd2fadc78d55..396092fd249928ca01133eeeeb61f0ad90b2e332 100644
|
||||
--- a/src/main/java/org/bukkit/entity/HumanEntity.java
|
||||
+++ b/src/main/java/org/bukkit/entity/HumanEntity.java
|
||||
@@ -315,6 +315,26 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder
|
||||
*/
|
||||
public int getExpToLevel();
|
||||
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * If there is an Entity on this entities left shoulder, it will be released to the world and returned.
|
||||
+ * If no Entity is released, null will be returned.
|
||||
+ *
|
||||
+ * @return The released entity, or null
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public Entity releaseLeftShoulderEntity();
|
||||
+
|
||||
+ /**
|
||||
+ * If there is an Entity on this entities left shoulder, it will be released to the world and returned.
|
||||
+ * If no Entity is released, null will be returned.
|
||||
+ *
|
||||
+ * @return The released entity, or null
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public Entity releaseRightShoulderEntity();
|
||||
+ // Paper end
|
||||
+
|
||||
/**
|
||||
* Gets the current cooldown for a player's attack.
|
||||
*
|
23
patches/unapplied/api/0060-Entity-fromMobSpawner.patch
Normal file
23
patches/unapplied/api/0060-Entity-fromMobSpawner.patch
Normal file
|
@ -0,0 +1,23 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Sun, 18 Jun 2017 18:17:05 -0500
|
||||
Subject: [PATCH] Entity#fromMobSpawner()
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/entity/Entity.java b/src/main/java/org/bukkit/entity/Entity.java
|
||||
index 7e0ec58ea1d23501f0273882ebae8e45513b02cf..d794ed97bd14c67584af9190bad7d0cd07001b05 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Entity.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Entity.java
|
||||
@@ -673,5 +673,12 @@ public interface Entity extends Metadatable, CommandSender, Nameable, Persistent
|
||||
*/
|
||||
@Nullable
|
||||
Location getOrigin();
|
||||
+
|
||||
+ /**
|
||||
+ * Returns whether this entity was spawned from a mob spawner.
|
||||
+ *
|
||||
+ * @return True if entity spawned from a mob spawner
|
||||
+ */
|
||||
+ boolean fromMobSpawner();
|
||||
// Paper end
|
||||
}
|
174
patches/unapplied/api/0061-Profile-Lookup-Events.patch
Normal file
174
patches/unapplied/api/0061-Profile-Lookup-Events.patch
Normal file
|
@ -0,0 +1,174 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sat, 17 Jun 2017 16:30:44 -0400
|
||||
Subject: [PATCH] Profile Lookup Events
|
||||
|
||||
Adds a Pre Lookup Event and a Post Lookup Event so that plugins may prefill in profile data, and cache the responses from
|
||||
profiles that had to be looked up.
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/profile/LookupProfileEvent.java b/src/main/java/com/destroystokyo/paper/event/profile/LookupProfileEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..8df37c07cd55ddf110d1dd68183d7b697f7a6756
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/profile/LookupProfileEvent.java
|
||||
@@ -0,0 +1,46 @@
|
||||
+package com.destroystokyo.paper.event.profile;
|
||||
+
|
||||
+import com.destroystokyo.paper.profile.PlayerProfile;
|
||||
+import org.bukkit.Bukkit;
|
||||
+import org.bukkit.event.Event;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * Allows a plugin to be notified anytime AFTER a Profile has been looked up from the Mojang API
|
||||
+ * This is an opportunity to view the response and potentially cache things.
|
||||
+ *
|
||||
+ * No guarantees are made about thread execution context for this event. If you need to know, check
|
||||
+ * event.isAsync()
|
||||
+ */
|
||||
+public class LookupProfileEvent extends Event {
|
||||
+
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+
|
||||
+ @NotNull private final PlayerProfile profile;
|
||||
+
|
||||
+ public LookupProfileEvent(@NotNull PlayerProfile profile) {
|
||||
+ super(!Bukkit.isPrimaryThread());
|
||||
+ this.profile = profile;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return The profile that was recently looked up. This profile can be mutated
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public PlayerProfile getPlayerProfile() {
|
||||
+ return profile;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/profile/PreLookupProfileEvent.java b/src/main/java/com/destroystokyo/paper/event/profile/PreLookupProfileEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..4dcf6242c9acc62d030a94f67b78729ed29f8c85
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/profile/PreLookupProfileEvent.java
|
||||
@@ -0,0 +1,108 @@
|
||||
+package com.destroystokyo.paper.event.profile;
|
||||
+
|
||||
+import com.destroystokyo.paper.profile.PlayerProfile;
|
||||
+import com.destroystokyo.paper.profile.ProfileProperty;
|
||||
+import com.google.common.collect.ArrayListMultimap;
|
||||
+import org.bukkit.Bukkit;
|
||||
+import org.bukkit.event.Event;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+
|
||||
+import java.util.HashSet;
|
||||
+import java.util.Set;
|
||||
+import java.util.UUID;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
+
|
||||
+/**
|
||||
+ * Allows a plugin to intercept a Profile Lookup for a Profile by name
|
||||
+ *
|
||||
+ * At the point of event fire, the UUID and properties are unset.
|
||||
+ *
|
||||
+ * If a plugin sets the UUID, and optionally the properties, the API call to look up the profile may be skipped.
|
||||
+ *
|
||||
+ * No guarantees are made about thread execution context for this event. If you need to know, check
|
||||
+ * event.isAsync()
|
||||
+ */
|
||||
+public class PreLookupProfileEvent extends Event {
|
||||
+
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+ @NotNull private final String name;
|
||||
+ private UUID uuid;
|
||||
+ @NotNull private Set<ProfileProperty> properties = new HashSet<>();
|
||||
+
|
||||
+ public PreLookupProfileEvent(@NotNull String name) {
|
||||
+ super(!Bukkit.isPrimaryThread());
|
||||
+ this.name = name;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return Name of the profile
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public String getName() {
|
||||
+ return name;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * If this value is left null by the completion of the event call, then the server will
|
||||
+ * trigger a call to the Mojang API to look up the UUID (Network Request), and subsequently, fire a
|
||||
+ * {@link LookupProfileEvent}
|
||||
+ *
|
||||
+ * @return The UUID of the profile if it has already been provided by a plugin
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public UUID getUUID() {
|
||||
+ return uuid;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the UUID for this player name. This will skip the initial API call to find the players UUID.
|
||||
+ *
|
||||
+ * However, if Profile Properties are needed by the server, you must also set them or else an API call might still be made.
|
||||
+ *
|
||||
+ * @param uuid the UUID to set for the profile or null to reset
|
||||
+ */
|
||||
+ public void setUUID(@Nullable UUID uuid) {
|
||||
+ this.uuid = uuid;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return The currently pending prepopulated properties.
|
||||
+ * Any property in this Set will be automatically prefilled on this Profile
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Set<ProfileProperty> getProfileProperties() {
|
||||
+ return this.properties;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Clears any existing prepopulated properties and uses the supplied properties
|
||||
+ * Any property in this Set will be automatically prefilled on this Profile
|
||||
+ * @param properties The properties to add
|
||||
+ */
|
||||
+ public void setProfileProperties(@NotNull Set<ProfileProperty> properties) {
|
||||
+ this.properties = new HashSet<>();
|
||||
+ this.properties.addAll(properties);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Adds any properties currently missing to the prepopulated properties set, replacing any that already were set.
|
||||
+ * Any property in this Set will be automatically prefilled on this Profile
|
||||
+ * @param properties The properties to add
|
||||
+ */
|
||||
+ public void addProfileProperties(@NotNull Set<ProfileProperty> properties) {
|
||||
+ this.properties.addAll(properties);
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+}
|
|
@ -0,0 +1,83 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sat, 10 Dec 2016 16:12:48 -0500
|
||||
Subject: [PATCH] Improve the Saddle API for Horses
|
||||
|
||||
Not all horses with Saddles have armor. This lets us break up the horses with saddles
|
||||
and access their saddle state separately from an interface shared with Armor.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/inventory/ArmoredHorseInventory.java b/src/main/java/org/bukkit/inventory/ArmoredHorseInventory.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..163ffe8ff76ded6265d865901d5110fb6a56950d
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/org/bukkit/inventory/ArmoredHorseInventory.java
|
||||
@@ -0,0 +1,21 @@
|
||||
+package org.bukkit.inventory;
|
||||
+
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
+
|
||||
+public interface ArmoredHorseInventory extends AbstractHorseInventory {
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the item in the horse's armor slot.
|
||||
+ *
|
||||
+ * @return the armor item
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ ItemStack getArmor();
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the item in the horse's armor slot.
|
||||
+ *
|
||||
+ * @param stack the new item
|
||||
+ */
|
||||
+ void setArmor(@Nullable ItemStack stack);
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/inventory/HorseInventory.java b/src/main/java/org/bukkit/inventory/HorseInventory.java
|
||||
index 608e99c4207405bf9dd88d44ad8e82eefa19e45c..53498debe4cfb80592ef3025270bc8e5df4a5fec 100644
|
||||
--- a/src/main/java/org/bukkit/inventory/HorseInventory.java
|
||||
+++ b/src/main/java/org/bukkit/inventory/HorseInventory.java
|
||||
@@ -5,20 +5,4 @@ import org.jetbrains.annotations.Nullable;
|
||||
/**
|
||||
* An interface to the inventory of a Horse.
|
||||
*/
|
||||
-public interface HorseInventory extends AbstractHorseInventory {
|
||||
-
|
||||
- /**
|
||||
- * Gets the item in the horse's armor slot.
|
||||
- *
|
||||
- * @return the armor item
|
||||
- */
|
||||
- @Nullable
|
||||
- ItemStack getArmor();
|
||||
-
|
||||
- /**
|
||||
- * Sets the item in the horse's armor slot.
|
||||
- *
|
||||
- * @param stack the new item
|
||||
- */
|
||||
- void setArmor(@Nullable ItemStack stack);
|
||||
-}
|
||||
+public interface HorseInventory extends AbstractHorseInventory, ArmoredHorseInventory {}
|
||||
diff --git a/src/main/java/org/bukkit/inventory/LlamaInventory.java b/src/main/java/org/bukkit/inventory/LlamaInventory.java
|
||||
index 2fa2c9d07ecbafaf2396d913af90f1f4d432b238..5ac1afb8a213fa0fe344db4730ecbc5de6eed445 100644
|
||||
--- a/src/main/java/org/bukkit/inventory/LlamaInventory.java
|
||||
+++ b/src/main/java/org/bukkit/inventory/LlamaInventory.java
|
||||
@@ -6,7 +6,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
/**
|
||||
* An interface to the inventory of a {@link Llama}.
|
||||
*/
|
||||
-public interface LlamaInventory extends AbstractHorseInventory {
|
||||
+public interface LlamaInventory extends SaddledHorseInventory {
|
||||
|
||||
/**
|
||||
* Gets the item in the llama's decor slot.
|
||||
diff --git a/src/main/java/org/bukkit/inventory/SaddledHorseInventory.java b/src/main/java/org/bukkit/inventory/SaddledHorseInventory.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..7944f26a3e2a92601c3be0e55c00c39cc16cf177
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/org/bukkit/inventory/SaddledHorseInventory.java
|
||||
@@ -0,0 +1,3 @@
|
||||
+package org.bukkit.inventory;
|
||||
+
|
||||
+public interface SaddledHorseInventory extends AbstractHorseInventory {}
|
52
patches/unapplied/api/0063-Add-getI18NDisplayName-API.patch
Normal file
52
patches/unapplied/api/0063-Add-getI18NDisplayName-API.patch
Normal file
|
@ -0,0 +1,52 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Wed, 4 May 2016 23:55:48 -0400
|
||||
Subject: [PATCH] Add getI18NDisplayName API
|
||||
|
||||
Gets the Display name as seen in the Client.
|
||||
Currently the server only supports the English language. To override this,
|
||||
You must replace the language file embedded in the server jar.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/inventory/ItemFactory.java b/src/main/java/org/bukkit/inventory/ItemFactory.java
|
||||
index 6cc4bad2ecd19f44a680ff03cbfb99d48ea5c337..b1fbb931148a87f29e8b8796b13851d767cc1d68 100644
|
||||
--- a/src/main/java/org/bukkit/inventory/ItemFactory.java
|
||||
+++ b/src/main/java/org/bukkit/inventory/ItemFactory.java
|
||||
@@ -160,5 +160,16 @@ public interface ItemFactory {
|
||||
*/
|
||||
@NotNull
|
||||
net.kyori.adventure.text.Component displayName(@NotNull ItemStack itemStack);
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the Display name as seen in the Client.
|
||||
+ * Currently the server only supports the English language. To override this,
|
||||
+ * You must replace the language file embedded in the server jar.
|
||||
+ *
|
||||
+ * @param item Item to return Display name of
|
||||
+ * @return Display name of Item
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ String getI18NDisplayName(@Nullable ItemStack item);
|
||||
// Paper end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java
|
||||
index a15abec467bac70116a6fc21a300d4930b909f15..de5bcdb7b84acdd5e22500e367df292f35a86e19 100644
|
||||
--- a/src/main/java/org/bukkit/inventory/ItemStack.java
|
||||
+++ b/src/main/java/org/bukkit/inventory/ItemStack.java
|
||||
@@ -611,5 +611,17 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, net.kyor
|
||||
public @NotNull net.kyori.adventure.text.Component displayName() {
|
||||
return Bukkit.getServer().getItemFactory().displayName(this);
|
||||
}
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the Display name as seen in the Client.
|
||||
+ * Currently the server only supports the English language. To override this,
|
||||
+ * You must replace the language file embedded in the server jar.
|
||||
+ *
|
||||
+ * @return Display name of Item
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public String getI18NDisplayName() {
|
||||
+ return Bukkit.getServer().getItemFactory().getI18NDisplayName(this);
|
||||
+ }
|
||||
// Paper end
|
||||
}
|
63
patches/unapplied/api/0064-ensureServerConversions-API.patch
Normal file
63
patches/unapplied/api/0064-ensureServerConversions-API.patch
Normal file
|
@ -0,0 +1,63 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Wed, 4 May 2016 23:55:48 -0400
|
||||
Subject: [PATCH] ensureServerConversions API
|
||||
|
||||
This will take a Bukkit ItemStack and run it through any conversions a server process would perform on it,
|
||||
to ensure it meets latest minecraft expectations.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/inventory/ItemFactory.java b/src/main/java/org/bukkit/inventory/ItemFactory.java
|
||||
index b1fbb931148a87f29e8b8796b13851d767cc1d68..71e5ee496a947fbd8e3ec579833b157c76b51833 100644
|
||||
--- a/src/main/java/org/bukkit/inventory/ItemFactory.java
|
||||
+++ b/src/main/java/org/bukkit/inventory/ItemFactory.java
|
||||
@@ -171,5 +171,17 @@ public interface ItemFactory {
|
||||
*/
|
||||
@Nullable
|
||||
String getI18NDisplayName(@Nullable ItemStack item);
|
||||
+
|
||||
+ /**
|
||||
+ * Minecraft updates are converting simple item stacks into more complex NBT oriented Item Stacks.
|
||||
+ *
|
||||
+ * Use this method to to ensure any desired data conversions are processed.
|
||||
+ * The input itemstack will not be the same as the returned itemstack.
|
||||
+ *
|
||||
+ * @param item The item to process conversions on
|
||||
+ * @return A potentially Data Converted ItemStack
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ ItemStack ensureServerConversions(@NotNull ItemStack item);
|
||||
// Paper end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java
|
||||
index de5bcdb7b84acdd5e22500e367df292f35a86e19..e8783b0116f4efd5447a5f6f260506000983ffd2 100644
|
||||
--- a/src/main/java/org/bukkit/inventory/ItemStack.java
|
||||
+++ b/src/main/java/org/bukkit/inventory/ItemStack.java
|
||||
@@ -536,7 +536,7 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, net.kyor
|
||||
}
|
||||
}
|
||||
|
||||
- return result;
|
||||
+ return result.ensureServerConversions(); // Paper
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -612,6 +612,19 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, net.kyor
|
||||
return Bukkit.getServer().getItemFactory().displayName(this);
|
||||
}
|
||||
|
||||
+ /**
|
||||
+ * Minecraft updates are converting simple item stacks into more complex NBT oriented Item Stacks.
|
||||
+ *
|
||||
+ * Use this method to to ensure any desired data conversions are processed.
|
||||
+ * The input itemstack will not be the same as the returned itemstack.
|
||||
+ *
|
||||
+ * @return A potentially Data Converted ItemStack
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ItemStack ensureServerConversions() {
|
||||
+ return Bukkit.getServer().getItemFactory().ensureServerConversions(this);
|
||||
+ }
|
||||
+
|
||||
/**
|
||||
* Gets the Display name as seen in the Client.
|
||||
* Currently the server only supports the English language. To override this,
|
|
@ -0,0 +1,56 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Mon, 31 Jul 2017 02:08:55 -0500
|
||||
Subject: [PATCH] Make /plugins list alphabetical
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/command/defaults/PluginsCommand.java b/src/main/java/org/bukkit/command/defaults/PluginsCommand.java
|
||||
index bcb576a4271b1ec7b1cfe6f83cf161b7d89ed2e5..4de959bbd1270d7d6ea8e5e69521bcca6abe2138 100644
|
||||
--- a/src/main/java/org/bukkit/command/defaults/PluginsCommand.java
|
||||
+++ b/src/main/java/org/bukkit/command/defaults/PluginsCommand.java
|
||||
@@ -3,6 +3,9 @@ package org.bukkit.command.defaults;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
+import java.util.Map;
|
||||
+import java.util.TreeMap;
|
||||
+
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
@@ -34,15 +37,22 @@ public class PluginsCommand extends BukkitCommand {
|
||||
|
||||
@NotNull
|
||||
private String getPluginList() {
|
||||
- StringBuilder pluginList = new StringBuilder();
|
||||
- Plugin[] plugins = Bukkit.getPluginManager().getPlugins();
|
||||
+ // Paper start
|
||||
+ TreeMap<String, Plugin> plugins = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
|
||||
+
|
||||
+ for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
|
||||
+ plugins.put(plugin.getDescription().getName(), plugin);
|
||||
+ }
|
||||
|
||||
- for (Plugin plugin : plugins) {
|
||||
+ StringBuilder pluginList = new StringBuilder();
|
||||
+ for (Map.Entry<String, Plugin> entry : plugins.entrySet()) {
|
||||
if (pluginList.length() > 0) {
|
||||
pluginList.append(ChatColor.WHITE);
|
||||
pluginList.append(", ");
|
||||
}
|
||||
|
||||
+ Plugin plugin = entry.getValue();
|
||||
+
|
||||
pluginList.append(plugin.isEnabled() ? ChatColor.GREEN : ChatColor.RED);
|
||||
pluginList.append(plugin.getDescription().getName());
|
||||
|
||||
@@ -51,6 +61,8 @@ public class PluginsCommand extends BukkitCommand {
|
||||
}
|
||||
}
|
||||
|
||||
- return "(" + plugins.length + "): " + pluginList.toString();
|
||||
+ return "(" + plugins.size() + "): " + pluginList.toString();
|
||||
+ // Paper end
|
||||
}
|
||||
+
|
||||
}
|
26
patches/unapplied/api/0066-LivingEntity-setKiller.patch
Normal file
26
patches/unapplied/api/0066-LivingEntity-setKiller.patch
Normal file
|
@ -0,0 +1,26 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Mon, 31 Jul 2017 01:49:43 -0500
|
||||
Subject: [PATCH] LivingEntity#setKiller
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/entity/LivingEntity.java b/src/main/java/org/bukkit/entity/LivingEntity.java
|
||||
index b41133f23d25f90fc0993499056c4eeaf003a701..bfc90a3569abc717f37c064e3068c55ef323edab 100644
|
||||
--- a/src/main/java/org/bukkit/entity/LivingEntity.java
|
||||
+++ b/src/main/java/org/bukkit/entity/LivingEntity.java
|
||||
@@ -279,6 +279,15 @@ public interface LivingEntity extends Attributable, Damageable, ProjectileSource
|
||||
@Nullable
|
||||
public Player getKiller();
|
||||
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Sets the player identified as the killer of the living entity.
|
||||
+ *
|
||||
+ * @param killer player
|
||||
+ */
|
||||
+ public void setKiller(@Nullable Player killer);
|
||||
+ // Paper end
|
||||
+
|
||||
/**
|
||||
* Adds the given {@link PotionEffect} to the living entity.
|
||||
*
|
157
patches/unapplied/api/0067-ProfileWhitelistVerifyEvent.patch
Normal file
157
patches/unapplied/api/0067-ProfileWhitelistVerifyEvent.patch
Normal file
|
@ -0,0 +1,157 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 3 Jul 2017 18:11:34 -0500
|
||||
Subject: [PATCH] ProfileWhitelistVerifyEvent
|
||||
|
||||
Fires when the server is validating if a player is whitelisted.
|
||||
|
||||
Allows you to do dynamic whitelisting and change of kick message
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/profile/ProfileWhitelistVerifyEvent.java b/src/main/java/com/destroystokyo/paper/event/profile/ProfileWhitelistVerifyEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..8a259ab49ea79673b6da9e4e2aaecec67469994e
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/profile/ProfileWhitelistVerifyEvent.java
|
||||
@@ -0,0 +1,142 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2017 - Daniel Ennis (Aikar) - MIT License
|
||||
+ *
|
||||
+ * Permission is hereby granted, free of charge, to any person obtaining
|
||||
+ * a copy of this software and associated documentation files (the
|
||||
+ * "Software"), to deal in the Software without restriction, including
|
||||
+ * without limitation the rights to use, copy, modify, merge, publish,
|
||||
+ * distribute, sublicense, and/or sell copies of the Software, and to
|
||||
+ * permit persons to whom the Software is furnished to do so, subject to
|
||||
+ * the following conditions:
|
||||
+ *
|
||||
+ * The above copyright notice and this permission notice shall be
|
||||
+ * included in all copies or substantial portions of the Software.
|
||||
+ *
|
||||
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
+ */
|
||||
+
|
||||
+package com.destroystokyo.paper.event.profile;
|
||||
+
|
||||
+import com.destroystokyo.paper.profile.PlayerProfile;
|
||||
+import net.kyori.adventure.text.Component;
|
||||
+import org.bukkit.Bukkit;
|
||||
+import org.bukkit.event.Event;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
+
|
||||
+/**
|
||||
+ * Fires when the server needs to verify if a player is whitelisted.
|
||||
+ *
|
||||
+ * Plugins may override/control the servers whitelist with this event,
|
||||
+ * and dynamically change the kick message.
|
||||
+ */
|
||||
+public class ProfileWhitelistVerifyEvent extends Event {
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+ @NotNull private final PlayerProfile profile;
|
||||
+ private final boolean whitelistEnabled;
|
||||
+ private boolean whitelisted;
|
||||
+ private final boolean isOp;
|
||||
+ @Nullable private Component kickMessage;
|
||||
+
|
||||
+ @Deprecated
|
||||
+ public ProfileWhitelistVerifyEvent(@NotNull final PlayerProfile profile, boolean whitelistEnabled, boolean whitelisted, boolean isOp, @Nullable String kickMessage) {
|
||||
+ this(profile, whitelistEnabled, whitelisted, isOp, kickMessage == null ? null : Bukkit.getUnsafe().legacyComponentSerializer().deserialize(kickMessage));
|
||||
+ }
|
||||
+
|
||||
+ public ProfileWhitelistVerifyEvent(@NotNull final PlayerProfile profile, boolean whitelistEnabled, boolean whitelisted, boolean isOp, @Nullable Component kickMessage) {
|
||||
+ this.profile = profile;
|
||||
+ this.whitelistEnabled = whitelistEnabled;
|
||||
+ this.whitelisted = whitelisted;
|
||||
+ this.isOp = isOp;
|
||||
+ this.kickMessage = kickMessage;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return the currently planned message to send to the user if they are not whitelisted
|
||||
+ * @deprecated use {@link #kickMessage()}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ @Nullable
|
||||
+ public String getKickMessage() {
|
||||
+ return this.kickMessage == null ? null : Bukkit.getUnsafe().legacyComponentSerializer().serialize(kickMessage);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @param kickMessage The message to send to the player on kick if not whitelisted. May set to null to use the server configured default
|
||||
+ * @deprecated Use {@link #kickMessage(Component)}
|
||||
+ */
|
||||
+ @Deprecated
|
||||
+ public void setKickMessage(@Nullable String kickMessage) {
|
||||
+ this.kickMessage(kickMessage == null ? null : Bukkit.getUnsafe().legacyComponentSerializer().deserialize(kickMessage));
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return the currently planned message to send to the user if they are not whitelisted
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public Component kickMessage() {
|
||||
+ return this.kickMessage;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @param kickMessage The message to send to the player on kick if not whitelisted. May set to null to use the server configured default
|
||||
+ */
|
||||
+ public void kickMessage(@Nullable Component kickMessage) {
|
||||
+ this.kickMessage = kickMessage;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return The profile of the player trying to connect
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public PlayerProfile getPlayerProfile() {
|
||||
+ return profile;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return Whether the player is whitelisted to play on this server (whitelist may be off is why its true)
|
||||
+ */
|
||||
+ public boolean isWhitelisted() {
|
||||
+ return whitelisted;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Changes the players whitelisted state. false will deny the login
|
||||
+ * @param whitelisted The new whitelisted state
|
||||
+ */
|
||||
+ public void setWhitelisted(boolean whitelisted) {
|
||||
+ this.whitelisted = whitelisted;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return if the player obtained whitelist status by having op
|
||||
+ */
|
||||
+ public boolean isOp() {
|
||||
+ return isOp;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return if the server even has whitelist on
|
||||
+ */
|
||||
+ public boolean isWhitelistEnabled() {
|
||||
+ return whitelistEnabled;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+}
|
|
@ -0,0 +1,51 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Minecrell <minecrell@minecrell.net>
|
||||
Date: Thu, 21 Sep 2017 16:33:12 +0200
|
||||
Subject: [PATCH] Allow plugins to use SLF4J for logging
|
||||
|
||||
SLF4J is a commonly used abstraction for various logging frameworks
|
||||
such as java.util.logging (JUL) or Log4j. Currently, plugins are
|
||||
required to do all their logging using the provided JUL logger.
|
||||
This is annoying for plugins that target multiple platforms or when
|
||||
using libraries that log messages using SLF4J.
|
||||
|
||||
Expose SLF4J as optional logging API for plugins, so they can use
|
||||
it without having to shade it in the plugin and going through
|
||||
several layers of logging abstraction.
|
||||
|
||||
diff --git a/build.gradle.kts b/build.gradle.kts
|
||||
index 533600dfb2e73736857cc2a10525db7dc2452433..02f80c9a34a23c2285a1e05b41f53b4bafc28c5a 100644
|
||||
--- a/build.gradle.kts
|
||||
+++ b/build.gradle.kts
|
||||
@@ -37,6 +37,8 @@ dependencies {
|
||||
apiAndDocs("net.kyori:adventure-text-serializer-gson")
|
||||
apiAndDocs("net.kyori:adventure-text-serializer-legacy")
|
||||
apiAndDocs("net.kyori:adventure-text-serializer-plain")
|
||||
+ api("org.apache.logging.log4j:log4j-api:2.14.1") // Paper
|
||||
+ api("org.slf4j:slf4j-api:1.7.30") // Paper
|
||||
|
||||
implementation("org.ow2.asm:asm:9.1")
|
||||
implementation("org.ow2.asm:asm-commons:9.1")
|
||||
diff --git a/src/main/java/org/bukkit/plugin/Plugin.java b/src/main/java/org/bukkit/plugin/Plugin.java
|
||||
index 03ca87a1cbace2459174bb7bb8847bda766e80c5..c25fc646be750d3a3b2f4fb3f1c53daee5254107 100644
|
||||
--- a/src/main/java/org/bukkit/plugin/Plugin.java
|
||||
+++ b/src/main/java/org/bukkit/plugin/Plugin.java
|
||||
@@ -179,6 +179,18 @@ public interface Plugin extends TabExecutor {
|
||||
@NotNull
|
||||
public Logger getLogger();
|
||||
|
||||
+ // Paper start - Add SLF4J/Log4J loggers
|
||||
+ @NotNull
|
||||
+ default org.slf4j.Logger getSLF4JLogger() {
|
||||
+ return org.slf4j.LoggerFactory.getLogger(getLogger().getName());
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ default org.apache.logging.log4j.Logger getLog4JLogger() {
|
||||
+ return org.apache.logging.log4j.LogManager.getLogger(getLogger().getName());
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
/**
|
||||
* Returns the name of the plugin.
|
||||
* <p>
|
|
@ -0,0 +1,41 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Minecrell <minecrell@minecrell.net>
|
||||
Date: Thu, 21 Sep 2017 16:14:13 +0200
|
||||
Subject: [PATCH] Handle plugin prefixes in implementation logging
|
||||
configuration
|
||||
|
||||
Currently, plugin prefixes are prepended to the log message in
|
||||
the PluginLogger before passing the message to the underlying
|
||||
logging framework. This is bad design because they need to be
|
||||
stripped manually when using custom appenders to log messages
|
||||
in a different format.
|
||||
|
||||
Additionally, it makes integration of alternative logging APIs hard
|
||||
because all logging must go through the PluginLogger. Avoid using
|
||||
PluginLogger and create a regular logger using the plugin name.
|
||||
The implementation should handle plugin prefixes by displaying
|
||||
logger names when appropriate.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/plugin/java/JavaPlugin.java b/src/main/java/org/bukkit/plugin/java/JavaPlugin.java
|
||||
index 50a479488917b4ce019fa71a496c41e843e9c5c4..f99d60ae4003f953b5680a997e9e43e63c035b0c 100644
|
||||
--- a/src/main/java/org/bukkit/plugin/java/JavaPlugin.java
|
||||
+++ b/src/main/java/org/bukkit/plugin/java/JavaPlugin.java
|
||||
@@ -43,7 +43,7 @@ public abstract class JavaPlugin extends PluginBase {
|
||||
private boolean naggable = true;
|
||||
private FileConfiguration newConfig = null;
|
||||
private File configFile = null;
|
||||
- private PluginLogger logger = null;
|
||||
+ private Logger logger = null; // Paper - PluginLogger -> Logger
|
||||
|
||||
public JavaPlugin() {
|
||||
final ClassLoader classLoader = this.getClass().getClassLoader();
|
||||
@@ -277,7 +277,8 @@ public abstract class JavaPlugin extends PluginBase {
|
||||
this.dataFolder = dataFolder;
|
||||
this.classLoader = classLoader;
|
||||
this.configFile = new File(dataFolder, "config.yml");
|
||||
- this.logger = new PluginLogger(this);
|
||||
+ // Paper - Handle plugin prefix in implementation
|
||||
+ this.logger = Logger.getLogger(description.getPrefix() != null ? description.getPrefix() : description.getName());
|
||||
}
|
||||
|
||||
/**
|
118
patches/unapplied/api/0070-Add-PlayerJumpEvent.patch
Normal file
118
patches/unapplied/api/0070-Add-PlayerJumpEvent.patch
Normal file
|
@ -0,0 +1,118 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <zach.brown@destroystokyo.com>
|
||||
Date: Thu, 28 Sep 2017 17:21:32 -0400
|
||||
Subject: [PATCH] Add PlayerJumpEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/player/PlayerJumpEvent.java b/src/main/java/com/destroystokyo/paper/event/player/PlayerJumpEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..289a0d784a3c74caf8a7231b4dd166096b1849a1
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/player/PlayerJumpEvent.java
|
||||
@@ -0,0 +1,106 @@
|
||||
+package com.destroystokyo.paper.event.player;
|
||||
+
|
||||
+import com.google.common.base.Preconditions;
|
||||
+import org.bukkit.Location;
|
||||
+import org.bukkit.entity.Player;
|
||||
+import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.player.PlayerEvent;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * Called when the server detects the player is jumping.
|
||||
+ * <p>
|
||||
+ * Added to avoid the overhead and special case logic that many plugins use
|
||||
+ * when checking for jumps via PlayerMoveEvent, this event is fired whenever
|
||||
+ * the server detects that the player is jumping.
|
||||
+ */
|
||||
+public class PlayerJumpEvent extends PlayerEvent implements Cancellable {
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+ private boolean cancel = false;
|
||||
+ @NotNull private Location from;
|
||||
+ @NotNull private Location to;
|
||||
+
|
||||
+ public PlayerJumpEvent(@NotNull final Player player, @NotNull final Location from, @NotNull final Location to) {
|
||||
+ super(player);
|
||||
+ this.from = from;
|
||||
+ this.to = to;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the cancellation state of this event. A cancelled event will not
|
||||
+ * be executed in the server, but will still pass to other plugins
|
||||
+ * <p>
|
||||
+ * If a jump event is cancelled, the player will be moved or
|
||||
+ * teleported back to the Location as defined by getFrom(). This will not
|
||||
+ * fire an event
|
||||
+ *
|
||||
+ * @return true if this event is cancelled
|
||||
+ */
|
||||
+ public boolean isCancelled() {
|
||||
+ return cancel;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the cancellation state of this event. A cancelled event will not
|
||||
+ * be executed in the server, but will still pass to other plugins
|
||||
+ * <p>
|
||||
+ * If a jump event is cancelled, the player will be moved or
|
||||
+ * teleported back to the Location as defined by getFrom(). This will not
|
||||
+ * fire an event
|
||||
+ *
|
||||
+ * @param cancel true if you wish to cancel this event
|
||||
+ */
|
||||
+ public void setCancelled(boolean cancel) {
|
||||
+ this.cancel = cancel;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the location this player jumped from
|
||||
+ *
|
||||
+ * @return Location the player jumped from
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Location getFrom() {
|
||||
+ return from;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the location to mark as where the player jumped from
|
||||
+ *
|
||||
+ * @param from New location to mark as the players previous location
|
||||
+ */
|
||||
+ public void setFrom(@NotNull Location from) {
|
||||
+ validateLocation(from);
|
||||
+ this.from = from;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the location this player jumped to
|
||||
+ *
|
||||
+ * This information is based on what the client sends, it typically
|
||||
+ * has little relation to the arc of the jump at any given point.
|
||||
+ *
|
||||
+ * @return Location the player jumped to
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Location getTo() {
|
||||
+ return to;
|
||||
+ }
|
||||
+
|
||||
+ private void validateLocation(Location loc) {
|
||||
+ Preconditions.checkArgument(loc != null, "Cannot use null location!");
|
||||
+ Preconditions.checkArgument(loc.getWorld() != null, "Cannot use location with null world!");
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+}
|
|
@ -0,0 +1,117 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Minecrell <minecrell@minecrell.net>
|
||||
Date: Thu, 21 Sep 2017 19:41:20 +0200
|
||||
Subject: [PATCH] Add workaround for plugins modifying the parent of the plugin
|
||||
logger
|
||||
|
||||
Essentials uses a custom logger name ("Essentials") instead of the
|
||||
plugin logger. Log messages are redirected to the plugin logger by
|
||||
setting the parent of the "Essentials" logger to the plugin logger.
|
||||
|
||||
With our changes, the plugin logger is now also called "Essentials",
|
||||
resulting in an infinite loop. Make sure plugins can't change the
|
||||
parent of the plugin logger to avoid this.
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/utils/PaperPluginLogger.java b/src/main/java/com/destroystokyo/paper/utils/PaperPluginLogger.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..76f2cb9cd99cad2a9484eab2becd8c36f1dd91b3
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/utils/PaperPluginLogger.java
|
||||
@@ -0,0 +1,41 @@
|
||||
+package com.destroystokyo.paper.utils;
|
||||
+
|
||||
+import org.bukkit.plugin.PluginDescriptionFile;
|
||||
+
|
||||
+import java.util.logging.Level;
|
||||
+import java.util.logging.LogManager;
|
||||
+import java.util.logging.Logger;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * Prevents plugins (e.g. Essentials) from changing the parent of the plugin logger.
|
||||
+ */
|
||||
+public class PaperPluginLogger extends Logger {
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static Logger getLogger(@NotNull PluginDescriptionFile description) {
|
||||
+ Logger logger = new PaperPluginLogger(description);
|
||||
+ if (!LogManager.getLogManager().addLogger(logger)) {
|
||||
+ // Disable this if it's going to happen across reloads anyways...
|
||||
+ //logger.log(Level.WARNING, "Could not insert plugin logger - one was already found: {}", LogManager.getLogManager().getLogger(this.getName()));
|
||||
+ logger = LogManager.getLogManager().getLogger(description.getPrefix() != null ? description.getPrefix() : description.getName());
|
||||
+ }
|
||||
+
|
||||
+ return logger;
|
||||
+ }
|
||||
+
|
||||
+ private PaperPluginLogger(@NotNull PluginDescriptionFile description) {
|
||||
+ super(description.getPrefix() != null ? description.getPrefix() : description.getName(), null);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setParent(@NotNull Logger parent) {
|
||||
+ if (getParent() != null) {
|
||||
+ warning("Ignoring attempt to change parent of plugin logger");
|
||||
+ } else {
|
||||
+ this.log(Level.FINE, "Setting plugin logger parent to {0}", parent);
|
||||
+ super.setParent(parent);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/plugin/java/JavaPlugin.java b/src/main/java/org/bukkit/plugin/java/JavaPlugin.java
|
||||
index f99d60ae4003f953b5680a997e9e43e63c035b0c..c943bd801b54519ba6cf5d45aec593d7b7438f99 100644
|
||||
--- a/src/main/java/org/bukkit/plugin/java/JavaPlugin.java
|
||||
+++ b/src/main/java/org/bukkit/plugin/java/JavaPlugin.java
|
||||
@@ -43,7 +43,7 @@ public abstract class JavaPlugin extends PluginBase {
|
||||
private boolean naggable = true;
|
||||
private FileConfiguration newConfig = null;
|
||||
private File configFile = null;
|
||||
- private Logger logger = null; // Paper - PluginLogger -> Logger
|
||||
+ Logger logger = null; // Paper - PluginLogger -> Logger, package-private
|
||||
|
||||
public JavaPlugin() {
|
||||
final ClassLoader classLoader = this.getClass().getClassLoader();
|
||||
@@ -277,8 +277,11 @@ public abstract class JavaPlugin extends PluginBase {
|
||||
this.dataFolder = dataFolder;
|
||||
this.classLoader = classLoader;
|
||||
this.configFile = new File(dataFolder, "config.yml");
|
||||
- // Paper - Handle plugin prefix in implementation
|
||||
- this.logger = Logger.getLogger(description.getPrefix() != null ? description.getPrefix() : description.getName());
|
||||
+ // Paper start
|
||||
+ if (this.logger == null) {
|
||||
+ this.logger = com.destroystokyo.paper.utils.PaperPluginLogger.getLogger(this.description);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
/**
|
||||
diff --git a/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java b/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java
|
||||
index 657243776c8a2abb5a57e5c407212a8387d649eb..4fa5f7140ea97e1b6a63808b59115bfb1a85cb32 100644
|
||||
--- a/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java
|
||||
+++ b/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java
|
||||
@@ -44,6 +44,7 @@ public final class PluginClassLoader extends URLClassLoader { // Spigot
|
||||
private JavaPlugin pluginInit;
|
||||
private IllegalStateException pluginState;
|
||||
private final Set<String> seenIllegalAccess = Collections.newSetFromMap(new ConcurrentHashMap<>());
|
||||
+ private java.util.logging.Logger logger; // Paper - add field
|
||||
|
||||
static {
|
||||
ClassLoader.registerAsParallelCapable();
|
||||
@@ -62,6 +63,8 @@ public final class PluginClassLoader extends URLClassLoader { // Spigot
|
||||
this.url = file.toURI().toURL();
|
||||
this.libraryLoader = libraryLoader;
|
||||
|
||||
+ this.logger = com.destroystokyo.paper.utils.PaperPluginLogger.getLogger(description); // Paper - Register logger early
|
||||
+
|
||||
try {
|
||||
Class<?> jarClass;
|
||||
try {
|
||||
@@ -229,6 +232,7 @@ public final class PluginClassLoader extends URLClassLoader { // Spigot
|
||||
pluginState = new IllegalStateException("Initial initialization");
|
||||
this.pluginInit = javaPlugin;
|
||||
|
||||
+ javaPlugin.logger = this.logger; // Paper - set logger
|
||||
javaPlugin.init(loader, loader.server, description, dataFolder, file, this);
|
||||
}
|
||||
}
|
149
patches/unapplied/api/0072-Add-PlayerArmorChangeEvent.patch
Normal file
149
patches/unapplied/api/0072-Add-PlayerArmorChangeEvent.patch
Normal file
|
@ -0,0 +1,149 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: pkt77 <parkerkt77@gmail.com>
|
||||
Date: Fri, 10 Nov 2017 23:45:59 -0500
|
||||
Subject: [PATCH] Add PlayerArmorChangeEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/player/PlayerArmorChangeEvent.java b/src/main/java/com/destroystokyo/paper/event/player/PlayerArmorChangeEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..e406ce639a2e88b78f82f25e71678a669d0a958b
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/player/PlayerArmorChangeEvent.java
|
||||
@@ -0,0 +1,137 @@
|
||||
+package com.destroystokyo.paper.event.player;
|
||||
+
|
||||
+import org.bukkit.Material;
|
||||
+import org.bukkit.entity.Player;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.player.PlayerEvent;
|
||||
+import org.bukkit.inventory.ItemStack;
|
||||
+
|
||||
+import java.util.Arrays;
|
||||
+import java.util.Collections;
|
||||
+import java.util.HashSet;
|
||||
+import java.util.Set;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
+
|
||||
+import static org.bukkit.Material.*;
|
||||
+
|
||||
+/**
|
||||
+ * Called when the player themselves change their armor items
|
||||
+ * <p>
|
||||
+ * Not currently called for environmental factors though it <strong>MAY BE IN THE FUTURE</strong>
|
||||
+ */
|
||||
+public class PlayerArmorChangeEvent extends PlayerEvent {
|
||||
+ private static final HandlerList HANDLERS = new HandlerList();
|
||||
+
|
||||
+ @NotNull private final SlotType slotType;
|
||||
+ @Nullable private final ItemStack oldItem;
|
||||
+ @Nullable private final ItemStack newItem;
|
||||
+
|
||||
+ public PlayerArmorChangeEvent(@NotNull Player player, @NotNull SlotType slotType, @Nullable ItemStack oldItem, @Nullable ItemStack newItem) {
|
||||
+ super(player);
|
||||
+ this.slotType = slotType;
|
||||
+ this.oldItem = oldItem;
|
||||
+ this.newItem = newItem;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the type of slot being altered.
|
||||
+ *
|
||||
+ * @return type of slot being altered
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public SlotType getSlotType() {
|
||||
+ return this.slotType;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the existing item that's being replaced
|
||||
+ *
|
||||
+ * @return old item
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public ItemStack getOldItem() {
|
||||
+ return this.oldItem;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the new item that's replacing the old
|
||||
+ *
|
||||
+ * @return new item
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public ItemStack getNewItem() {
|
||||
+ return this.newItem;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public String toString() {
|
||||
+ return "ArmorChangeEvent{" + "player=" + player + ", slotType=" + slotType + ", oldItem=" + oldItem + ", newItem=" + newItem + '}';
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return HANDLERS;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return HANDLERS;
|
||||
+ }
|
||||
+
|
||||
+ public enum SlotType {
|
||||
+ HEAD(NETHERITE_HELMET, DIAMOND_HELMET, GOLDEN_HELMET, IRON_HELMET, CHAINMAIL_HELMET, LEATHER_HELMET, CARVED_PUMPKIN, PLAYER_HEAD, SKELETON_SKULL, ZOMBIE_HEAD, CREEPER_HEAD, WITHER_SKELETON_SKULL, TURTLE_HELMET),
|
||||
+ CHEST(NETHERITE_CHESTPLATE, DIAMOND_CHESTPLATE, GOLDEN_CHESTPLATE, IRON_CHESTPLATE, CHAINMAIL_CHESTPLATE, LEATHER_CHESTPLATE, ELYTRA),
|
||||
+ LEGS(NETHERITE_LEGGINGS, DIAMOND_LEGGINGS, GOLDEN_LEGGINGS, IRON_LEGGINGS, CHAINMAIL_LEGGINGS, LEATHER_LEGGINGS),
|
||||
+ FEET(NETHERITE_BOOTS, DIAMOND_BOOTS, GOLDEN_BOOTS, IRON_BOOTS, CHAINMAIL_BOOTS, LEATHER_BOOTS);
|
||||
+
|
||||
+ private final Set<Material> mutableTypes = new HashSet<>();
|
||||
+ private Set<Material> immutableTypes;
|
||||
+
|
||||
+ SlotType(Material... types) {
|
||||
+ this.mutableTypes.addAll(Arrays.asList(types));
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets an immutable set of all allowed material types that can be placed in an
|
||||
+ * armor slot.
|
||||
+ *
|
||||
+ * @return immutable set of material types
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Set<Material> getTypes() {
|
||||
+ if (immutableTypes == null) {
|
||||
+ immutableTypes = Collections.unmodifiableSet(mutableTypes);
|
||||
+ }
|
||||
+
|
||||
+ return immutableTypes;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the type of slot via the specified material
|
||||
+ *
|
||||
+ * @param material material to get slot by
|
||||
+ * @return slot type the material will go in, or null if it won't
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public static SlotType getByMaterial(@NotNull Material material) {
|
||||
+ for (SlotType slotType : values()) {
|
||||
+ if (slotType.getTypes().contains(material)) {
|
||||
+ return slotType;
|
||||
+ }
|
||||
+ }
|
||||
+ return null;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets whether or not this material can be equipped to a slot
|
||||
+ *
|
||||
+ * @param material material to check
|
||||
+ * @return whether or not this material can be equipped
|
||||
+ */
|
||||
+ public static boolean isEquipable(@NotNull Material material) {
|
||||
+ return getByMaterial(material) != null;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
|
@ -0,0 +1,31 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 6 Nov 2017 21:10:01 -0500
|
||||
Subject: [PATCH] API to get a BlockState without a snapshot
|
||||
|
||||
This allows you to get a BlockState without creating a snapshot, operating
|
||||
on the real tile entity.
|
||||
|
||||
This is useful for where performance is needed
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/block/Block.java b/src/main/java/org/bukkit/block/Block.java
|
||||
index da0964b1b6555ad50cb2ee47f13a7b9dfb1ab6aa..3ca05a6e86a5329cf452041eac476e3636eec34a 100644
|
||||
--- a/src/main/java/org/bukkit/block/Block.java
|
||||
+++ b/src/main/java/org/bukkit/block/Block.java
|
||||
@@ -271,6 +271,16 @@ public interface Block extends Metadatable {
|
||||
@NotNull
|
||||
BlockState getState();
|
||||
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * @see #getState() optionally disables use of snapshot, to operate on real block data
|
||||
+ * @param useSnapshot if this block is a TE, should we create a fully copy of the TileEntity
|
||||
+ * @return BlockState with the current state of this block
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ BlockState getState(boolean useSnapshot);
|
||||
+ // Paper end
|
||||
+
|
||||
/**
|
||||
* Returns the biome that this block resides in
|
||||
*
|
266
patches/unapplied/api/0074-AsyncTabCompleteEvent.patch
Normal file
266
patches/unapplied/api/0074-AsyncTabCompleteEvent.patch
Normal file
|
@ -0,0 +1,266 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sun, 26 Nov 2017 13:17:09 -0500
|
||||
Subject: [PATCH] AsyncTabCompleteEvent
|
||||
|
||||
Let plugins be able to control tab completion of commands and chat async.
|
||||
|
||||
This will be useful for frameworks like ACF so we can define async safe completion handlers,
|
||||
and avoid going to main for tab completions.
|
||||
|
||||
Especially useful if you need to query a database in order to obtain the results for tab
|
||||
completion, such as offline players.
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/server/AsyncTabCompleteEvent.java b/src/main/java/com/destroystokyo/paper/event/server/AsyncTabCompleteEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..619ed37169c126a8c75d02699a04728bac49d10d
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/server/AsyncTabCompleteEvent.java
|
||||
@@ -0,0 +1,177 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2017 Daniel Ennis (Aikar) MIT License
|
||||
+ *
|
||||
+ * Permission is hereby granted, free of charge, to any person obtaining
|
||||
+ * a copy of this software and associated documentation files (the
|
||||
+ * "Software"), to deal in the Software without restriction, including
|
||||
+ * without limitation the rights to use, copy, modify, merge, publish,
|
||||
+ * distribute, sublicense, and/or sell copies of the Software, and to
|
||||
+ * permit persons to whom the Software is furnished to do so, subject to
|
||||
+ * the following conditions:
|
||||
+ *
|
||||
+ * The above copyright notice and this permission notice shall be
|
||||
+ * included in all copies or substantial portions of the Software.
|
||||
+ *
|
||||
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
+ */
|
||||
+
|
||||
+package com.destroystokyo.paper.event.server;
|
||||
+
|
||||
+import com.google.common.collect.ImmutableList;
|
||||
+import org.apache.commons.lang.Validate;
|
||||
+import org.bukkit.Location;
|
||||
+import org.bukkit.command.Command;
|
||||
+import org.bukkit.command.CommandSender;
|
||||
+import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.event.Event;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+
|
||||
+import java.util.ArrayList;
|
||||
+import java.util.List;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
+
|
||||
+/**
|
||||
+ * Allows plugins to compute tab completion results asynchronously. If this event provides completions, then the standard synchronous process will not be fired to populate the results. However, the synchronous TabCompleteEvent will fire with the Async results.
|
||||
+ *
|
||||
+ * Only 1 process will be allowed to provide completions, the Async Event, or the standard process.
|
||||
+ */
|
||||
+public class AsyncTabCompleteEvent extends Event implements Cancellable {
|
||||
+ @NotNull private final CommandSender sender;
|
||||
+ @NotNull private final String buffer;
|
||||
+ private final boolean isCommand;
|
||||
+ @Nullable
|
||||
+ private final Location loc;
|
||||
+ @NotNull private List<String> completions;
|
||||
+ private boolean cancelled;
|
||||
+ private boolean handled = false;
|
||||
+ private boolean fireSyncHandler = true;
|
||||
+
|
||||
+ public AsyncTabCompleteEvent(@NotNull CommandSender sender, @NotNull List<String> completions, @NotNull String buffer, boolean isCommand, @Nullable Location loc) {
|
||||
+ super(true);
|
||||
+ this.sender = sender;
|
||||
+ this.completions = completions;
|
||||
+ this.buffer = buffer;
|
||||
+ this.isCommand = isCommand;
|
||||
+ this.loc = loc;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Get the sender completing this command.
|
||||
+ *
|
||||
+ * @return the {@link CommandSender} instance
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public CommandSender getSender() {
|
||||
+ return sender;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * The list of completions which will be offered to the sender, in order.
|
||||
+ * This list is mutable and reflects what will be offered.
|
||||
+ *
|
||||
+ * If this collection is not empty after the event is fired, then
|
||||
+ * the standard process of calling {@link Command#tabComplete(CommandSender, String, String[])}
|
||||
+ * or current player names will not be called.
|
||||
+ *
|
||||
+ * @return a list of offered completions
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public List<String> getCompletions() {
|
||||
+ return completions;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Set the completions offered, overriding any already set.
|
||||
+ * If this collection is not empty after the event is fired, then
|
||||
+ * the standard process of calling {@link Command#tabComplete(CommandSender, String, String[])}
|
||||
+ * or current player names will not be called.
|
||||
+ *
|
||||
+ * The passed collection will be cloned to a new List. You must call {{@link #getCompletions()}} to mutate from here
|
||||
+ *
|
||||
+ * @param completions the new completions
|
||||
+ */
|
||||
+ public void setCompletions(@NotNull List<String> completions) {
|
||||
+ Validate.notNull(completions);
|
||||
+ this.completions = new ArrayList<>(completions);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Return the entire buffer which formed the basis of this completion.
|
||||
+ *
|
||||
+ * @return command buffer, as entered
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public String getBuffer() {
|
||||
+ return buffer;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return True if it is a command being tab completed, false if it is a chat message.
|
||||
+ */
|
||||
+ public boolean isCommand() {
|
||||
+ return isCommand;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return The position looked at by the sender, or null if none
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public Location getLocation() {
|
||||
+ return loc;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * If true, the standard process of calling {@link Command#tabComplete(CommandSender, String, String[])}
|
||||
+ * or current player names will not be called.
|
||||
+ *
|
||||
+ * @return Is completions considered handled. Always true if completions is not empty.
|
||||
+ */
|
||||
+ public boolean isHandled() {
|
||||
+ return !completions.isEmpty() || handled;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets whether or not to consider the completion request handled.
|
||||
+ * If true, the standard process of calling {@link Command#tabComplete(CommandSender, String, String[])}
|
||||
+ * or current player names will not be called.
|
||||
+ *
|
||||
+ * @param handled if this completion should be marked as being handled
|
||||
+ */
|
||||
+ public void setHandled(boolean handled) {
|
||||
+ this.handled = handled;
|
||||
+ }
|
||||
+
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isCancelled() {
|
||||
+ return cancelled;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Will provide no completions, and will not fire the synchronous process
|
||||
+ * @param cancelled true if you wish to cancel this event
|
||||
+ */
|
||||
+ @Override
|
||||
+ public void setCancelled(boolean cancelled) {
|
||||
+ this.cancelled = cancelled;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/event/server/TabCompleteEvent.java b/src/main/java/org/bukkit/event/server/TabCompleteEvent.java
|
||||
index d1a9956a1573dab54c5ff2e5d67ca86cfe1dc01a..f96c4ba53ab41ea66d4f9a4d54eeabb63f992b58 100644
|
||||
--- a/src/main/java/org/bukkit/event/server/TabCompleteEvent.java
|
||||
+++ b/src/main/java/org/bukkit/event/server/TabCompleteEvent.java
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.bukkit.event.server;
|
||||
|
||||
+import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.command.CommandSender;
|
||||
@@ -8,6 +9,7 @@ import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.player.PlayerCommandSendEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Called when a {@link CommandSender} of any description (ie: player or
|
||||
@@ -29,6 +31,13 @@ public class TabCompleteEvent extends Event implements Cancellable {
|
||||
private boolean cancelled;
|
||||
|
||||
public TabCompleteEvent(@NotNull CommandSender sender, @NotNull String buffer, @NotNull List<String> completions) {
|
||||
+ // Paper start
|
||||
+ this(sender, buffer, completions, sender instanceof org.bukkit.command.ConsoleCommandSender || buffer.startsWith("/"), null);
|
||||
+ }
|
||||
+ public TabCompleteEvent(@NotNull CommandSender sender, @NotNull String buffer, @NotNull List<String> completions, boolean isCommand, @Nullable org.bukkit.Location location) {
|
||||
+ this.isCommand = isCommand;
|
||||
+ this.loc = location;
|
||||
+ // Paper end
|
||||
Validate.notNull(sender, "sender");
|
||||
Validate.notNull(buffer, "buffer");
|
||||
Validate.notNull(completions, "completions");
|
||||
@@ -69,14 +78,35 @@ public class TabCompleteEvent extends Event implements Cancellable {
|
||||
return completions;
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ private final boolean isCommand;
|
||||
+ private final org.bukkit.Location loc;
|
||||
+ /**
|
||||
+ * @return True if it is a command being tab completed, false if it is a chat message.
|
||||
+ */
|
||||
+ public boolean isCommand() {
|
||||
+ return isCommand;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return The position looked at by the sender, or null if none
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public org.bukkit.Location getLocation() {
|
||||
+ return loc;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
/**
|
||||
* Set the completions offered, overriding any already set.
|
||||
*
|
||||
+ * The passed collection will be cloned to a new List. You must call {{@link #getCompletions()}} to mutate from here
|
||||
+ *
|
||||
* @param completions the new completions
|
||||
*/
|
||||
public void setCompletions(@NotNull List<String> completions) {
|
||||
Validate.notNull(completions);
|
||||
- this.completions = completions;
|
||||
+ this.completions = new ArrayList<>(completions); // Paper
|
||||
}
|
||||
|
||||
@Override
|
|
@ -0,0 +1,71 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Minecrell <minecrell@minecrell.net>
|
||||
Date: Tue, 10 Oct 2017 18:44:42 +0200
|
||||
Subject: [PATCH] Expose client protocol version and virtual host
|
||||
|
||||
Add a NetworkClient interface that provides access to:
|
||||
- The socket address
|
||||
- The protocol version
|
||||
- The virtual host (the hostname/port the client used to connect
|
||||
to the server)
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/network/NetworkClient.java b/src/main/java/com/destroystokyo/paper/network/NetworkClient.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..7b2af1bd72dfbcf4e962a982940fc49b851aa04f
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/network/NetworkClient.java
|
||||
@@ -0,0 +1,41 @@
|
||||
+package com.destroystokyo.paper.network;
|
||||
+
|
||||
+import java.net.InetSocketAddress;
|
||||
+
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
+
|
||||
+/**
|
||||
+ * Represents a client connected to the server.
|
||||
+ */
|
||||
+public interface NetworkClient {
|
||||
+
|
||||
+ /**
|
||||
+ * Returns the socket address of the client.
|
||||
+ *
|
||||
+ * @return The client's socket address
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ InetSocketAddress getAddress();
|
||||
+
|
||||
+ /**
|
||||
+ * Returns the protocol version of the client.
|
||||
+ *
|
||||
+ * @return The client's protocol version, or {@code -1} if unknown
|
||||
+ * @see <a href="http://wiki.vg/Protocol_version_numbers">List of protocol
|
||||
+ * version numbers</a>
|
||||
+ */
|
||||
+ int getProtocolVersion();
|
||||
+
|
||||
+ /**
|
||||
+ * Returns the virtual host the client is connected to.
|
||||
+ *
|
||||
+ * <p>The virtual host refers to the hostname/port the client used to
|
||||
+ * connect to the server.</p>
|
||||
+ *
|
||||
+ * @return The client's virtual host, or {@code null} if unknown
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ InetSocketAddress getVirtualHost();
|
||||
+
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java
|
||||
index 0dae92b41684e9c2ada74d8987f922db04a419ca..34445011ccd22753a345dfc1ff87e01d2432654c 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Player.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Player.java
|
||||
@@ -36,7 +36,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
/**
|
||||
* Represents a player, connected or not
|
||||
*/
|
||||
-public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginMessageRecipient, net.kyori.adventure.identity.Identified { // Paper
|
||||
+public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginMessageRecipient, net.kyori.adventure.identity.Identified, com.destroystokyo.paper.network.NetworkClient { // Paper
|
||||
|
||||
// Paper start
|
||||
@Override
|
|
@ -0,0 +1,35 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sat, 9 Dec 2017 12:40:25 -0500
|
||||
Subject: [PATCH] Display warning on deprecated recipe API
|
||||
|
||||
Any plugin still using this API will result in the server saving an inconsistent UUID to player data files,
|
||||
which then triggers warnings such as "Tried to load unrecognized recipe: bukkit:9e5b92f5-e549-4f47-b0a8-9f89390ed77b removed now."
|
||||
on the players login.
|
||||
|
||||
Plugin authors need to define a key to keep it consistent between server restarts.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/inventory/ShapedRecipe.java b/src/main/java/org/bukkit/inventory/ShapedRecipe.java
|
||||
index d74b3114f535e1e5e36ae007f1fe0522916a0362..d742c4058ba9aed4fbe1591fd755a06608b06e98 100644
|
||||
--- a/src/main/java/org/bukkit/inventory/ShapedRecipe.java
|
||||
+++ b/src/main/java/org/bukkit/inventory/ShapedRecipe.java
|
||||
@@ -25,6 +25,7 @@ public class ShapedRecipe implements Recipe, Keyed {
|
||||
public ShapedRecipe(@NotNull ItemStack result) {
|
||||
Preconditions.checkArgument(result.getType() != Material.AIR, "Recipe must have non-AIR result.");
|
||||
this.key = NamespacedKey.randomKey();
|
||||
+ new Throwable("Warning: A plugin is creating a recipe using a Deprecated method. This will cause you to receive warnings stating 'Tried to load unrecognized recipe: bukkit:<ID>'. Please ask the author to give their recipe a static key using NamespacedKey.").printStackTrace();
|
||||
this.output = new ItemStack(result);
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/inventory/ShapelessRecipe.java b/src/main/java/org/bukkit/inventory/ShapelessRecipe.java
|
||||
index 68447fb8c12356e779b96ec98c54119045046751..84062dd719cb8a6142dc8c806777cb208c6b42b2 100644
|
||||
--- a/src/main/java/org/bukkit/inventory/ShapelessRecipe.java
|
||||
+++ b/src/main/java/org/bukkit/inventory/ShapelessRecipe.java
|
||||
@@ -26,6 +26,7 @@ public class ShapelessRecipe implements Recipe, Keyed {
|
||||
public ShapelessRecipe(@NotNull ItemStack result) {
|
||||
Preconditions.checkArgument(result.getType() != Material.AIR, "Recipe must have non-AIR result.");
|
||||
this.key = NamespacedKey.randomKey();
|
||||
+ new Throwable("Warning: A plugin is creating a recipe using a Deprecated method. This will cause you to receive warnings stating 'Tried to load unrecognized recipe: bukkit:<ID>'. Please ask the author to give their recipe a static key using NamespacedKey.").printStackTrace();
|
||||
this.output = new ItemStack(result);
|
||||
}
|
||||
|
93
patches/unapplied/api/0077-PlayerPickupExperienceEvent.patch
Normal file
93
patches/unapplied/api/0077-PlayerPickupExperienceEvent.patch
Normal file
|
@ -0,0 +1,93 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 19 Dec 2017 22:00:41 -0500
|
||||
Subject: [PATCH] PlayerPickupExperienceEvent
|
||||
|
||||
Allows plugins to cancel a player picking up an experience orb
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/player/PlayerPickupExperienceEvent.java b/src/main/java/com/destroystokyo/paper/event/player/PlayerPickupExperienceEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..f7beb22d5105157940b39efe594ace9d4cb153f5
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/player/PlayerPickupExperienceEvent.java
|
||||
@@ -0,0 +1,80 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2017 Daniel Ennis (Aikar) MIT License
|
||||
+ *
|
||||
+ * Permission is hereby granted, free of charge, to any person obtaining
|
||||
+ * a copy of this software and associated documentation files (the
|
||||
+ * "Software"), to deal in the Software without restriction, including
|
||||
+ * without limitation the rights to use, copy, modify, merge, publish,
|
||||
+ * distribute, sublicense, and/or sell copies of the Software, and to
|
||||
+ * permit persons to whom the Software is furnished to do so, subject to
|
||||
+ * the following conditions:
|
||||
+ *
|
||||
+ * The above copyright notice and this permission notice shall be
|
||||
+ * included in all copies or substantial portions of the Software.
|
||||
+ *
|
||||
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
+ */
|
||||
+
|
||||
+package com.destroystokyo.paper.event.player;
|
||||
+
|
||||
+import org.bukkit.entity.ExperienceOrb;
|
||||
+import org.bukkit.entity.Player;
|
||||
+import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.event.Event;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.player.PlayerEvent;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * Fired when a player is attempting to pick up an experience orb
|
||||
+ */
|
||||
+public class PlayerPickupExperienceEvent extends PlayerEvent implements Cancellable {
|
||||
+ @NotNull private final ExperienceOrb experienceOrb;
|
||||
+
|
||||
+ public PlayerPickupExperienceEvent(@NotNull Player player, @NotNull ExperienceOrb experienceOrb) {
|
||||
+ super(player);
|
||||
+ this.experienceOrb = experienceOrb;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return Returns the Orb that the player is picking up
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ExperienceOrb getExperienceOrb() {
|
||||
+ return experienceOrb;
|
||||
+ }
|
||||
+
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+
|
||||
+ @NotNull
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ private boolean cancelled = false;
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isCancelled() {
|
||||
+ return cancelled;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * If true, Cancels picking up the experience orb, leaving it in the world
|
||||
+ * @param cancel true if you wish to cancel this event
|
||||
+ */
|
||||
+ @Override
|
||||
+ public void setCancelled(boolean cancel) {
|
||||
+ cancelled = cancel;
|
||||
+ }
|
||||
+}
|
102
patches/unapplied/api/0078-ExperienceOrbMergeEvent.patch
Normal file
102
patches/unapplied/api/0078-ExperienceOrbMergeEvent.patch
Normal file
|
@ -0,0 +1,102 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 19 Dec 2017 22:56:24 -0500
|
||||
Subject: [PATCH] ExperienceOrbMergeEvent
|
||||
|
||||
Fired when the server is about to merge 2 experience orbs
|
||||
Plugins can cancel this if they want to ensure experience orbs do not lose important
|
||||
metadata such as spawn reason, or conditionally move data from source to target.
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/ExperienceOrbMergeEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/ExperienceOrbMergeEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0ce3e397716c28c30ed05e153babd0bfb9dd354a
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/entity/ExperienceOrbMergeEvent.java
|
||||
@@ -0,0 +1,87 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2017 Daniel Ennis (Aikar) MIT License
|
||||
+ *
|
||||
+ * Permission is hereby granted, free of charge, to any person obtaining
|
||||
+ * a copy of this software and associated documentation files (the
|
||||
+ * "Software"), to deal in the Software without restriction, including
|
||||
+ * without limitation the rights to use, copy, modify, merge, publish,
|
||||
+ * distribute, sublicense, and/or sell copies of the Software, and to
|
||||
+ * permit persons to whom the Software is furnished to do so, subject to
|
||||
+ * the following conditions:
|
||||
+ *
|
||||
+ * The above copyright notice and this permission notice shall be
|
||||
+ * included in all copies or substantial portions of the Software.
|
||||
+ *
|
||||
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
+ */
|
||||
+
|
||||
+package com.destroystokyo.paper.event.entity;
|
||||
+
|
||||
+import org.bukkit.entity.ExperienceOrb;
|
||||
+import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.entity.EntityEvent;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * Fired anytime the server is about to merge 2 experience orbs into one
|
||||
+ */
|
||||
+public class ExperienceOrbMergeEvent extends EntityEvent implements Cancellable {
|
||||
+ @NotNull private final ExperienceOrb mergeTarget;
|
||||
+ @NotNull private final ExperienceOrb mergeSource;
|
||||
+
|
||||
+ public ExperienceOrbMergeEvent(@NotNull ExperienceOrb mergeTarget, @NotNull ExperienceOrb mergeSource) {
|
||||
+ super(mergeTarget);
|
||||
+ this.mergeTarget = mergeTarget;
|
||||
+ this.mergeSource = mergeSource;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return The orb that will absorb the other experience orb
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ExperienceOrb getMergeTarget() {
|
||||
+ return mergeTarget;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return The orb that is subject to being removed and merged into the target orb
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ExperienceOrb getMergeSource() {
|
||||
+ return mergeSource;
|
||||
+ }
|
||||
+
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+
|
||||
+ @NotNull
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ private boolean cancelled = false;
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isCancelled() {
|
||||
+ return cancelled;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @param cancel true if you wish to cancel this event, and prevent the orbs from merging
|
||||
+ */
|
||||
+ @Override
|
||||
+ public void setCancelled(boolean cancel) {
|
||||
+ cancelled = cancel;
|
||||
+ }
|
||||
+}
|
|
@ -0,0 +1,50 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Wed, 20 Dec 2017 17:38:07 -0500
|
||||
Subject: [PATCH] Ability to apply mending to XP API
|
||||
|
||||
This allows plugins that give players the ability to apply the experience
|
||||
points to the Item Mending formula, which will repair an item instead
|
||||
of giving the player experience points.
|
||||
|
||||
Both an API To standalone mend, and apply mending logic to .giveExp has been added.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java
|
||||
index b4c7f2d6de64d32804c8630f0ea1563a876b3510..96f1f1544d03d2928e95daa0dd02579ef3fdc87c 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Player.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Player.java
|
||||
@@ -985,12 +985,33 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
|
||||
*/
|
||||
public void resetPlayerWeather();
|
||||
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Gives the player the amount of experience specified.
|
||||
+ *
|
||||
+ * @param amount Exp amount to give
|
||||
+ */
|
||||
+ public default void giveExp(int amount) {
|
||||
+ giveExp(amount, false);
|
||||
+ }
|
||||
/**
|
||||
* Gives the player the amount of experience specified.
|
||||
*
|
||||
* @param amount Exp amount to give
|
||||
+ * @param applyMending Mend players items with mending, with same behavior as picking up orbs. calls {@link #applyMending(int)}
|
||||
*/
|
||||
- public void giveExp(int amount);
|
||||
+ public void giveExp(int amount, boolean applyMending);
|
||||
+
|
||||
+ /**
|
||||
+ * Applies the mending effect to any items just as picking up an orb would.
|
||||
+ *
|
||||
+ * Can also be called with {@link #giveExp(int, boolean)} by passing true to applyMending
|
||||
+ *
|
||||
+ * @param amount Exp to apply
|
||||
+ * @return the remaining experience
|
||||
+ */
|
||||
+ public int applyMending(int amount);
|
||||
+ // Paper end
|
||||
|
||||
/**
|
||||
* Gives the player the amount of experience levels specified. Levels can
|
127
patches/unapplied/api/0080-PreCreatureSpawnEvent.patch
Normal file
127
patches/unapplied/api/0080-PreCreatureSpawnEvent.patch
Normal file
|
@ -0,0 +1,127 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sun, 14 Jan 2018 16:59:43 -0500
|
||||
Subject: [PATCH] PreCreatureSpawnEvent
|
||||
|
||||
Adds an event to fire before an Entity is created, so that plugins that need to cancel
|
||||
CreatureSpawnEvent can do so from this event instead.
|
||||
|
||||
Cancelling CreatureSpawnEvent rapidly causes a lot of garbage collection and CPU waste
|
||||
as it's done after the Entity object has been fully created.
|
||||
|
||||
Mob Limiting plugins and blanket "ban this type of monster" plugins should use this event
|
||||
instead and save a lot of server resources.
|
||||
|
||||
See: https://github.com/PaperMC/Paper/issues/917
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/PreCreatureSpawnEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/PreCreatureSpawnEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..3ad231aa3206c8cfd5ec995249584cebab5d11f3
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/entity/PreCreatureSpawnEvent.java
|
||||
@@ -0,0 +1,105 @@
|
||||
+package com.destroystokyo.paper.event.entity;
|
||||
+
|
||||
+import com.google.common.base.Preconditions;
|
||||
+import org.bukkit.Location;
|
||||
+import org.bukkit.entity.EntityType;
|
||||
+import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.event.Event;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * WARNING: This event only fires for a limited number of cases, and not for every case that CreatureSpawnEvent does.
|
||||
+ *
|
||||
+ * You should still listen to CreatureSpawnEvent as a backup, and only use this event as an "enhancement".
|
||||
+ * The intent of this event is to improve server performance, so it fires even if the spawning might fail later, for
|
||||
+ * example when the entity would be unable to spawn due to limited space or lighting.
|
||||
+ *
|
||||
+ * Currently: NATURAL and SPAWNER based reasons. Please submit a Pull Request for future additions.
|
||||
+ * Also, Plugins that replace Entity Registrations with their own custom entities might not fire this event.
|
||||
+ */
|
||||
+public class PreCreatureSpawnEvent extends Event implements Cancellable {
|
||||
+ @NotNull private final Location location;
|
||||
+ @NotNull private final EntityType type;
|
||||
+ @NotNull private final CreatureSpawnEvent.SpawnReason reason;
|
||||
+ private boolean shouldAbortSpawn;
|
||||
+
|
||||
+ public PreCreatureSpawnEvent(@NotNull Location location, @NotNull EntityType type, @NotNull CreatureSpawnEvent.SpawnReason reason) {
|
||||
+ this.location = Preconditions.checkNotNull(location, "Location may not be null").clone();
|
||||
+ this.type = Preconditions.checkNotNull(type, "Type may not be null");
|
||||
+ this.reason = Preconditions.checkNotNull(reason, "Reason may not be null");
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return The location this creature is being spawned at
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Location getSpawnLocation() {
|
||||
+ return location;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return The type of creature being spawned
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public EntityType getType() {
|
||||
+ return type;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return Reason this creature is spawning (ie, NATURAL vs SPAWNER)
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public CreatureSpawnEvent.SpawnReason getReason() {
|
||||
+ return reason;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return If the spawn process should be aborted vs trying more attempts
|
||||
+ */
|
||||
+ public boolean shouldAbortSpawn() {
|
||||
+ return shouldAbortSpawn;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Set this if you are more blanket blocking all types of these spawns, and wish to abort the spawn process from
|
||||
+ * trying more attempts after this cancellation.
|
||||
+ *
|
||||
+ * @param shouldAbortSpawn Set if the spawn process should be aborted vs trying more attempts
|
||||
+ */
|
||||
+ public void setShouldAbortSpawn(boolean shouldAbortSpawn) {
|
||||
+ this.shouldAbortSpawn = shouldAbortSpawn;
|
||||
+ }
|
||||
+
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+
|
||||
+ @NotNull
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ private boolean cancelled = false;
|
||||
+
|
||||
+ /**
|
||||
+ * @return If the spawn of this creature is cancelled or not
|
||||
+ */
|
||||
+ @Override
|
||||
+ public boolean isCancelled() {
|
||||
+ return cancelled;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Cancelling this event is more effecient than cancelling CreatureSpawnEvent
|
||||
+ * @param cancel true if you wish to cancel this event, and abort the spawn of this creature
|
||||
+ */
|
||||
+ @Override
|
||||
+ public void setCancelled(boolean cancel) {
|
||||
+ cancelled = cancel;
|
||||
+ }
|
||||
+}
|
|
@ -0,0 +1,80 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sun, 14 Jan 2018 17:31:37 -0500
|
||||
Subject: [PATCH] PlayerNaturallySpawnCreaturesEvent
|
||||
|
||||
This event can be used for when you want to exclude a certain player
|
||||
from triggering monster spawns on a server.
|
||||
|
||||
Also a highly more effecient way to blanket block spawns in a world
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/PlayerNaturallySpawnCreaturesEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/PlayerNaturallySpawnCreaturesEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..112a0dbf522b8e74ce882678434923814e6b187f
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/entity/PlayerNaturallySpawnCreaturesEvent.java
|
||||
@@ -0,0 +1,64 @@
|
||||
+package com.destroystokyo.paper.event.entity;
|
||||
+
|
||||
+import org.bukkit.entity.Player;
|
||||
+import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.event.Event;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.player.PlayerEvent;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * Fired when the server is calculating what chunks to try to spawn monsters in every Monster Spawn Tick event
|
||||
+ */
|
||||
+public class PlayerNaturallySpawnCreaturesEvent extends PlayerEvent implements Cancellable {
|
||||
+ private byte radius;
|
||||
+
|
||||
+ public PlayerNaturallySpawnCreaturesEvent(@NotNull Player player, byte radius) {
|
||||
+ super(player);
|
||||
+ this.radius = radius;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return The radius of chunks around this player to be included in natural spawn selection
|
||||
+ */
|
||||
+ public byte getSpawnRadius() {
|
||||
+ return radius;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @param radius The radius of chunks around this player to be included in natural spawn selection
|
||||
+ */
|
||||
+ public void setSpawnRadius(byte radius) {
|
||||
+ this.radius = radius;
|
||||
+ }
|
||||
+
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+
|
||||
+ @NotNull
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ private boolean cancelled = false;
|
||||
+
|
||||
+ /**
|
||||
+ * @return If this players chunks will be excluded from natural spawns
|
||||
+ */
|
||||
+ @Override
|
||||
+ public boolean isCancelled() {
|
||||
+ return cancelled;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @param cancel true if you wish to cancel this event, and not include this players chunks for natural spawning
|
||||
+ */
|
||||
+ @Override
|
||||
+ public void setCancelled(boolean cancel) {
|
||||
+ cancelled = cancel;
|
||||
+ }
|
||||
+}
|
|
@ -0,0 +1,78 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Fri, 19 Jan 2018 00:29:28 -0500
|
||||
Subject: [PATCH] Add setPlayerProfile API for Skulls
|
||||
|
||||
This allows you to create already filled textures on Skulls to avoid texture lookups
|
||||
which commonly cause rate limit issues with Mojang API
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/block/Skull.java b/src/main/java/org/bukkit/block/Skull.java
|
||||
index 943d751fb3e48212fbe258845beba03c25fa22d9..a6914f01e01e9103702185f92b0209b3c84c152a 100644
|
||||
--- a/src/main/java/org/bukkit/block/Skull.java
|
||||
+++ b/src/main/java/org/bukkit/block/Skull.java
|
||||
@@ -7,6 +7,7 @@ import org.bukkit.block.data.BlockData;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
+import com.destroystokyo.paper.profile.PlayerProfile; // Paper
|
||||
|
||||
/**
|
||||
* Represents a captured state of a skull block.
|
||||
@@ -61,6 +62,20 @@ public interface Skull extends TileState {
|
||||
*/
|
||||
public void setOwningPlayer(@NotNull OfflinePlayer player);
|
||||
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Sets this skull to use the supplied Player Profile, which can include textures already prefilled.
|
||||
+ * @param profile The profile to set this Skull to use, may not be null
|
||||
+ */
|
||||
+ void setPlayerProfile(@NotNull PlayerProfile profile);
|
||||
+
|
||||
+ /**
|
||||
+ * If the skull has an owner, per {@link #hasOwner()}, return the owners {@link PlayerProfile}
|
||||
+ * @return The profile of the owner, if set
|
||||
+ */
|
||||
+ @Nullable PlayerProfile getPlayerProfile();
|
||||
+ // Paper end
|
||||
+
|
||||
/**
|
||||
* Gets the rotation of the skull in the world (or facing direction if this
|
||||
* is a wall mounted skull).
|
||||
diff --git a/src/main/java/org/bukkit/inventory/meta/SkullMeta.java b/src/main/java/org/bukkit/inventory/meta/SkullMeta.java
|
||||
index 496254f959345d74167a9b44d160ea1bb428c5a1..88d1c889c09adb91abb09a8e43a30c871b217da2 100644
|
||||
--- a/src/main/java/org/bukkit/inventory/meta/SkullMeta.java
|
||||
+++ b/src/main/java/org/bukkit/inventory/meta/SkullMeta.java
|
||||
@@ -1,9 +1,11 @@
|
||||
package org.bukkit.inventory.meta;
|
||||
|
||||
+import com.destroystokyo.paper.profile.PlayerProfile;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
+
|
||||
/**
|
||||
* Represents a skull that can have an owner.
|
||||
*/
|
||||
@@ -36,6 +38,20 @@ public interface SkullMeta extends ItemMeta {
|
||||
@Deprecated
|
||||
boolean setOwner(@Nullable String owner);
|
||||
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Sets this skull to use the supplied Player Profile, which can include textures already prefilled.
|
||||
+ * @param profile The profile to set this Skull to use, or null to clear owner
|
||||
+ */
|
||||
+ void setPlayerProfile(@Nullable PlayerProfile profile);
|
||||
+
|
||||
+ /**
|
||||
+ * If the skull has an owner, per {@link #hasOwner()}, return the owners {@link PlayerProfile}
|
||||
+ * @return The profile of the owner, if set
|
||||
+ */
|
||||
+ @Nullable PlayerProfile getPlayerProfile();
|
||||
+ // Paper end
|
||||
+
|
||||
/**
|
||||
* Gets the owner of the skull.
|
||||
*
|
176
patches/unapplied/api/0083-Fill-Profile-Property-Events.patch
Normal file
176
patches/unapplied/api/0083-Fill-Profile-Property-Events.patch
Normal file
|
@ -0,0 +1,176 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 2 Jan 2018 00:31:08 -0500
|
||||
Subject: [PATCH] Fill Profile Property Events
|
||||
|
||||
Allows plugins to populate profile properties from local sources to avoid calls out to Mojang API
|
||||
to fill in textures for example.
|
||||
|
||||
If Mojang API does need to be hit, event fire so you can get the results.
|
||||
|
||||
This is useful for implementing a ProfileCache for Player Skulls
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/profile/FillProfileEvent.java b/src/main/java/com/destroystokyo/paper/event/profile/FillProfileEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..71f36e9cae209ec6861835a5e76e018de959040a
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/profile/FillProfileEvent.java
|
||||
@@ -0,0 +1,75 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2018 Daniel Ennis (Aikar) MIT License
|
||||
+ *
|
||||
+ * Permission is hereby granted, free of charge, to any person obtaining
|
||||
+ * a copy of this software and associated documentation files (the
|
||||
+ * "Software"), to deal in the Software without restriction, including
|
||||
+ * without limitation the rights to use, copy, modify, merge, publish,
|
||||
+ * distribute, sublicense, and/or sell copies of the Software, and to
|
||||
+ * permit persons to whom the Software is furnished to do so, subject to
|
||||
+ * the following conditions:
|
||||
+ *
|
||||
+ * The above copyright notice and this permission notice shall be
|
||||
+ * included in all copies or substantial portions of the Software.
|
||||
+ *
|
||||
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
+ */
|
||||
+
|
||||
+package com.destroystokyo.paper.event.profile;
|
||||
+
|
||||
+import com.destroystokyo.paper.profile.PlayerProfile;
|
||||
+import com.destroystokyo.paper.profile.ProfileProperty;
|
||||
+import org.bukkit.event.Event;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+
|
||||
+import java.util.Set;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * Fired once a profiles additional properties (such as textures) has been filled
|
||||
+ */
|
||||
+public class FillProfileEvent extends Event {
|
||||
+ @NotNull private final PlayerProfile profile;
|
||||
+
|
||||
+ public FillProfileEvent(@NotNull PlayerProfile profile) {
|
||||
+ super(!org.bukkit.Bukkit.isPrimaryThread());
|
||||
+ this.profile = profile;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return The Profile that had properties filled
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public PlayerProfile getPlayerProfile() {
|
||||
+ return profile;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Same as .getPlayerProfile().getProperties()
|
||||
+ *
|
||||
+ * @see PlayerProfile#getProperties()
|
||||
+ * @return The new properties on the profile.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Set<ProfileProperty> getProperties() {
|
||||
+ return profile.getProperties();
|
||||
+ }
|
||||
+
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+
|
||||
+ @NotNull
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/profile/PreFillProfileEvent.java b/src/main/java/com/destroystokyo/paper/event/profile/PreFillProfileEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..021bc86310a06f84b39459e0eb8927802726399c
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/profile/PreFillProfileEvent.java
|
||||
@@ -0,0 +1,77 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2018 Daniel Ennis (Aikar) MIT License
|
||||
+ *
|
||||
+ * Permission is hereby granted, free of charge, to any person obtaining
|
||||
+ * a copy of this software and associated documentation files (the
|
||||
+ * "Software"), to deal in the Software without restriction, including
|
||||
+ * without limitation the rights to use, copy, modify, merge, publish,
|
||||
+ * distribute, sublicense, and/or sell copies of the Software, and to
|
||||
+ * permit persons to whom the Software is furnished to do so, subject to
|
||||
+ * the following conditions:
|
||||
+ *
|
||||
+ * The above copyright notice and this permission notice shall be
|
||||
+ * included in all copies or substantial portions of the Software.
|
||||
+ *
|
||||
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
+ */
|
||||
+
|
||||
+package com.destroystokyo.paper.event.profile;
|
||||
+
|
||||
+import com.destroystokyo.paper.profile.PlayerProfile;
|
||||
+import com.destroystokyo.paper.profile.ProfileProperty;
|
||||
+import org.bukkit.event.Event;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+
|
||||
+import java.util.Collection;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * Fired when the server is requesting to fill in properties of an incomplete profile, such as textures.
|
||||
+ *
|
||||
+ * Allows plugins to pre populate cached properties and avoid a call to the Mojang API
|
||||
+ */
|
||||
+public class PreFillProfileEvent extends Event {
|
||||
+ @NotNull private final PlayerProfile profile;
|
||||
+
|
||||
+ public PreFillProfileEvent(@NotNull PlayerProfile profile) {
|
||||
+ super(!org.bukkit.Bukkit.isPrimaryThread());
|
||||
+ this.profile = profile;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return The profile that needs its properties filled
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public PlayerProfile getPlayerProfile() {
|
||||
+ return profile;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the properties on the profile, avoiding the call to the Mojang API
|
||||
+ * Same as .getPlayerProfile().setProperties(properties);
|
||||
+ *
|
||||
+ * @see PlayerProfile#setProperties(Collection)
|
||||
+ * @param properties The properties to set/append
|
||||
+ */
|
||||
+ public void setProperties(@NotNull Collection<ProfileProperty> properties) {
|
||||
+ profile.setProperties(properties);
|
||||
+ }
|
||||
+
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+
|
||||
+ @NotNull
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+}
|
|
@ -0,0 +1,75 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Fri, 19 Jan 2018 08:15:14 -0600
|
||||
Subject: [PATCH] PlayerAdvancementCriterionGrantEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/player/PlayerAdvancementCriterionGrantEvent.java b/src/main/java/com/destroystokyo/paper/event/player/PlayerAdvancementCriterionGrantEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..bb8d7c959cdea4b66455a49e74804ea4b126620d
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/player/PlayerAdvancementCriterionGrantEvent.java
|
||||
@@ -0,0 +1,63 @@
|
||||
+package com.destroystokyo.paper.event.player;
|
||||
+
|
||||
+import org.bukkit.advancement.Advancement;
|
||||
+import org.bukkit.entity.Player;
|
||||
+import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.player.PlayerEvent;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * Called when a player is granted a criteria in an advancement.
|
||||
+ */
|
||||
+public class PlayerAdvancementCriterionGrantEvent extends PlayerEvent implements Cancellable {
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+ @NotNull private final Advancement advancement;
|
||||
+ @NotNull private final String criterion;
|
||||
+ private boolean cancel = false;
|
||||
+
|
||||
+ public PlayerAdvancementCriterionGrantEvent(@NotNull Player who, @NotNull Advancement advancement, @NotNull String criterion) {
|
||||
+ super(who);
|
||||
+ this.advancement = advancement;
|
||||
+ this.criterion = criterion;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Get the advancement which has been affected.
|
||||
+ *
|
||||
+ * @return affected advancement
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Advancement getAdvancement() {
|
||||
+ return advancement;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Get the criterion which has been granted.
|
||||
+ *
|
||||
+ * @return granted criterion
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public String getCriterion() {
|
||||
+ return criterion;
|
||||
+ }
|
||||
+
|
||||
+ public boolean isCancelled() {
|
||||
+ return cancel;
|
||||
+ }
|
||||
+
|
||||
+ public void setCancelled(boolean cancel) {
|
||||
+ this.cancel = cancel;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+}
|
96
patches/unapplied/api/0085-Add-ArmorStand-Item-Meta.patch
Normal file
96
patches/unapplied/api/0085-Add-ArmorStand-Item-Meta.patch
Normal file
|
@ -0,0 +1,96 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <zach.brown@destroystokyo.com>
|
||||
Date: Sat, 27 Jan 2018 17:06:24 -0500
|
||||
Subject: [PATCH] Add ArmorStand Item Meta
|
||||
|
||||
This is adds basic item meta for armor stands. It does not add all
|
||||
possible metadata however.
|
||||
|
||||
There are armor, hand, and equipment types, as well as position data
|
||||
that can also be added here. This initial addition should serve a
|
||||
starting point for future additions in this area.
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/inventory/meta/ArmorStandMeta.java b/src/main/java/com/destroystokyo/paper/inventory/meta/ArmorStandMeta.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..7e4acfff16db80a75e1ff2fee1972b16955b0918
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/inventory/meta/ArmorStandMeta.java
|
||||
@@ -0,0 +1,78 @@
|
||||
+package com.destroystokyo.paper.inventory.meta;
|
||||
+
|
||||
+import org.bukkit.inventory.meta.ItemMeta;
|
||||
+
|
||||
+public interface ArmorStandMeta extends ItemMeta {
|
||||
+
|
||||
+ /**
|
||||
+ * Gets whether the ArmorStand should be invisible when spawned
|
||||
+ *
|
||||
+ * @return true if this should be invisible
|
||||
+ */
|
||||
+ boolean isInvisible();
|
||||
+
|
||||
+ /**
|
||||
+ * Gets whether this ArmorStand should have no base plate when spawned
|
||||
+ *
|
||||
+ * @return true if it will not have a base plate
|
||||
+ */
|
||||
+ boolean hasNoBasePlate();
|
||||
+
|
||||
+ /**
|
||||
+ * Gets whether this ArmorStand should show arms when spawned
|
||||
+ *
|
||||
+ * @return true if it will show arms
|
||||
+ */
|
||||
+ boolean shouldShowArms();
|
||||
+
|
||||
+ /**
|
||||
+ * Gets whether this ArmorStand will be small when spawned
|
||||
+ *
|
||||
+ * @return true if it will be small
|
||||
+ */
|
||||
+ boolean isSmall();
|
||||
+
|
||||
+ /**
|
||||
+ * Gets whether this ArmorStand will be a marker when spawned
|
||||
+ * The exact details of this flag are an implementation detail
|
||||
+ *
|
||||
+ * @return true if it will be a marker
|
||||
+ */
|
||||
+ boolean isMarker();
|
||||
+
|
||||
+ /**
|
||||
+ * Sets that this ArmorStand should be invisible when spawned
|
||||
+ *
|
||||
+ * @param invisible true if set invisible
|
||||
+ */
|
||||
+ void setInvisible(boolean invisible);
|
||||
+
|
||||
+ /**
|
||||
+ * Sets that this ArmorStand should have no base plate when spawned
|
||||
+ *
|
||||
+ * @param noBasePlate true if no base plate
|
||||
+ */
|
||||
+ void setNoBasePlate(boolean noBasePlate);
|
||||
+
|
||||
+ /**
|
||||
+ * Sets that this ArmorStand should show arms when spawned
|
||||
+ *
|
||||
+ * @param showArms true if show arms
|
||||
+ */
|
||||
+ void setShowArms(boolean showArms);
|
||||
+
|
||||
+ /**
|
||||
+ * Sets that this ArmorStand should be small when spawned
|
||||
+ *
|
||||
+ * @param small true if small
|
||||
+ */
|
||||
+ void setSmall(boolean small);
|
||||
+
|
||||
+ /**
|
||||
+ * Sets that this ArmorStand should be a marker when spawned
|
||||
+ * The exact details of this flag are an implementation detail
|
||||
+ *
|
||||
+ * @param marker true if a marker
|
||||
+ */
|
||||
+ void setMarker(boolean marker);
|
||||
+}
|
39
patches/unapplied/api/0086-Optimize-Hoppers.patch
Normal file
39
patches/unapplied/api/0086-Optimize-Hoppers.patch
Normal file
|
@ -0,0 +1,39 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Thu, 18 Jan 2018 01:00:27 -0500
|
||||
Subject: [PATCH] Optimize Hoppers
|
||||
|
||||
Adds data about what Item related methods were used in InventoryMoveItem event
|
||||
so that the server can improve the performance of this event.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/event/inventory/InventoryMoveItemEvent.java b/src/main/java/org/bukkit/event/inventory/InventoryMoveItemEvent.java
|
||||
index a8c48f5a416326e96c431e5fa22edee04825530e..04d4a83bfc4f86341f9d72128458154d08c8ec43 100644
|
||||
--- a/src/main/java/org/bukkit/event/inventory/InventoryMoveItemEvent.java
|
||||
+++ b/src/main/java/org/bukkit/event/inventory/InventoryMoveItemEvent.java
|
||||
@@ -31,6 +31,8 @@ public class InventoryMoveItemEvent extends Event implements Cancellable {
|
||||
private final Inventory destinationInventory;
|
||||
private ItemStack itemStack;
|
||||
private final boolean didSourceInitiate;
|
||||
+ public boolean calledGetItem; // Paper
|
||||
+ public boolean calledSetItem; // Paper
|
||||
|
||||
public InventoryMoveItemEvent(@NotNull final Inventory sourceInventory, @NotNull final ItemStack itemStack, @NotNull final Inventory destinationInventory, final boolean didSourceInitiate) {
|
||||
Validate.notNull(itemStack, "ItemStack cannot be null");
|
||||
@@ -58,7 +60,8 @@ public class InventoryMoveItemEvent extends Event implements Cancellable {
|
||||
*/
|
||||
@NotNull
|
||||
public ItemStack getItem() {
|
||||
- return itemStack.clone();
|
||||
+ calledGetItem = true; // Paper - record this method was used for auto detection of mode
|
||||
+ return itemStack; // Paper - Removed clone, handled better in Server
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -70,6 +73,7 @@ public class InventoryMoveItemEvent extends Event implements Cancellable {
|
||||
*/
|
||||
public void setItem(@NotNull ItemStack itemStack) {
|
||||
Validate.notNull(itemStack, "ItemStack cannot be null. Cancel the event if you want nothing to be transferred.");
|
||||
+ calledSetItem = true; // Paper - record this method was used for auto detection of mode
|
||||
this.itemStack = itemStack.clone();
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sat, 24 Feb 2018 00:55:52 -0500
|
||||
Subject: [PATCH] Tameable#getOwnerUniqueId API
|
||||
|
||||
This is faster if all you need is the UUID, as .getOwner() will cause
|
||||
an OfflinePlayer to be loaded from disk.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/entity/Tameable.java b/src/main/java/org/bukkit/entity/Tameable.java
|
||||
index 26c996cd41acc88490ac0135a9239cffc03e8efb..65e68da98ab66ed781bce2f0dbe0913be48d2990 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Tameable.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Tameable.java
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.bukkit.entity;
|
||||
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public interface Tameable extends Animals {
|
||||
@@ -25,9 +26,22 @@ public interface Tameable extends Animals {
|
||||
*/
|
||||
public void setTamed(boolean tame);
|
||||
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Gets the owners UUID
|
||||
+ *
|
||||
+ * @return the owners UUID, or null if not owned
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public java.util.UUID getOwnerUniqueId();
|
||||
+ // Paper end
|
||||
+
|
||||
/**
|
||||
* Gets the current owning AnimalTamer
|
||||
*
|
||||
+ * @see #getOwnerUniqueId() Recommended to use UUID version instead of this for performance.
|
||||
+ * This method will cause OfflinePlayer to be loaded from disk if the owner is not online.
|
||||
+ *
|
||||
* @return the owning AnimalTamer, or null if not owned
|
||||
*/
|
||||
@Nullable
|
|
@ -0,0 +1,91 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sun, 18 Mar 2018 11:43:30 -0400
|
||||
Subject: [PATCH] Ability to change PlayerProfile in AsyncPreLoginEvent
|
||||
|
||||
This will allow you to change the players name or skin on login.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/event/player/AsyncPlayerPreLoginEvent.java b/src/main/java/org/bukkit/event/player/AsyncPlayerPreLoginEvent.java
|
||||
index 31f6f781a0403bf6388d668f0effaed5aae94468..25e0d571710403c334bd73ce1b97109dd65c3244 100644
|
||||
--- a/src/main/java/org/bukkit/event/player/AsyncPlayerPreLoginEvent.java
|
||||
+++ b/src/main/java/org/bukkit/event/player/AsyncPlayerPreLoginEvent.java
|
||||
@@ -2,6 +2,9 @@ package org.bukkit.event.player;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.util.UUID;
|
||||
+
|
||||
+import com.destroystokyo.paper.profile.PlayerProfile;
|
||||
+import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -15,9 +18,9 @@ public class AsyncPlayerPreLoginEvent extends Event {
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
private Result result;
|
||||
private net.kyori.adventure.text.Component message; // Paper
|
||||
- private final String name;
|
||||
+ //private String name; // Paper - Not used anymore
|
||||
private final InetAddress ipAddress;
|
||||
- private final UUID uniqueId;
|
||||
+ //private UUID uniqueId; // Paper - Not used anymore
|
||||
|
||||
@Deprecated
|
||||
public AsyncPlayerPreLoginEvent(@NotNull final String name, @NotNull final InetAddress ipAddress) {
|
||||
@@ -25,12 +28,37 @@ public class AsyncPlayerPreLoginEvent extends Event {
|
||||
}
|
||||
|
||||
public AsyncPlayerPreLoginEvent(@NotNull final String name, @NotNull final InetAddress ipAddress, @NotNull final UUID uniqueId) {
|
||||
+ // Paper start
|
||||
+ this(name, ipAddress, uniqueId, Bukkit.createProfile(uniqueId, name));
|
||||
+ }
|
||||
+ private PlayerProfile profile;
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the PlayerProfile of the player logging in
|
||||
+ * @return The Profile
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public PlayerProfile getPlayerProfile() {
|
||||
+ return profile;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Changes the PlayerProfile the player will login as
|
||||
+ * @param profile The profile to use
|
||||
+ */
|
||||
+ public void setPlayerProfile(@NotNull PlayerProfile profile) {
|
||||
+ this.profile = profile;
|
||||
+ }
|
||||
+
|
||||
+ public AsyncPlayerPreLoginEvent(@NotNull final String name, @NotNull final InetAddress ipAddress, @NotNull final UUID uniqueId, @NotNull PlayerProfile profile) {
|
||||
super(true);
|
||||
+ this.profile = profile;
|
||||
+ // Paper end
|
||||
this.result = Result.ALLOWED;
|
||||
this.message = net.kyori.adventure.text.Component.empty(); // Paper
|
||||
- this.name = name;
|
||||
+ //this.name = name; // Paper - Not used anymore
|
||||
this.ipAddress = ipAddress;
|
||||
- this.uniqueId = uniqueId;
|
||||
+ //this.uniqueId = uniqueId; // Paper - Not used anymore
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -193,7 +221,7 @@ public class AsyncPlayerPreLoginEvent extends Event {
|
||||
*/
|
||||
@NotNull
|
||||
public String getName() {
|
||||
- return name;
|
||||
+ return profile.getName(); // Paper
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -213,7 +241,7 @@ public class AsyncPlayerPreLoginEvent extends Event {
|
||||
*/
|
||||
@NotNull
|
||||
public UUID getUniqueId() {
|
||||
- return uniqueId;
|
||||
+ return profile.getId(); // Paper
|
||||
}
|
||||
|
||||
@NotNull
|
|
@ -0,0 +1,381 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Minecrell <minecrell@minecrell.net>
|
||||
Date: Wed, 11 Oct 2017 15:55:38 +0200
|
||||
Subject: [PATCH] Add extended PaperServerListPingEvent
|
||||
|
||||
Add a new event that extends the original ServerListPingEvent
|
||||
and allows full control of the response sent to the client.
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/server/PaperServerListPingEvent.java b/src/main/java/com/destroystokyo/paper/event/server/PaperServerListPingEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..baac2e4f090a490372ef4aed92c8a5771955e921
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/server/PaperServerListPingEvent.java
|
||||
@@ -0,0 +1,334 @@
|
||||
+package com.destroystokyo.paper.event.server;
|
||||
+
|
||||
+import static java.util.Objects.requireNonNull;
|
||||
+
|
||||
+import com.destroystokyo.paper.network.StatusClient;
|
||||
+import com.destroystokyo.paper.profile.PlayerProfile;
|
||||
+import org.bukkit.Bukkit;
|
||||
+import org.bukkit.entity.Player;
|
||||
+import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.event.server.ServerListPingEvent;
|
||||
+import org.bukkit.util.CachedServerIcon;
|
||||
+
|
||||
+import java.util.ArrayList;
|
||||
+import java.util.Iterator;
|
||||
+import java.util.List;
|
||||
+import java.util.NoSuchElementException;
|
||||
+import java.util.UUID;
|
||||
+
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
+
|
||||
+/**
|
||||
+ * Extended version of {@link ServerListPingEvent} that allows full control
|
||||
+ * of the response sent to the client.
|
||||
+ */
|
||||
+public class PaperServerListPingEvent extends ServerListPingEvent implements Cancellable {
|
||||
+
|
||||
+ @NotNull private final StatusClient client;
|
||||
+
|
||||
+ private int numPlayers;
|
||||
+ private boolean hidePlayers;
|
||||
+ @NotNull private final List<PlayerProfile> playerSample = new ArrayList<>();
|
||||
+
|
||||
+ @NotNull private String version;
|
||||
+ private int protocolVersion;
|
||||
+
|
||||
+ @Nullable private CachedServerIcon favicon;
|
||||
+
|
||||
+ private boolean cancelled;
|
||||
+
|
||||
+ private boolean originalPlayerCount = true;
|
||||
+ private Object[] players;
|
||||
+
|
||||
+ @Deprecated
|
||||
+ public PaperServerListPingEvent(@NotNull StatusClient client, @NotNull String motd, int numPlayers, int maxPlayers,
|
||||
+ @NotNull String version, int protocolVersion, @Nullable CachedServerIcon favicon) {
|
||||
+ super(client.getAddress().getAddress(), motd, numPlayers, maxPlayers);
|
||||
+ this.client = client;
|
||||
+ this.numPlayers = numPlayers;
|
||||
+ this.version = version;
|
||||
+ this.protocolVersion = protocolVersion;
|
||||
+ setServerIcon(favicon);
|
||||
+ }
|
||||
+
|
||||
+ public PaperServerListPingEvent(@NotNull StatusClient client, @NotNull net.kyori.adventure.text.Component motd, int numPlayers, int maxPlayers,
|
||||
+ @NotNull String version, int protocolVersion, @Nullable CachedServerIcon favicon) {
|
||||
+ super(client.getAddress().getAddress(), motd, numPlayers, maxPlayers);
|
||||
+ this.client = client;
|
||||
+ this.numPlayers = numPlayers;
|
||||
+ this.version = version;
|
||||
+ this.protocolVersion = protocolVersion;
|
||||
+ setServerIcon(favicon);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Returns the {@link StatusClient} pinging the server.
|
||||
+ *
|
||||
+ * @return The client
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public StatusClient getClient() {
|
||||
+ return this.client;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * {@inheritDoc}
|
||||
+ *
|
||||
+ * <p>Returns {@code -1} if players are hidden using
|
||||
+ * {@link #shouldHidePlayers()}.</p>
|
||||
+ */
|
||||
+ @Override
|
||||
+ public int getNumPlayers() {
|
||||
+ if (this.hidePlayers) {
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ return this.numPlayers;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the number of players displayed in the server list.
|
||||
+ *
|
||||
+ * <p>Note that this won't have any effect if {@link #shouldHidePlayers()}
|
||||
+ * is enabled.</p>
|
||||
+ *
|
||||
+ * @param numPlayers The number of online players
|
||||
+ */
|
||||
+ public void setNumPlayers(int numPlayers) {
|
||||
+ if (this.numPlayers != numPlayers) {
|
||||
+ this.numPlayers = numPlayers;
|
||||
+ this.originalPlayerCount = false;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * {@inheritDoc}
|
||||
+ *
|
||||
+ * <p>Returns {@code -1} if players are hidden using
|
||||
+ * {@link #shouldHidePlayers()}.</p>
|
||||
+ */
|
||||
+ @Override
|
||||
+ public int getMaxPlayers() {
|
||||
+ if (this.hidePlayers) {
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ return super.getMaxPlayers();
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Returns whether all player related information is hidden in the server
|
||||
+ * list. This will cause {@link #getNumPlayers()}, {@link #getMaxPlayers()}
|
||||
+ * and {@link #getPlayerSample()} to be skipped in the response.
|
||||
+ *
|
||||
+ * <p>The Vanilla Minecraft client will display the player count as {@code ???}
|
||||
+ * when this option is enabled.</p>
|
||||
+ *
|
||||
+ * @return {@code true} if the player count is hidden
|
||||
+ */
|
||||
+ public boolean shouldHidePlayers() {
|
||||
+ return hidePlayers;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets whether all player related information is hidden in the server
|
||||
+ * list. This will cause {@link #getNumPlayers()}, {@link #getMaxPlayers()}
|
||||
+ * and {@link #getPlayerSample()} to be skipped in the response.
|
||||
+ *
|
||||
+ * <p>The Vanilla Minecraft client will display the player count as {@code ???}
|
||||
+ * when this option is enabled.</p>
|
||||
+ *
|
||||
+ * @param hidePlayers {@code true} if the player count should be hidden
|
||||
+ */
|
||||
+ public void setHidePlayers(boolean hidePlayers) {
|
||||
+ this.hidePlayers = hidePlayers;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Returns a mutable list of {@link PlayerProfile} that will be displayed
|
||||
+ * as online players on the client.
|
||||
+ *
|
||||
+ * <p>The Vanilla Minecraft client will display them when hovering the
|
||||
+ * player count with the mouse.</p>
|
||||
+ *
|
||||
+ * @return The mutable player sample list
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public List<PlayerProfile> getPlayerSample() {
|
||||
+ return this.playerSample;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Returns the version that will be sent as server version on the client.
|
||||
+ *
|
||||
+ * @return The server version
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public String getVersion() {
|
||||
+ return version;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the version that will be sent as server version to the client.
|
||||
+ *
|
||||
+ * @param version The server version
|
||||
+ */
|
||||
+ public void setVersion(@NotNull String version) {
|
||||
+ this.version = requireNonNull(version, "version");
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Returns the protocol version that will be sent as the protocol version
|
||||
+ * of the server to the client.
|
||||
+ *
|
||||
+ * @return The protocol version of the server, or {@code -1} if the server
|
||||
+ * has not finished initialization yet
|
||||
+ */
|
||||
+ public int getProtocolVersion() {
|
||||
+ return protocolVersion;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the protocol version that will be sent as the protocol version
|
||||
+ * of the server to the client.
|
||||
+ *
|
||||
+ * @param protocolVersion The protocol version of the server
|
||||
+ */
|
||||
+ public void setProtocolVersion(int protocolVersion) {
|
||||
+ this.protocolVersion = protocolVersion;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the server icon sent to the client.
|
||||
+ *
|
||||
+ * @return The icon to send to the client, or {@code null} for none
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public CachedServerIcon getServerIcon() {
|
||||
+ return this.favicon;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the server icon sent to the client.
|
||||
+ *
|
||||
+ * @param icon The icon to send to the client, or {@code null} for none
|
||||
+ */
|
||||
+ @Override
|
||||
+ public void setServerIcon(@Nullable CachedServerIcon icon) {
|
||||
+ if (icon != null && icon.isEmpty()) {
|
||||
+ // Represent empty icons as null
|
||||
+ icon = null;
|
||||
+ }
|
||||
+
|
||||
+ this.favicon = icon;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * {@inheritDoc}
|
||||
+ *
|
||||
+ * <p>Cancelling this event will cause the connection to be closed immediately,
|
||||
+ * without sending a response to the client.</p>
|
||||
+ */
|
||||
+ @Override
|
||||
+ public boolean isCancelled() {
|
||||
+ return this.cancelled;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * {@inheritDoc}
|
||||
+ *
|
||||
+ * <p>Cancelling this event will cause the connection to be closed immediately,
|
||||
+ * without sending a response to the client.</p>
|
||||
+ */
|
||||
+ @Override
|
||||
+ public void setCancelled(boolean cancel) {
|
||||
+ this.cancelled = cancel;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * {@inheritDoc}
|
||||
+ *
|
||||
+ * <p><b>Note:</b> For compatibility reasons, this method will return all
|
||||
+ * online players, not just the ones referenced in {@link #getPlayerSample()}.
|
||||
+ * Removing a player will:</p>
|
||||
+ *
|
||||
+ * <ul>
|
||||
+ * <li>Decrement the online player count (if and only if) the player
|
||||
+ * count wasn't changed by another plugin before.</li>
|
||||
+ * <li>Remove all entries from {@link #getPlayerSample()} that refer to
|
||||
+ * the removed player (based on their {@link UUID}).</li>
|
||||
+ * </ul>
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public Iterator<Player> iterator() {
|
||||
+ if (this.players == null) {
|
||||
+ this.players = getOnlinePlayers();
|
||||
+ }
|
||||
+
|
||||
+ return new PlayerIterator();
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ protected Object[] getOnlinePlayers() {
|
||||
+ return Bukkit.getOnlinePlayers().toArray();
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ protected Player getBukkitPlayer(@NotNull Object player) {
|
||||
+ return (Player) player;
|
||||
+ }
|
||||
+
|
||||
+ private final class PlayerIterator implements Iterator<Player> {
|
||||
+
|
||||
+ private int next;
|
||||
+ private int current;
|
||||
+ @Nullable private Player player;
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean hasNext() {
|
||||
+ for (; this.next < players.length; this.next++) {
|
||||
+ if (players[this.next] != null) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public Player next() {
|
||||
+ if (!hasNext()) {
|
||||
+ this.player = null;
|
||||
+ throw new NoSuchElementException();
|
||||
+ }
|
||||
+
|
||||
+ this.current = this.next++;
|
||||
+ return this.player = getBukkitPlayer(players[this.current]);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void remove() {
|
||||
+ if (this.player == null) {
|
||||
+ throw new IllegalStateException();
|
||||
+ }
|
||||
+
|
||||
+ UUID uniqueId = this.player.getUniqueId();
|
||||
+ this.player = null;
|
||||
+
|
||||
+ // Remove player from iterator
|
||||
+ players[this.current] = null;
|
||||
+
|
||||
+ // Remove player from sample
|
||||
+ getPlayerSample().removeIf(p -> uniqueId.equals(p.getId()));
|
||||
+
|
||||
+ // Decrement player count
|
||||
+ if (originalPlayerCount) {
|
||||
+ numPlayers--;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/network/StatusClient.java b/src/main/java/com/destroystokyo/paper/network/StatusClient.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..517d15238ed117f38bbd39f570874014cecf7bb5
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/network/StatusClient.java
|
||||
@@ -0,0 +1,13 @@
|
||||
+package com.destroystokyo.paper.network;
|
||||
+
|
||||
+import com.destroystokyo.paper.event.server.PaperServerListPingEvent;
|
||||
+
|
||||
+/**
|
||||
+ * Represents a client requesting the current status from the server (e.g. from
|
||||
+ * the server list).
|
||||
+ *
|
||||
+ * @see PaperServerListPingEvent
|
||||
+ */
|
||||
+public interface StatusClient extends NetworkClient {
|
||||
+
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/util/CachedServerIcon.java b/src/main/java/org/bukkit/util/CachedServerIcon.java
|
||||
index 612958a331575d1da2715531ebdf6b1168f2e860..bb4f7702ced0baf0670a7a21d48ad528b7249361 100644
|
||||
--- a/src/main/java/org/bukkit/util/CachedServerIcon.java
|
||||
+++ b/src/main/java/org/bukkit/util/CachedServerIcon.java
|
||||
@@ -18,4 +18,9 @@ public interface CachedServerIcon {
|
||||
@Nullable
|
||||
public String getData(); // Paper
|
||||
|
||||
+ // Paper start
|
||||
+ default boolean isEmpty() {
|
||||
+ return getData() == null;
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
40
patches/unapplied/api/0090-Player.setPlayerProfile-API.patch
Normal file
40
patches/unapplied/api/0090-Player.setPlayerProfile-API.patch
Normal file
|
@ -0,0 +1,40 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sun, 18 Mar 2018 12:28:55 -0400
|
||||
Subject: [PATCH] Player.setPlayerProfile API
|
||||
|
||||
This can be useful for changing name or skins after a player has logged in.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java
|
||||
index 8d5ddb1451ea1d7a7a5c9eefb843a4adb885d20e..0dabd6f69e85b21f7ec6e6a2ac46d7fc58af24f6 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Player.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Player.java
|
||||
@@ -4,6 +4,7 @@ import java.net.InetSocketAddress;
|
||||
import java.util.UUID;
|
||||
import com.destroystokyo.paper.Title; // Paper
|
||||
import net.kyori.adventure.text.Component;
|
||||
+import com.destroystokyo.paper.profile.PlayerProfile; // Paper
|
||||
import org.bukkit.DyeColor;
|
||||
import org.bukkit.Effect;
|
||||
import org.bukkit.GameMode;
|
||||
@@ -1914,6 +1915,20 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
|
||||
* was {@link org.bukkit.event.player.PlayerResourcePackStatusEvent.Status#SUCCESSFULLY_LOADED}
|
||||
*/
|
||||
boolean hasResourcePack();
|
||||
+
|
||||
+ /**
|
||||
+ * Gets a copy of this players profile
|
||||
+ * @return The players profile object
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ PlayerProfile getPlayerProfile();
|
||||
+
|
||||
+ /**
|
||||
+ * Changes the PlayerProfile for this player. This will cause this player
|
||||
+ * to be reregistered to all clients that can currently see this player
|
||||
+ * @param profile The new profile to use
|
||||
+ */
|
||||
+ void setPlayerProfile(@NotNull PlayerProfile profile);
|
||||
// Paper end
|
||||
|
||||
// Spigot start
|
58
patches/unapplied/api/0091-getPlayerUniqueId-API.patch
Normal file
58
patches/unapplied/api/0091-getPlayerUniqueId-API.patch
Normal file
|
@ -0,0 +1,58 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Thu, 22 Mar 2018 01:39:28 -0400
|
||||
Subject: [PATCH] getPlayerUniqueId API
|
||||
|
||||
Gets the unique ID of the player currently known as the specified player name
|
||||
In Offline Mode, will return an Offline UUID
|
||||
|
||||
This is a more performant way to obtain a UUID for a name than loading an OfflinePlayer
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
|
||||
index befd34cfdd37451532f14feeba5e728d3f86751a..c85fc0cb1c4927fe637f20a4e2499bce7707d633 100644
|
||||
--- a/src/main/java/org/bukkit/Bukkit.java
|
||||
+++ b/src/main/java/org/bukkit/Bukkit.java
|
||||
@@ -559,6 +559,20 @@ public final class Bukkit {
|
||||
return server.getPlayer(id);
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Gets the unique ID of the player currently known as the specified player name
|
||||
+ * In Offline Mode, will return an Offline UUID
|
||||
+ *
|
||||
+ * @param playerName the player name to look up the unique ID for
|
||||
+ * @return A UUID, or null if that player name is not registered with Minecraft and the server is in online mode
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public static UUID getPlayerUniqueId(@NotNull String playerName) {
|
||||
+ return server.getPlayerUniqueId(playerName);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
/**
|
||||
* Gets the plugin manager for interfacing with plugins.
|
||||
*
|
||||
diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
|
||||
index 89fc36a73b8ae26f19b06cb0f9376ec33724b939..1a80dad1fa0bf3f33f5669f846912092132f8d64 100644
|
||||
--- a/src/main/java/org/bukkit/Server.java
|
||||
+++ b/src/main/java/org/bukkit/Server.java
|
||||
@@ -477,6 +477,18 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
|
||||
@Nullable
|
||||
public Player getPlayer(@NotNull UUID id);
|
||||
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Gets the unique ID of the player currently known as the specified player name
|
||||
+ * In Offline Mode, will return an Offline UUID
|
||||
+ *
|
||||
+ * @param playerName the player name to look up the unique ID for
|
||||
+ * @return A UUID, or null if that player name is not registered with Minecraft and the server is in online mode
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public UUID getPlayerUniqueId(@NotNull String playerName);
|
||||
+ // Paper end
|
||||
+
|
||||
/**
|
||||
* Gets the plugin manager for interfacing with plugins.
|
||||
*
|
|
@ -0,0 +1,30 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Minecrell <minecrell@minecrell.net>
|
||||
Date: Wed, 11 Oct 2017 19:30:20 +0200
|
||||
Subject: [PATCH] Add legacy ping support to PaperServerListPingEvent
|
||||
|
||||
Add a new method to StatusClient check if the client is a legacy
|
||||
client that does not support all of the features provided in the
|
||||
event.
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/network/StatusClient.java b/src/main/java/com/destroystokyo/paper/network/StatusClient.java
|
||||
index 517d15238ed117f38bbd39f570874014cecf7bb5..ffda9f6a8b094942009aa78b331d22d9dcca2802 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/network/StatusClient.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/network/StatusClient.java
|
||||
@@ -10,4 +10,16 @@ import com.destroystokyo.paper.event.server.PaperServerListPingEvent;
|
||||
*/
|
||||
public interface StatusClient extends NetworkClient {
|
||||
|
||||
+ /**
|
||||
+ * Returns whether the client is using an older version that doesn't
|
||||
+ * support all of the features in {@link PaperServerListPingEvent}.
|
||||
+ *
|
||||
+ * <p>For Vanilla, this returns {@code true} for all clients older than 1.7.</p>
|
||||
+ *
|
||||
+ * @return {@code true} if the client is using legacy ping
|
||||
+ */
|
||||
+ default boolean isLegacy() {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Vainomaa <mikroskeem@mikroskeem.eu>
|
||||
Date: Sun, 1 Apr 2018 02:28:43 +0300
|
||||
Subject: [PATCH] Add method to open already placed sign
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/entity/HumanEntity.java b/src/main/java/org/bukkit/entity/HumanEntity.java
|
||||
index 396092fd249928ca01133eeeeb61f0ad90b2e332..5cc025b69c4f405be8f7098d0dcef40fa522b39f 100644
|
||||
--- a/src/main/java/org/bukkit/entity/HumanEntity.java
|
||||
+++ b/src/main/java/org/bukkit/entity/HumanEntity.java
|
||||
@@ -476,6 +476,14 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder
|
||||
*/
|
||||
@Deprecated
|
||||
public void setShoulderEntityRight(@Nullable Entity entity);
|
||||
+ // Paper start - Add method to open already placed sign
|
||||
+ /**
|
||||
+ * Opens an editor window for the specified sign
|
||||
+ *
|
||||
+ * @param sign The sign to open
|
||||
+ */
|
||||
+ void openSign(@NotNull org.bukkit.block.Sign sign);
|
||||
+ // Paper end
|
||||
|
||||
/**
|
||||
* Make the entity drop the item in their hand.
|
|
@ -0,0 +1,253 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sat, 28 Apr 2018 10:28:50 -0400
|
||||
Subject: [PATCH] Add Ban Methods to Player Objects
|
||||
|
||||
Allows a more logical API for banning players.
|
||||
|
||||
player.banPlayer("Breaking the rules");
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/OfflinePlayer.java b/src/main/java/org/bukkit/OfflinePlayer.java
|
||||
index 58313929f81509030216a0e5e3869da63e11108e..6cf05fed701c67a2c797a4e0839c795802a238a1 100644
|
||||
--- a/src/main/java/org/bukkit/OfflinePlayer.java
|
||||
+++ b/src/main/java/org/bukkit/OfflinePlayer.java
|
||||
@@ -45,6 +45,61 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio
|
||||
* @return true if banned, otherwise false
|
||||
*/
|
||||
public boolean isBanned();
|
||||
+ // Paper start
|
||||
+
|
||||
+ /**
|
||||
+ * Permanently Bans this player from the server
|
||||
+ *
|
||||
+ * @param reason Reason for Ban
|
||||
+ * @return Ban Entry
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public default BanEntry banPlayer(@Nullable String reason) {
|
||||
+ return banPlayer(reason, null, null);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Permanently Bans this player from the server
|
||||
+ * @param reason Reason for Ban
|
||||
+ * @param source Source of the ban, or null for default
|
||||
+ * @return Ban Entry
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public default BanEntry banPlayer(@Nullable String reason, @Nullable String source) {
|
||||
+ return banPlayer(reason, null, source);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Bans this player from the server
|
||||
+ * @param reason Reason for Ban
|
||||
+ * @param expires When to expire the ban
|
||||
+ * @return Ban Entry
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public default BanEntry banPlayer(@Nullable String reason, @Nullable java.util.Date expires) {
|
||||
+ return banPlayer(reason, expires, null);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Bans this player from the server
|
||||
+ * @param reason Reason for Ban
|
||||
+ * @param expires When to expire the ban
|
||||
+ * @param source Source of the ban or null for default
|
||||
+ * @return Ban Entry
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public default BanEntry banPlayer(@Nullable String reason, @Nullable java.util.Date expires, @Nullable String source) {
|
||||
+ return banPlayer(reason, expires, source, true);
|
||||
+ }
|
||||
+ @NotNull
|
||||
+ public default BanEntry banPlayer(@Nullable String reason, @Nullable java.util.Date expires, @Nullable String source, boolean kickIfOnline) {
|
||||
+ BanEntry banEntry = Bukkit.getServer().getBanList(BanList.Type.NAME).addBan(getName(), reason, expires, source);
|
||||
+ if (kickIfOnline && isOnline()) {
|
||||
+ getPlayer().kickPlayer(reason);
|
||||
+ }
|
||||
+ return banEntry;
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
/**
|
||||
* Checks if this player is whitelisted or not
|
||||
diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java
|
||||
index b2fdf015b8a86ca96eb5c92aa85d7e36ee21aaad..83bd47744d3e056264e6bf024b45cc86fcd5ea42 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Player.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Player.java
|
||||
@@ -5,6 +5,10 @@ import java.util.UUID;
|
||||
import com.destroystokyo.paper.Title; // Paper
|
||||
import net.kyori.adventure.text.Component;
|
||||
import com.destroystokyo.paper.profile.PlayerProfile; // Paper
|
||||
+import java.util.Date; // Paper
|
||||
+import org.bukkit.BanEntry; // Paper
|
||||
+import org.bukkit.BanList; // Paper
|
||||
+import org.bukkit.Bukkit; // Paper
|
||||
import org.bukkit.DyeColor;
|
||||
import org.bukkit.Effect;
|
||||
import org.bukkit.GameMode;
|
||||
@@ -711,6 +715,162 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
|
||||
public void sendMap(@NotNull MapView map);
|
||||
|
||||
// Paper start
|
||||
+ /**
|
||||
+ * Permanently Bans the Profile and IP address currently used by the player.
|
||||
+ *
|
||||
+ * @param reason Reason for ban
|
||||
+ * @return Ban Entry
|
||||
+ */
|
||||
+ // For reference, Bukkit defines this as nullable, while they impl isn't, we'll follow API.
|
||||
+ @Nullable
|
||||
+ public default BanEntry banPlayerFull(@Nullable String reason) {
|
||||
+ return banPlayerFull(reason, null, null);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Permanently Bans the Profile and IP address currently used by the player.
|
||||
+ *
|
||||
+ * @param reason Reason for ban
|
||||
+ * @param source Source of ban, or null for default
|
||||
+ * @return Ban Entry
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public default BanEntry banPlayerFull(@Nullable String reason, @Nullable String source) {
|
||||
+ return banPlayerFull(reason, null, source);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Bans the Profile and IP address currently used by the player.
|
||||
+ *
|
||||
+ * @param reason Reason for Ban
|
||||
+ * @param expires When to expire the ban
|
||||
+ * @return Ban Entry
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public default BanEntry banPlayerFull(@Nullable String reason, @Nullable Date expires) {
|
||||
+ return banPlayerFull(reason, expires, null);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Bans the Profile and IP address currently used by the player.
|
||||
+ *
|
||||
+ * @param reason Reason for Ban
|
||||
+ * @param expires When to expire the ban
|
||||
+ * @param source Source of the ban, or null for default
|
||||
+ * @return Ban Entry
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public default BanEntry banPlayerFull(@Nullable String reason, @Nullable Date expires, @Nullable String source) {
|
||||
+ banPlayer(reason, expires, source);
|
||||
+ return banPlayerIP(reason, expires, source, true);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Permanently Bans the IP address currently used by the player.
|
||||
+ * Does not ban the Profile, use {@link #banPlayerFull(String, Date, String)}
|
||||
+ *
|
||||
+ * @param reason Reason for ban
|
||||
+ * @param kickPlayer Whether or not to kick the player afterwards
|
||||
+ * @return Ban Entry
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public default BanEntry banPlayerIP(@Nullable String reason, boolean kickPlayer) {
|
||||
+ return banPlayerIP(reason, null, null, kickPlayer);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Permanently Bans the IP address currently used by the player.
|
||||
+ * Does not ban the Profile, use {@link #banPlayerFull(String, Date, String)}
|
||||
+ * @param reason Reason for ban
|
||||
+ * @param source Source of ban, or null for default
|
||||
+ * @param kickPlayer Whether or not to kick the player afterwards
|
||||
+ * @return Ban Entry
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public default BanEntry banPlayerIP(@Nullable String reason, @Nullable String source, boolean kickPlayer) {
|
||||
+ return banPlayerIP(reason, null, source, kickPlayer);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Bans the IP address currently used by the player.
|
||||
+ * Does not ban the Profile, use {@link #banPlayerFull(String, Date, String)}
|
||||
+ * @param reason Reason for Ban
|
||||
+ * @param expires When to expire the ban
|
||||
+ * @param kickPlayer Whether or not to kick the player afterwards
|
||||
+ * @return Ban Entry
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public default BanEntry banPlayerIP(@Nullable String reason, @Nullable Date expires, boolean kickPlayer) {
|
||||
+ return banPlayerIP(reason, expires, null, kickPlayer);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Permanently Bans the IP address currently used by the player.
|
||||
+ * Does not ban the Profile, use {@link #banPlayerFull(String, Date, String)}
|
||||
+ *
|
||||
+ * @param reason Reason for ban
|
||||
+ * @return Ban Entry
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public default BanEntry banPlayerIP(@Nullable String reason) {
|
||||
+ return banPlayerIP(reason, null, null);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Permanently Bans the IP address currently used by the player.
|
||||
+ * Does not ban the Profile, use {@link #banPlayerFull(String, Date, String)}
|
||||
+ * @param reason Reason for ban
|
||||
+ * @param source Source of ban, or null for default
|
||||
+ * @return Ban Entry
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public default BanEntry banPlayerIP(@Nullable String reason, @Nullable String source) {
|
||||
+ return banPlayerIP(reason, null, source);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Bans the IP address currently used by the player.
|
||||
+ * Does not ban the Profile, use {@link #banPlayerFull(String, Date, String)}
|
||||
+ * @param reason Reason for Ban
|
||||
+ * @param expires When to expire the ban
|
||||
+ * @return Ban Entry
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public default BanEntry banPlayerIP(@Nullable String reason, @Nullable Date expires) {
|
||||
+ return banPlayerIP(reason, expires, null);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Bans the IP address currently used by the player.
|
||||
+ * Does not ban the Profile, use {@link #banPlayerFull(String, Date, String)}
|
||||
+ * @param reason Reason for Ban
|
||||
+ * @param expires When to expire the ban
|
||||
+ * @param source Source of the banm or null for default
|
||||
+ * @return Ban Entry
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public default BanEntry banPlayerIP(@Nullable String reason, @Nullable Date expires, @Nullable String source) {
|
||||
+ return banPlayerIP(reason, expires, source, true);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Bans the IP address currently used by the player.
|
||||
+ * Does not ban the Profile, use {@link #banPlayerFull(String, Date, String)}
|
||||
+ * @param reason Reason for Ban
|
||||
+ * @param expires When to expire the ban
|
||||
+ * @param source Source of the banm or null for default
|
||||
+ * @param kickPlayer if the targeted player should be kicked
|
||||
+ * @return Ban Entry
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public default BanEntry banPlayerIP(@Nullable String reason, @Nullable Date expires, @Nullable String source, boolean kickPlayer) {
|
||||
+ BanEntry banEntry = Bukkit.getServer().getBanList(BanList.Type.IP).addBan(getAddress().getAddress().getHostAddress(), reason, expires, source);
|
||||
+ if (kickPlayer && isOnline()) {
|
||||
+ getPlayer().kickPlayer(reason);
|
||||
+ }
|
||||
+
|
||||
+ return banEntry;
|
||||
+ }
|
||||
|
||||
/**
|
||||
* Sends an Action Bar message to the client.
|
102
patches/unapplied/api/0095-EndermanEscapeEvent.patch
Normal file
102
patches/unapplied/api/0095-EndermanEscapeEvent.patch
Normal file
|
@ -0,0 +1,102 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 30 Apr 2018 13:14:30 -0400
|
||||
Subject: [PATCH] EndermanEscapeEvent
|
||||
|
||||
Fires an event anytime an enderman intends to teleport away from the player
|
||||
|
||||
You may cancel this, enabling ranged attacks to damage the enderman for example.
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/EndermanEscapeEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/EndermanEscapeEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..806112a8b5a7ce31166675f5b074ceaf42e364b6
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/entity/EndermanEscapeEvent.java
|
||||
@@ -0,0 +1,87 @@
|
||||
+package com.destroystokyo.paper.event.entity;
|
||||
+
|
||||
+import org.bukkit.entity.Enderman;
|
||||
+import org.bukkit.entity.Entity;
|
||||
+import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.event.Event;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.entity.EntityEvent;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+public class EndermanEscapeEvent extends EntityEvent implements Cancellable {
|
||||
+ @NotNull private final Reason reason;
|
||||
+
|
||||
+ public EndermanEscapeEvent(@NotNull Enderman entity, @NotNull Reason reason) {
|
||||
+ super(entity);
|
||||
+ this.reason = reason;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public Enderman getEntity() {
|
||||
+ return (Enderman) super.getEntity();
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return The reason the enderman is trying to escape
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Reason getReason() {
|
||||
+ return reason;
|
||||
+ }
|
||||
+
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+
|
||||
+ @NotNull
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ private boolean cancelled = false;
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isCancelled() {
|
||||
+ return cancelled;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Cancels the escape.
|
||||
+ *
|
||||
+ * If this escape normally would of resulted in damage avoidance such as indirect,
|
||||
+ * the enderman will now take damage.
|
||||
+ *
|
||||
+ * @param cancel true if you wish to cancel this event
|
||||
+ */
|
||||
+ @Override
|
||||
+ public void setCancelled(boolean cancel) {
|
||||
+ cancelled = cancel;
|
||||
+ }
|
||||
+
|
||||
+ public enum Reason {
|
||||
+ /**
|
||||
+ * The enderman has stopped attacking and ran away
|
||||
+ */
|
||||
+ RUNAWAY,
|
||||
+ /**
|
||||
+ * The enderman has teleported away due to indirect damage (ranged)
|
||||
+ */
|
||||
+ INDIRECT,
|
||||
+ /**
|
||||
+ * The enderman has teleported away due to a critical hit
|
||||
+ */
|
||||
+ CRITICAL_HIT,
|
||||
+ /**
|
||||
+ * The enderman has teleported away due to the player staring at it during combat
|
||||
+ */
|
||||
+ STARE,
|
||||
+ /**
|
||||
+ * Specific case for CRITICAL_HIT where the enderman is taking rain damage
|
||||
+ */
|
||||
+ DROWN
|
||||
+ }
|
||||
+}
|
29
patches/unapplied/api/0096-Enderman.teleportRandomly.patch
Normal file
29
patches/unapplied/api/0096-Enderman.teleportRandomly.patch
Normal file
|
@ -0,0 +1,29 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 30 Apr 2018 13:29:15 -0400
|
||||
Subject: [PATCH] Enderman.teleportRandomly()
|
||||
|
||||
Ability to trigger the vanilla "teleport randomly" mechanic of an enderman.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/entity/Enderman.java b/src/main/java/org/bukkit/entity/Enderman.java
|
||||
index bb325d9c802e33431530bbccdcf5de5839e5fe68..821c690f8a32918bdb284ffec4af98f411f76ccc 100644
|
||||
--- a/src/main/java/org/bukkit/entity/Enderman.java
|
||||
+++ b/src/main/java/org/bukkit/entity/Enderman.java
|
||||
@@ -10,6 +10,17 @@ import org.jetbrains.annotations.Nullable;
|
||||
*/
|
||||
public interface Enderman extends Monster {
|
||||
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Try to teleport the enderman to a random nearby location.
|
||||
+ *
|
||||
+ * May conditionally fail if the random location was not valid
|
||||
+ * @return If the enderman teleported successfully or not
|
||||
+ */
|
||||
+
|
||||
+ public boolean teleportRandomly();
|
||||
+ // Paper end
|
||||
+
|
||||
/**
|
||||
* Gets the id and data of the block that the Enderman is carrying.
|
||||
*
|
|
@ -0,0 +1,292 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 30 Apr 2018 17:55:28 -0400
|
||||
Subject: [PATCH] Additional world.getNearbyEntities API's
|
||||
|
||||
Provides more methods to get nearby entities, and filter by types and predicates
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java
|
||||
index 98c74a6b4f126f2a3e65f95e55561f652c10c4b9..8e434b7048cd650245c6b522807e2f8a6dc497e9 100644
|
||||
--- a/src/main/java/org/bukkit/World.java
|
||||
+++ b/src/main/java/org/bukkit/World.java
|
||||
@@ -1,6 +1,9 @@
|
||||
package org.bukkit;
|
||||
|
||||
import java.io.File;
|
||||
+import org.bukkit.generator.ChunkGenerator;
|
||||
+
|
||||
+import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@@ -652,6 +655,256 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
|
||||
@NotNull
|
||||
public Collection<Entity> getEntitiesByClasses(@NotNull Class<?>... classes);
|
||||
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Gets nearby players within the specified radius (bounding box)
|
||||
+ * @param loc Center location
|
||||
+ * @param radius Radius
|
||||
+ * @return the collection of entities near location. This will always be a non-null collection.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public default Collection<LivingEntity> getNearbyLivingEntities(@NotNull Location loc, double radius) {
|
||||
+ return getNearbyEntitiesByType(org.bukkit.entity.LivingEntity.class, loc, radius, radius, radius);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets nearby players within the specified radius (bounding box)
|
||||
+ * @param loc Center location
|
||||
+ * @param xzRadius X/Z Radius
|
||||
+ * @param yRadius Y Radius
|
||||
+ * @return the collection of entities near location. This will always be a non-null collection.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public default Collection<LivingEntity> getNearbyLivingEntities(@NotNull Location loc, double xzRadius, double yRadius) {
|
||||
+ return getNearbyEntitiesByType(org.bukkit.entity.LivingEntity.class, loc, xzRadius, yRadius, xzRadius);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets nearby players within the specified radius (bounding box)
|
||||
+ * @param loc Center location
|
||||
+ * @param xRadius X Radius
|
||||
+ * @param yRadius Y Radius
|
||||
+ * @param zRadius Z radius
|
||||
+ * @return the collection of entities near location. This will always be a non-null collection.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public default Collection<LivingEntity> getNearbyLivingEntities(@NotNull Location loc, double xRadius, double yRadius, double zRadius) {
|
||||
+ return getNearbyEntitiesByType(org.bukkit.entity.LivingEntity.class, loc, xRadius, yRadius, zRadius);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets nearby players within the specified radius (bounding box)
|
||||
+ * @param loc Center location
|
||||
+ * @param radius X Radius
|
||||
+ * @param predicate a predicate used to filter results
|
||||
+ * @return the collection of living entities near location. This will always be a non-null collection
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public default Collection<LivingEntity> getNearbyLivingEntities(@NotNull Location loc, double radius, @Nullable Predicate<LivingEntity> predicate) {
|
||||
+ return getNearbyEntitiesByType(org.bukkit.entity.LivingEntity.class, loc, radius, radius, radius, predicate);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets nearby players within the specified radius (bounding box)
|
||||
+ * @param loc Center location
|
||||
+ * @param xzRadius X/Z Radius
|
||||
+ * @param yRadius Y Radius
|
||||
+ * @param predicate a predicate used to filter results
|
||||
+ * @return the collection of living entities near location. This will always be a non-null collection
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public default Collection<LivingEntity> getNearbyLivingEntities(@NotNull Location loc, double xzRadius, double yRadius, @Nullable Predicate<LivingEntity> predicate) {
|
||||
+ return getNearbyEntitiesByType(org.bukkit.entity.LivingEntity.class, loc, xzRadius, yRadius, xzRadius, predicate);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets nearby players within the specified radius (bounding box)
|
||||
+ * @param loc Center location
|
||||
+ * @param xRadius X Radius
|
||||
+ * @param yRadius Y Radius
|
||||
+ * @param zRadius Z radius
|
||||
+ * @param predicate a predicate used to filter results
|
||||
+ * @return the collection of living entities near location. This will always be a non-null collection.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public default Collection<LivingEntity> getNearbyLivingEntities(@NotNull Location loc, double xRadius, double yRadius, double zRadius, @Nullable Predicate<LivingEntity> predicate) {
|
||||
+ return getNearbyEntitiesByType(org.bukkit.entity.LivingEntity.class, loc, xRadius, yRadius, zRadius, predicate);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets nearby players within the specified radius (bounding box)
|
||||
+ * @param loc Center location
|
||||
+ * @param radius X/Y/Z Radius
|
||||
+ * @return the collection of living entities near location. This will always be a non-null collection.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public default Collection<Player> getNearbyPlayers(@NotNull Location loc, double radius) {
|
||||
+ return getNearbyEntitiesByType(org.bukkit.entity.Player.class, loc, radius, radius, radius);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets nearby players within the specified radius (bounding box)
|
||||
+ * @param loc Center location
|
||||
+ * @param xzRadius X/Z Radius
|
||||
+ * @param yRadius Y Radius
|
||||
+ * @return the collection of living entities near location. This will always be a non-null collection.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public default Collection<Player> getNearbyPlayers(@NotNull Location loc, double xzRadius, double yRadius) {
|
||||
+ return getNearbyEntitiesByType(org.bukkit.entity.Player.class, loc, xzRadius, yRadius, xzRadius);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets nearby players within the specified radius (bounding box)
|
||||
+ * @param loc Center location
|
||||
+ * @param xRadius X Radius
|
||||
+ * @param yRadius Y Radius
|
||||
+ * @param zRadius Z Radius
|
||||
+ * @return the collection of players near location. This will always be a non-null collection.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public default Collection<Player> getNearbyPlayers(@NotNull Location loc, double xRadius, double yRadius, double zRadius) {
|
||||
+ return getNearbyEntitiesByType(org.bukkit.entity.Player.class, loc, xRadius, yRadius, zRadius);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets nearby players within the specified radius (bounding box)
|
||||
+ * @param loc Center location
|
||||
+ * @param radius X/Y/Z Radius
|
||||
+ * @param predicate a predicate used to filter results
|
||||
+ * @return the collection of players near location. This will always be a non-null collection.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public default Collection<Player> getNearbyPlayers(@NotNull Location loc, double radius, @Nullable Predicate<Player> predicate) {
|
||||
+ return getNearbyEntitiesByType(org.bukkit.entity.Player.class, loc, radius, radius, radius, predicate);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets nearby players within the specified radius (bounding box)
|
||||
+ * @param loc Center location
|
||||
+ * @param xzRadius X/Z Radius
|
||||
+ * @param yRadius Y Radius
|
||||
+ * @param predicate a predicate used to filter results
|
||||
+ * @return the collection of players near location. This will always be a non-null collection.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public default Collection<Player> getNearbyPlayers(@NotNull Location loc, double xzRadius, double yRadius, @Nullable Predicate<Player> predicate) {
|
||||
+ return getNearbyEntitiesByType(org.bukkit.entity.Player.class, loc, xzRadius, yRadius, xzRadius, predicate);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets nearby players within the specified radius (bounding box)
|
||||
+ * @param loc Center location
|
||||
+ * @param xRadius X Radius
|
||||
+ * @param yRadius Y Radius
|
||||
+ * @param zRadius Z Radius
|
||||
+ * @param predicate a predicate used to filter results
|
||||
+ * @return the collection of players near location. This will always be a non-null collection.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public default Collection<Player> getNearbyPlayers(@NotNull Location loc, double xRadius, double yRadius, double zRadius, @Nullable Predicate<Player> predicate) {
|
||||
+ return getNearbyEntitiesByType(org.bukkit.entity.Player.class, loc, xRadius, yRadius, zRadius, predicate);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets all nearby entities of the specified type, within the specified radius (bounding box)
|
||||
+ * @param clazz Type to filter by
|
||||
+ * @param loc Center location
|
||||
+ * @param radius X/Y/Z radius to search within
|
||||
+ * @param <T> the entity type
|
||||
+ * @return the collection of entities near location. This will always be a non-null collection.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public default <T extends Entity> Collection<T> getNearbyEntitiesByType(@Nullable Class<? extends T> clazz, @NotNull Location loc, double radius) {
|
||||
+ return getNearbyEntitiesByType(clazz, loc, radius, radius, radius, null);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets all nearby entities of the specified type, within the specified radius, with x and x radius matching (bounding box)
|
||||
+ * @param clazz Type to filter by
|
||||
+ * @param loc Center location
|
||||
+ * @param xzRadius X/Z radius to search within
|
||||
+ * @param yRadius Y radius to search within
|
||||
+ * @param <T> the entity type
|
||||
+ * @return the collection of entities near location. This will always be a non-null collection.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public default <T extends Entity> Collection<T> getNearbyEntitiesByType(@Nullable Class<? extends T> clazz, @NotNull Location loc, double xzRadius, double yRadius) {
|
||||
+ return getNearbyEntitiesByType(clazz, loc, xzRadius, yRadius, xzRadius, null);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets all nearby entities of the specified type, within the specified radius (bounding box)
|
||||
+ * @param clazz Type to filter by
|
||||
+ * @param loc Center location
|
||||
+ * @param xRadius X Radius
|
||||
+ * @param yRadius Y Radius
|
||||
+ * @param zRadius Z Radius
|
||||
+ * @param <T> the entity type
|
||||
+ * @return the collection of entities near location. This will always be a non-null collection.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public default <T extends Entity> Collection<T> getNearbyEntitiesByType(@Nullable Class<? extends T> clazz, @NotNull Location loc, double xRadius, double yRadius, double zRadius) {
|
||||
+ return getNearbyEntitiesByType(clazz, loc, xRadius, yRadius, zRadius, null);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets all nearby entities of the specified type, within the specified radius (bounding box)
|
||||
+ * @param clazz Type to filter by
|
||||
+ * @param loc Center location
|
||||
+ * @param radius X/Y/Z radius to search within
|
||||
+ * @param predicate a predicate used to filter results
|
||||
+ * @param <T> the entity type
|
||||
+ * @return the collection of entities near location. This will always be a non-null collection.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public default <T extends Entity> Collection<T> getNearbyEntitiesByType(@Nullable Class<? extends T> clazz, @NotNull Location loc, double radius, @Nullable Predicate<T> predicate) {
|
||||
+ return getNearbyEntitiesByType(clazz, loc, radius, radius, radius, predicate);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets all nearby entities of the specified type, within the specified radius, with x and x radius matching (bounding box)
|
||||
+ * @param clazz Type to filter by
|
||||
+ * @param loc Center location
|
||||
+ * @param xzRadius X/Z radius to search within
|
||||
+ * @param yRadius Y radius to search within
|
||||
+ * @param predicate a predicate used to filter results
|
||||
+ * @param <T> the entity type
|
||||
+ * @return the collection of entities near location. This will always be a non-null collection.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public default <T extends Entity> Collection<T> getNearbyEntitiesByType(@Nullable Class<? extends T> clazz, @NotNull Location loc, double xzRadius, double yRadius, @Nullable Predicate<T> predicate) {
|
||||
+ return getNearbyEntitiesByType(clazz, loc, xzRadius, yRadius, xzRadius, predicate);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets all nearby entities of the specified type, within the specified radius (bounding box)
|
||||
+ * @param clazz Type to filter by
|
||||
+ * @param loc Center location
|
||||
+ * @param xRadius X Radius
|
||||
+ * @param yRadius Y Radius
|
||||
+ * @param zRadius Z Radius
|
||||
+ * @param predicate a predicate used to filter results
|
||||
+ * @param <T> the entity type
|
||||
+ * @return the collection of entities near location. This will always be a non-null collection.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public default <T extends Entity> Collection<T> getNearbyEntitiesByType(@Nullable Class<? extends Entity> clazz, @NotNull Location loc, double xRadius, double yRadius, double zRadius, @Nullable Predicate<T> predicate) {
|
||||
+ if (clazz == null) {
|
||||
+ clazz = Entity.class;
|
||||
+ }
|
||||
+ List<T> nearby = new ArrayList<>();
|
||||
+ for (Entity bukkitEntity : getNearbyEntities(loc, xRadius, yRadius, zRadius)) {
|
||||
+ //noinspection unchecked
|
||||
+ if (clazz.isAssignableFrom(bukkitEntity.getClass()) && (predicate == null || predicate.test((T) bukkitEntity))) {
|
||||
+ //noinspection unchecked
|
||||
+ nearby.add((T) bukkitEntity);
|
||||
+ }
|
||||
+ }
|
||||
+ return nearby;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
/**
|
||||
* Get a list of all players in this World
|
||||
*
|
||||
diff --git a/src/main/java/org/bukkit/event/player/AsyncPlayerPreLoginEvent.java b/src/main/java/org/bukkit/event/player/AsyncPlayerPreLoginEvent.java
|
||||
index 25e0d571710403c334bd73ce1b97109dd65c3244..033960f566861e303b9cb61aae4c02add501d93f 100644
|
||||
--- a/src/main/java/org/bukkit/event/player/AsyncPlayerPreLoginEvent.java
|
||||
+++ b/src/main/java/org/bukkit/event/player/AsyncPlayerPreLoginEvent.java
|
||||
@@ -42,8 +42,7 @@ public class AsyncPlayerPreLoginEvent extends Event {
|
||||
return profile;
|
||||
}
|
||||
|
||||
- /**
|
||||
- * Changes the PlayerProfile the player will login as
|
||||
+ /* * Changes the PlayerProfile the player will login as
|
||||
* @param profile The profile to use
|
||||
*/
|
||||
public void setPlayerProfile(@NotNull PlayerProfile profile) {
|
18
patches/unapplied/api/0098-Location.isChunkLoaded-API.patch
Normal file
18
patches/unapplied/api/0098-Location.isChunkLoaded-API.patch
Normal file
|
@ -0,0 +1,18 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 30 Apr 2018 19:27:31 -0400
|
||||
Subject: [PATCH] Location.isChunkLoaded() API
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/Location.java b/src/main/java/org/bukkit/Location.java
|
||||
index 7c4db051472fb6a6c6d24092dc6f75487356690a..3be91f6c9b355c9e8562796d719f5a6ce566d85a 100644
|
||||
--- a/src/main/java/org/bukkit/Location.java
|
||||
+++ b/src/main/java/org/bukkit/Location.java
|
||||
@@ -533,6 +533,7 @@ public class Location implements Cloneable, ConfigurationSerializable {
|
||||
return this;
|
||||
}
|
||||
|
||||
+ public boolean isChunkLoaded() { return this.getWorld().isChunkLoaded(locToBlock(x) >> 4, locToBlock(z) >> 4); } // Paper
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null) {
|
|
@ -0,0 +1,586 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 29 Aug 2017 23:58:48 -0400
|
||||
Subject: [PATCH] Expand World.spawnParticle API and add Builder
|
||||
|
||||
Adds ability to control who receives it and who is the source/sender (vanish API)
|
||||
the standard API is to send the packet to everyone in the world, which is ineffecient.
|
||||
|
||||
This adds a new Builder API which is much friendlier to use.
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/ParticleBuilder.java b/src/main/java/com/destroystokyo/paper/ParticleBuilder.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..f45b8cfd1611345e8d81ecb8297a586f05eb5dc6
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/ParticleBuilder.java
|
||||
@@ -0,0 +1,485 @@
|
||||
+package com.destroystokyo.paper;
|
||||
+
|
||||
+import com.google.common.collect.Lists;
|
||||
+import org.bukkit.Color;
|
||||
+import org.bukkit.Location;
|
||||
+import org.bukkit.Particle;
|
||||
+import org.bukkit.World;
|
||||
+import org.bukkit.entity.Player;
|
||||
+import org.bukkit.util.NumberConversions;
|
||||
+
|
||||
+import java.util.Collection;
|
||||
+import java.util.List;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
+
|
||||
+/**
|
||||
+ * Helps prepare a particle to be sent to players.
|
||||
+ *
|
||||
+ * Usage of the builder is preferred over the super long {@link World#spawnParticle(Particle, Location, int, double, double, double, double, Object)} API
|
||||
+ */
|
||||
+public class ParticleBuilder {
|
||||
+
|
||||
+ private Particle particle;
|
||||
+ private List<Player> receivers;
|
||||
+ private Player source;
|
||||
+ private Location location;
|
||||
+ private int count = 1;
|
||||
+ private double offsetX = 0, offsetY = 0, offsetZ = 0;
|
||||
+ private double extra = 1;
|
||||
+ private Object data;
|
||||
+ private boolean force = true;
|
||||
+
|
||||
+ public ParticleBuilder(@NotNull Particle particle) {
|
||||
+ this.particle = particle;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sends the particle to all receiving players (or all). This method is safe to use
|
||||
+ * Asynchronously
|
||||
+ *
|
||||
+ * @return a reference to this object.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ParticleBuilder spawn() {
|
||||
+ if (this.location == null) {
|
||||
+ throw new IllegalStateException("Please specify location for this particle");
|
||||
+ }
|
||||
+ location.getWorld().spawnParticle(particle, receivers, source,
|
||||
+ location.getX(), location.getY(), location.getZ(),
|
||||
+ count, offsetX, offsetY, offsetZ, extra, data, force
|
||||
+ );
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return The particle going to be sent
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Particle particle() {
|
||||
+ return particle;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Changes what particle will be sent
|
||||
+ *
|
||||
+ * @param particle The particle
|
||||
+ * @return a reference to this object.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ParticleBuilder particle(@NotNull Particle particle) {
|
||||
+ this.particle = particle;
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return List of players who will receive the particle, or null for all in world
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public List<Player> receivers() {
|
||||
+ return receivers;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Example use:
|
||||
+ *
|
||||
+ * builder.receivers(16); if (builder.hasReceivers()) { sendParticleAsync(builder); }
|
||||
+ *
|
||||
+ * @return If this particle is going to be sent to someone
|
||||
+ */
|
||||
+ public boolean hasReceivers() {
|
||||
+ return (receivers == null && !location.getWorld().getPlayers().isEmpty()) || (
|
||||
+ receivers != null && !receivers.isEmpty());
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sends this particle to all players in the world. This is rather silly and you should likely not
|
||||
+ * be doing this.
|
||||
+ *
|
||||
+ * Just be a logical person and use receivers by radius or collection.
|
||||
+ *
|
||||
+ * @return a reference to this object.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ParticleBuilder allPlayers() {
|
||||
+ this.receivers = null;
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @param receivers List of players to receive this particle, or null for all players in the
|
||||
+ * world
|
||||
+ * @return a reference to this object.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ParticleBuilder receivers(@Nullable List<Player> receivers) {
|
||||
+ // Had to keep this as we first made API List<> and not Collection, but removing this may break plugins compiled on older jars
|
||||
+ // TODO: deprecate?
|
||||
+ this.receivers = receivers != null ? Lists.newArrayList(receivers) : null;
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @param receivers List of players to receive this particle, or null for all players in the
|
||||
+ * world
|
||||
+ * @return a reference to this object.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ParticleBuilder receivers(@Nullable Collection<Player> receivers) {
|
||||
+ this.receivers = receivers != null ? Lists.newArrayList(receivers) : null;
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @param receivers List of players to be receive this particle, or null for all players in the
|
||||
+ * world
|
||||
+ * @return a reference to this object.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ParticleBuilder receivers(@Nullable Player... receivers) {
|
||||
+ this.receivers = receivers != null ? Lists.newArrayList(receivers) : null;
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Selects all players within a cuboid selection around the particle location, within the
|
||||
+ * specified bounding box. If you want a more spherical check, see {@link #receivers(int,
|
||||
+ * boolean)}
|
||||
+ *
|
||||
+ * @param radius amount to add on all axis
|
||||
+ * @return a reference to this object.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ParticleBuilder receivers(int radius) {
|
||||
+ return receivers(radius, radius);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Selects all players within the specified radius around the particle location. If byDistance is
|
||||
+ * false, behavior uses cuboid selection the same as {@link #receivers(int, int)} If byDistance is
|
||||
+ * true, radius is tested by distance in a spherical shape
|
||||
+ *
|
||||
+ * @param radius amount to add on each axis
|
||||
+ * @param byDistance true to use a spherical radius, false to use a cuboid
|
||||
+ * @return a reference to this object.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ParticleBuilder receivers(int radius, boolean byDistance) {
|
||||
+ if (!byDistance) {
|
||||
+ return receivers(radius, radius, radius);
|
||||
+ } else {
|
||||
+ this.receivers = Lists.newArrayList();
|
||||
+ for (Player nearbyPlayer : location.getWorld()
|
||||
+ .getNearbyPlayers(location, radius, radius, radius)) {
|
||||
+ Location loc = nearbyPlayer.getLocation();
|
||||
+ double x = NumberConversions.square(location.getX() - loc.getX());
|
||||
+ double y = NumberConversions.square(location.getY() - loc.getY());
|
||||
+ double z = NumberConversions.square(location.getZ() - loc.getZ());
|
||||
+ if (Math.sqrt(x + y + z) > radius) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ this.receivers.add(nearbyPlayer);
|
||||
+ }
|
||||
+ return this;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Selects all players within a cuboid selection around the particle location, within the
|
||||
+ * specified bounding box. Allows specifying a different Y size than X and Z If you want a more
|
||||
+ * cylinder check, see {@link #receivers(int, int, boolean)} If you want a more spherical check,
|
||||
+ * see {@link #receivers(int, boolean)}
|
||||
+ *
|
||||
+ * @param xzRadius amount to add on the x/z axis
|
||||
+ * @param yRadius amount to add on the y axis
|
||||
+ * @return a reference to this object.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ParticleBuilder receivers(int xzRadius, int yRadius) {
|
||||
+ return receivers(xzRadius, yRadius, xzRadius);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Selects all players within the specified radius around the particle location. If byDistance is
|
||||
+ * false, behavior uses cuboid selection the same as {@link #receivers(int, int)} If byDistance is
|
||||
+ * true, radius is tested by distance on the y plane and on the x/z plane, in a cylinder shape.
|
||||
+ *
|
||||
+ * @param xzRadius amount to add on the x/z axis
|
||||
+ * @param yRadius amount to add on the y axis
|
||||
+ * @param byDistance true to use a cylinder shape, false to use cuboid
|
||||
+ * @return a reference to this object.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ParticleBuilder receivers(int xzRadius, int yRadius, boolean byDistance) {
|
||||
+ if (!byDistance) {
|
||||
+ return receivers(xzRadius, yRadius, xzRadius);
|
||||
+ } else {
|
||||
+ this.receivers = Lists.newArrayList();
|
||||
+ for (Player nearbyPlayer : location.getWorld()
|
||||
+ .getNearbyPlayers(location, xzRadius, yRadius, xzRadius)) {
|
||||
+ Location loc = nearbyPlayer.getLocation();
|
||||
+ if (Math.abs(loc.getY() - this.location.getY()) > yRadius) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ double x = NumberConversions.square(location.getX() - loc.getX());
|
||||
+ double z = NumberConversions.square(location.getZ() - loc.getZ());
|
||||
+ if (x + z > NumberConversions.square(xzRadius)) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ this.receivers.add(nearbyPlayer);
|
||||
+ }
|
||||
+ return this;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Selects all players within a cuboid selection around the particle location, within the
|
||||
+ * specified bounding box. If you want a more cylinder check, see {@link #receivers(int, int,
|
||||
+ * boolean)} If you want a more spherical check, see {@link #receivers(int, boolean)}
|
||||
+ *
|
||||
+ * @param xRadius amount to add on the x axis
|
||||
+ * @param yRadius amount to add on the y axis
|
||||
+ * @param zRadius amount to add on the z axis
|
||||
+ * @return a reference to this object.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ParticleBuilder receivers(int xRadius, int yRadius, int zRadius) {
|
||||
+ if (location == null) {
|
||||
+ throw new IllegalStateException("Please set location first");
|
||||
+ }
|
||||
+ return receivers(location.getWorld().getNearbyPlayers(location, xRadius, yRadius, zRadius));
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return The player considered the source of this particle (for Visibility concerns), or null
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public Player source() {
|
||||
+ return source;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the source of this particle for visibility concerns (Vanish API)
|
||||
+ *
|
||||
+ * @param source The player who is considered the source
|
||||
+ * @return a reference to this object.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ParticleBuilder source(@Nullable Player source) {
|
||||
+ this.source = source;
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return Location of where the particle will spawn
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public Location location() {
|
||||
+ return location;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the location of where to spawn the particle
|
||||
+ *
|
||||
+ * @param location The location of the particle
|
||||
+ * @return a reference to this object.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ParticleBuilder location(@NotNull Location location) {
|
||||
+ this.location = location.clone();
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the location of where to spawn the particle
|
||||
+ *
|
||||
+ * @param world World to spawn particle in
|
||||
+ * @param x X location
|
||||
+ * @param y Y location
|
||||
+ * @param z Z location
|
||||
+ * @return a reference to this object.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ParticleBuilder location(@NotNull World world, double x, double y, double z) {
|
||||
+ this.location = new Location(world, x, y, z);
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return Number of particles to spawn
|
||||
+ */
|
||||
+ public int count() {
|
||||
+ return count;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the number of particles to spawn
|
||||
+ *
|
||||
+ * @param count Number of particles
|
||||
+ * @return a reference to this object.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ParticleBuilder count(int count) {
|
||||
+ this.count = count;
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Particle offset X. Varies by particle on how this is used
|
||||
+ *
|
||||
+ * @return Particle offset X.
|
||||
+ */
|
||||
+ public double offsetX() {
|
||||
+ return offsetX;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Particle offset Y. Varies by particle on how this is used
|
||||
+ *
|
||||
+ * @return Particle offset Y.
|
||||
+ */
|
||||
+ public double offsetY() {
|
||||
+ return offsetY;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Particle offset Z. Varies by particle on how this is used
|
||||
+ *
|
||||
+ * @return Particle offset Z.
|
||||
+ */
|
||||
+ public double offsetZ() {
|
||||
+ return offsetZ;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the particle offset. Varies by particle on how this is used
|
||||
+ *
|
||||
+ * @param offsetX Particle offset X
|
||||
+ * @param offsetY Particle offset Y
|
||||
+ * @param offsetZ Particle offset Z
|
||||
+ * @return a reference to this object.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ParticleBuilder offset(double offsetX, double offsetY, double offsetZ) {
|
||||
+ this.offsetX = offsetX;
|
||||
+ this.offsetY = offsetY;
|
||||
+ this.offsetZ = offsetZ;
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the Particle extra data. Varies by particle on how this is used
|
||||
+ *
|
||||
+ * @return the extra particle data
|
||||
+ */
|
||||
+ public double extra() {
|
||||
+ return extra;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the particle extra data. Varies by particle on how this is used
|
||||
+ *
|
||||
+ * @param extra the extra particle data
|
||||
+ * @return a reference to this object.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ParticleBuilder extra(double extra) {
|
||||
+ this.extra = extra;
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Gets the particle custom data. Varies by particle on how this is used
|
||||
+ *
|
||||
+ * @param <T> The Particle data type
|
||||
+ * @return the ParticleData for this particle
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public <T> T data() {
|
||||
+ //noinspection unchecked
|
||||
+ return (T) data;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the particle custom data. Varies by particle on how this is used
|
||||
+ *
|
||||
+ * @param data The new particle data
|
||||
+ * @param <T> The Particle data type
|
||||
+ * @return a reference to this object.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public <T> ParticleBuilder data(@Nullable T data) {
|
||||
+ this.data = data;
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return whether the particle is forcefully shown to players.
|
||||
+ */
|
||||
+ public boolean force() {
|
||||
+ return force;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets whether the particle is forcefully shown to the player. If forced, the particle will show
|
||||
+ * faraway, as far as the player's view distance allows. If false, the particle will show
|
||||
+ * according to the client's particle settings.
|
||||
+ *
|
||||
+ * @param force true to force, false for normal
|
||||
+ * @return a reference to this object.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ParticleBuilder force(boolean force) {
|
||||
+ this.force = force;
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the particle Color. Only valid for REDSTONE.
|
||||
+ *
|
||||
+ * @param color the new particle color
|
||||
+ * @return a reference to this object.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ParticleBuilder color(@Nullable Color color) {
|
||||
+ return color(color, 1);
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the particle Color and size. Only valid for REDSTONE.
|
||||
+ *
|
||||
+ * @param color the new particle color
|
||||
+ * @param size the size of the particle
|
||||
+ * @return a reference to this object.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ParticleBuilder color(@Nullable Color color, float size) {
|
||||
+ if (particle != Particle.REDSTONE && color != null) {
|
||||
+ throw new IllegalStateException("Color may only be set on REDSTONE");
|
||||
+ }
|
||||
+
|
||||
+ // We don't officially support reusing these objects, but here we go
|
||||
+ if (color == null) {
|
||||
+ if (data instanceof Particle.DustOptions) {
|
||||
+ return data(null);
|
||||
+ } else {
|
||||
+ return this;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return data(new Particle.DustOptions(color, size));
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the particle Color.
|
||||
+ * Only valid for REDSTONE.
|
||||
+ * @param r red color component
|
||||
+ * @param g green color component
|
||||
+ * @param b blue color component
|
||||
+ * @return a reference to this object.
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public ParticleBuilder color(int r, int g, int b) {
|
||||
+ return color(Color.fromRGB(r, g, b));
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/Particle.java b/src/main/java/org/bukkit/Particle.java
|
||||
index dc5142460a711ee79aed30276382b92c82cbef00..40a3a54fc82252692fc8710cabb243d0984ccf4f 100644
|
||||
--- a/src/main/java/org/bukkit/Particle.java
|
||||
+++ b/src/main/java/org/bukkit/Particle.java
|
||||
@@ -122,6 +122,17 @@ public enum Particle {
|
||||
return dataType;
|
||||
}
|
||||
|
||||
+ // Paper start - Particle API expansion
|
||||
+ /**
|
||||
+ * Creates a {@link com.destroystokyo.paper.ParticleBuilder}
|
||||
+ *
|
||||
+ * @return a {@link com.destroystokyo.paper.ParticleBuilder} for the particle
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public com.destroystokyo.paper.ParticleBuilder builder() {
|
||||
+ return new com.destroystokyo.paper.ParticleBuilder(this);
|
||||
+ }
|
||||
+ // Paper end
|
||||
/**
|
||||
* Options which can be applied to redstone dust particles - a particle
|
||||
* color and size.
|
||||
diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java
|
||||
index fbf8eb17630dfc43be8cf7ba92193e3da8aad1a4..73d0e05c7f8dbab81cdaacb8111fc4681a631ad3 100644
|
||||
--- a/src/main/java/org/bukkit/World.java
|
||||
+++ b/src/main/java/org/bukkit/World.java
|
||||
@@ -2637,7 +2637,57 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
|
||||
* @param data the data to use for the particle or null,
|
||||
* the type of this depends on {@link Particle#getDataType()}
|
||||
*/
|
||||
- public <T> void spawnParticle(@NotNull Particle particle, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ, double extra, @Nullable T data);
|
||||
+ public default <T> void spawnParticle(@NotNull Particle particle, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ, double extra, @Nullable T data) { spawnParticle(particle, null, null, x, y, z, count, offsetX, offsetY, offsetZ, extra, data, true); }// Paper start - Expand Particle API
|
||||
+ /**
|
||||
+ * Spawns the particle (the number of times specified by count)
|
||||
+ * at the target location. The position of each particle will be
|
||||
+ * randomized positively and negatively by the offset parameters
|
||||
+ * on each axis.
|
||||
+ *
|
||||
+ * @param particle the particle to spawn
|
||||
+ * @param receivers List of players to receive the particles, or null for all in world
|
||||
+ * @param source Source of the particles to be used in visibility checks, or null if no player source
|
||||
+ * @param x the position on the x axis to spawn at
|
||||
+ * @param y the position on the y axis to spawn at
|
||||
+ * @param z the position on the z axis to spawn at
|
||||
+ * @param count the number of particles
|
||||
+ * @param offsetX the maximum random offset on the X axis
|
||||
+ * @param offsetY the maximum random offset on the Y axis
|
||||
+ * @param offsetZ the maximum random offset on the Z axis
|
||||
+ * @param extra the extra data for this particle, depends on the
|
||||
+ * particle used (normally speed)
|
||||
+ * @param data the data to use for the particle or null,
|
||||
+ * the type of this depends on {@link Particle#getDataType()}
|
||||
+ * @param <T> Type
|
||||
+ */
|
||||
+ public default <T> void spawnParticle(@NotNull Particle particle, @Nullable List<Player> receivers, @NotNull Player source, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ, double extra, @Nullable T data) { spawnParticle(particle, receivers, source, x, y, z, count, offsetX, offsetY, offsetZ, extra, data, true); }
|
||||
+ /**
|
||||
+ * Spawns the particle (the number of times specified by count)
|
||||
+ * at the target location. The position of each particle will be
|
||||
+ * randomized positively and negatively by the offset parameters
|
||||
+ * on each axis.
|
||||
+ *
|
||||
+ * @param particle the particle to spawn
|
||||
+ * @param receivers List of players to receive the particles, or null for all in world
|
||||
+ * @param source Source of the particles to be used in visibility checks, or null if no player source
|
||||
+ * @param x the position on the x axis to spawn at
|
||||
+ * @param y the position on the y axis to spawn at
|
||||
+ * @param z the position on the z axis to spawn at
|
||||
+ * @param count the number of particles
|
||||
+ * @param offsetX the maximum random offset on the X axis
|
||||
+ * @param offsetY the maximum random offset on the Y axis
|
||||
+ * @param offsetZ the maximum random offset on the Z axis
|
||||
+ * @param extra the extra data for this particle, depends on the
|
||||
+ * particle used (normally speed)
|
||||
+ * @param data the data to use for the particle or null,
|
||||
+ * the type of this depends on {@link Particle#getDataType()}
|
||||
+ * @param <T> Type
|
||||
+ * @param force allows the particle to be seen further away from the player
|
||||
+ * and shows to players using any vanilla client particle settings
|
||||
+ */
|
||||
+ public <T> void spawnParticle(@NotNull Particle particle, @Nullable List<Player> receivers, @Nullable Player source, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ, double extra, @Nullable T data, boolean force);
|
||||
+ // Paper end
|
||||
+
|
||||
|
||||
/**
|
||||
* Spawns the particle (the number of times specified by count)
|
116
patches/unapplied/api/0100-EndermanAttackPlayerEvent.patch
Normal file
116
patches/unapplied/api/0100-EndermanAttackPlayerEvent.patch
Normal file
|
@ -0,0 +1,116 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 1 May 2018 20:17:44 -0400
|
||||
Subject: [PATCH] EndermanAttackPlayerEvent
|
||||
|
||||
Allow control over whether or not an enderman aggros a player.
|
||||
|
||||
This allows you to override/extend the pumpkin/stare logic.
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/EndermanAttackPlayerEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/EndermanAttackPlayerEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..f530a3d9314e17d1da896cac633f6a422258d9a9
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/entity/EndermanAttackPlayerEvent.java
|
||||
@@ -0,0 +1,101 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2018 Daniel Ennis (Aikar) MIT License
|
||||
+ *
|
||||
+ * Permission is hereby granted, free of charge, to any person obtaining
|
||||
+ * a copy of this software and associated documentation files (the
|
||||
+ * "Software"), to deal in the Software without restriction, including
|
||||
+ * without limitation the rights to use, copy, modify, merge, publish,
|
||||
+ * distribute, sublicense, and/or sell copies of the Software, and to
|
||||
+ * permit persons to whom the Software is furnished to do so, subject to
|
||||
+ * the following conditions:
|
||||
+ *
|
||||
+ * The above copyright notice and this permission notice shall be
|
||||
+ * included in all copies or substantial portions of the Software.
|
||||
+ *
|
||||
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
+ */
|
||||
+
|
||||
+package com.destroystokyo.paper.event.entity;
|
||||
+
|
||||
+import org.bukkit.entity.Enderman;
|
||||
+import org.bukkit.entity.Entity;
|
||||
+import org.bukkit.entity.Player;
|
||||
+import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.event.Event;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.entity.EntityEvent;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+/**
|
||||
+ * Fired when an Enderman determines if it should attack a player or not.
|
||||
+ * Starts off cancelled if the player is wearing a pumpkin head or is not looking
|
||||
+ * at the Enderman, according to Vanilla rules.
|
||||
+ *
|
||||
+ */
|
||||
+public class EndermanAttackPlayerEvent extends EntityEvent implements Cancellable {
|
||||
+ @NotNull private final Player player;
|
||||
+
|
||||
+ public EndermanAttackPlayerEvent(@NotNull Enderman entity, @NotNull Player player) {
|
||||
+ super(entity);
|
||||
+ this.player = player;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * The enderman considering attacking
|
||||
+ *
|
||||
+ * @return The enderman considering attacking
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public Enderman getEntity() {
|
||||
+ return (Enderman) super.getEntity();
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * The player the Enderman is considering attacking
|
||||
+ *
|
||||
+ * @return The player the Enderman is considering attacking
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Player getPlayer() {
|
||||
+ return player;
|
||||
+ }
|
||||
+
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+
|
||||
+ @NotNull
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ private boolean cancelled = false;
|
||||
+
|
||||
+ /**
|
||||
+ *
|
||||
+ * @return If cancelled, the enderman will not attack
|
||||
+ */
|
||||
+ @Override
|
||||
+ public boolean isCancelled() {
|
||||
+ return cancelled;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Cancels if the Enderman will attack this player
|
||||
+ * @param cancel true if you wish to cancel this event
|
||||
+ */
|
||||
+ @Override
|
||||
+ public void setCancelled(boolean cancel) {
|
||||
+ cancelled = cancel;
|
||||
+ }
|
||||
+}
|
|
@ -0,0 +1,105 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 1 May 2018 21:33:35 -0400
|
||||
Subject: [PATCH] Close Plugin Class Loaders on Disable
|
||||
|
||||
This should close more memory leaks from /reload and disabling plugins,
|
||||
by closing the class loader and the jar file.
|
||||
|
||||
Note: This patch is no longer necessary as upstream now also closes
|
||||
PluginClassLoaders on disable. This patch is now only to keep around
|
||||
API methods it previously added, and to add back the log message when a
|
||||
PluginClassLoader fails to disable, as upstream decided to ignore the
|
||||
exception.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/plugin/PluginLoader.java b/src/main/java/org/bukkit/plugin/PluginLoader.java
|
||||
index a88733f1cd1ddb5d85ab1b0e6af4fd5b80bbc1c6..256e440e699942e3c9da4205bb964bdc10ec92c4 100644
|
||||
--- a/src/main/java/org/bukkit/plugin/PluginLoader.java
|
||||
+++ b/src/main/java/org/bukkit/plugin/PluginLoader.java
|
||||
@@ -77,4 +77,21 @@ public interface PluginLoader {
|
||||
* @param plugin Plugin to disable
|
||||
*/
|
||||
public void disablePlugin(@NotNull Plugin plugin);
|
||||
+
|
||||
+ // Paper start - close Classloader on disable
|
||||
+ /**
|
||||
+ * This method is no longer useful as upstream has
|
||||
+ * made it so plugin classloaders are always closed on disable.
|
||||
+ * Use {@link #disablePlugin(Plugin)} instead.
|
||||
+ *
|
||||
+ * @param plugin Plugin to disable
|
||||
+ * @param closeClassloader unused
|
||||
+ * @deprecated Classloader is always closed by upstream now.
|
||||
+ */
|
||||
+ @Deprecated(forRemoval = true)
|
||||
+ // provide default to allow other PluginLoader implementations to work
|
||||
+ default public void disablePlugin(@NotNull Plugin plugin, boolean closeClassloader) {
|
||||
+ disablePlugin(plugin);
|
||||
+ }
|
||||
+ // Paper end - close Classloader on disable
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/plugin/PluginManager.java b/src/main/java/org/bukkit/plugin/PluginManager.java
|
||||
index 41e26451fe12d8e6e0ef73c85731b24b4e3f200c..0d1b20f2b5580ea5505ccc2f003925dbcee67199 100644
|
||||
--- a/src/main/java/org/bukkit/plugin/PluginManager.java
|
||||
+++ b/src/main/java/org/bukkit/plugin/PluginManager.java
|
||||
@@ -161,6 +161,22 @@ public interface PluginManager {
|
||||
*/
|
||||
public void disablePlugin(@NotNull Plugin plugin);
|
||||
|
||||
+ // Paper start - close Classloader on disable
|
||||
+ /**
|
||||
+ * This method is no longer useful as upstream has
|
||||
+ * made it so plugin classloaders are always closed on disable.
|
||||
+ * Use {@link #disablePlugin(Plugin)} instead.
|
||||
+ *
|
||||
+ * @param plugin Plugin to disable
|
||||
+ * @param closeClassloader unused
|
||||
+ * @deprecated Classloader is always closed by upstream now.
|
||||
+ */
|
||||
+ @Deprecated(forRemoval = true)
|
||||
+ public default void disablePlugin(@NotNull Plugin plugin, boolean closeClassloader) {
|
||||
+ this.disablePlugin(plugin);
|
||||
+ }
|
||||
+ // Paper end - close Classloader on disable
|
||||
+
|
||||
/**
|
||||
* Gets a {@link Permission} from its fully qualified name
|
||||
*
|
||||
diff --git a/src/main/java/org/bukkit/plugin/SimplePluginManager.java b/src/main/java/org/bukkit/plugin/SimplePluginManager.java
|
||||
index 2d27dfb859c312d46a14d0356c7c3f227e965a67..7867243a8ed67416895cdcd949ac424f5d29d98b 100644
|
||||
--- a/src/main/java/org/bukkit/plugin/SimplePluginManager.java
|
||||
+++ b/src/main/java/org/bukkit/plugin/SimplePluginManager.java
|
||||
@@ -498,6 +498,21 @@ public final class SimplePluginManager implements PluginManager {
|
||||
}
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * This method is no longer useful as upstream has
|
||||
+ * made it so plugin classloaders are always closed on disable.
|
||||
+ * Use {@link #disablePlugins()} instead.
|
||||
+ *
|
||||
+ * @param closeClassloaders unused
|
||||
+ * @deprecated Classloader is always closed by upstream now.
|
||||
+ */
|
||||
+ @Deprecated(forRemoval = true)
|
||||
+ public void disablePlugins(boolean closeClassloaders) {
|
||||
+ this.disablePlugins();
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public void disablePlugin(@NotNull final Plugin plugin) {
|
||||
if (plugin.isEnabled()) {
|
||||
diff --git a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
|
||||
index b7cd98f20de3421cd3b8a95cfa2155fa77afa8b1..7483ceff298cafa244bd99316a0338aa075267d4 100644
|
||||
--- a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
|
||||
+++ b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
|
||||
@@ -366,6 +366,7 @@ public final class JavaPluginLoader implements PluginLoader {
|
||||
loader.close();
|
||||
} catch (IOException ex) {
|
||||
//
|
||||
+ this.server.getLogger().log(Level.WARNING, "Error closing the PluginClassLoader for '" + plugin.getDescription().getFullName() + "'", ex); // Paper - log exception
|
||||
}
|
||||
}
|
||||
}
|
122
patches/unapplied/api/0102-WitchConsumePotionEvent.patch
Normal file
122
patches/unapplied/api/0102-WitchConsumePotionEvent.patch
Normal file
|
@ -0,0 +1,122 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Wed, 16 May 2018 20:26:16 -0400
|
||||
Subject: [PATCH] WitchConsumePotionEvent
|
||||
|
||||
Fires when a witch consumes the potion in their hand
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/WitchConsumePotionEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/WitchConsumePotionEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..fbbace36d69373046a7f3618ed5c1c1318b489b9
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/entity/WitchConsumePotionEvent.java
|
||||
@@ -0,0 +1,70 @@
|
||||
+package com.destroystokyo.paper.event.entity;
|
||||
+
|
||||
+import org.bukkit.entity.Witch;
|
||||
+import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.entity.EntityEvent;
|
||||
+import org.bukkit.inventory.ItemStack;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
+
|
||||
+/**
|
||||
+ * Fired when a witch consumes the potion in their hand to buff themselves.
|
||||
+ */
|
||||
+public class WitchConsumePotionEvent extends EntityEvent implements Cancellable {
|
||||
+ @Nullable private ItemStack potion;
|
||||
+
|
||||
+ public WitchConsumePotionEvent(@NotNull Witch witch, @Nullable ItemStack potion) {
|
||||
+ super(witch);
|
||||
+ this.potion = potion;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public Witch getEntity() {
|
||||
+ return (Witch) super.getEntity();
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return the potion the witch will consume and have the effects applied.
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public ItemStack getPotion() {
|
||||
+ return potion;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the potion to be consumed and applied to the witch.
|
||||
+ * @param potion The potion
|
||||
+ */
|
||||
+ public void setPotion(@Nullable ItemStack potion) {
|
||||
+ this.potion = potion != null ? potion.clone() : null;
|
||||
+ }
|
||||
+
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+
|
||||
+ @NotNull
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ @NotNull
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ private boolean cancelled = false;
|
||||
+
|
||||
+ /**
|
||||
+ * @return Event was cancelled or potion was null
|
||||
+ */
|
||||
+ @Override
|
||||
+ public boolean isCancelled() {
|
||||
+ return cancelled || potion == null;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setCancelled(boolean cancel) {
|
||||
+ cancelled = cancel;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/WitchThrowPotionEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/WitchThrowPotionEvent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..6ef6367b67261c2b653a97322b9703a9409b3499
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/entity/WitchThrowPotionEvent.java
|
||||
@@ -0,0 +1,33 @@
|
||||
+package com.destroystokyo.paper.event.entity;
|
||||
+
|
||||
+import org.bukkit.event.Cancellable;
|
||||
+import org.bukkit.event.Event;
|
||||
+import org.bukkit.event.HandlerList;
|
||||
+
|
||||
+public class WitchThrowPotionEvent extends Event implements Cancellable {
|
||||
+ public WitchThrowPotionEvent() {
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ private static final HandlerList handlers = new HandlerList();
|
||||
+
|
||||
+ public HandlerList getHandlers() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ public static HandlerList getHandlerList() {
|
||||
+ return handlers;
|
||||
+ }
|
||||
+
|
||||
+ private boolean cancelled = false;
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isCancelled() {
|
||||
+ return cancelled;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setCancelled(boolean cancel) {
|
||||
+ cancelled = cancel;
|
||||
+ }
|
||||
+}
|
93
patches/unapplied/api/0103-WitchThrowPotionEvent.patch
Normal file
93
patches/unapplied/api/0103-WitchThrowPotionEvent.patch
Normal file
|
@ -0,0 +1,93 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Wed, 16 May 2018 20:39:09 -0400
|
||||
Subject: [PATCH] WitchThrowPotionEvent
|
||||
|
||||
Fired when a witch throws a potion at a player
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/event/entity/WitchThrowPotionEvent.java b/src/main/java/com/destroystokyo/paper/event/entity/WitchThrowPotionEvent.java
|
||||
index 6ef6367b67261c2b653a97322b9703a9409b3499..688a596aa2b925651a92bf092e1ef4d77a47258c 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/event/entity/WitchThrowPotionEvent.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/event/entity/WitchThrowPotionEvent.java
|
||||
@@ -1,29 +1,77 @@
|
||||
package com.destroystokyo.paper.event.entity;
|
||||
|
||||
+import org.bukkit.entity.LivingEntity;
|
||||
+import org.bukkit.entity.Witch;
|
||||
import org.bukkit.event.Cancellable;
|
||||
-import org.bukkit.event.Event;
|
||||
import org.bukkit.event.HandlerList;
|
||||
+import org.bukkit.event.entity.EntityEvent;
|
||||
+import org.bukkit.inventory.ItemStack;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
|
||||
-public class WitchThrowPotionEvent extends Event implements Cancellable {
|
||||
- public WitchThrowPotionEvent() {
|
||||
+/**
|
||||
+ * Fired when a witch throws a potion at a player
|
||||
+ */
|
||||
+public class WitchThrowPotionEvent extends EntityEvent implements Cancellable {
|
||||
+ @NotNull private final LivingEntity target;
|
||||
+ @Nullable private ItemStack potion;
|
||||
+
|
||||
+ public WitchThrowPotionEvent(@NotNull Witch witch, @NotNull LivingEntity target, @Nullable ItemStack potion) {
|
||||
+ super(witch);
|
||||
+ this.target = target;
|
||||
+ this.potion = potion;
|
||||
}
|
||||
|
||||
+ @NotNull
|
||||
+ @Override
|
||||
+ public Witch getEntity() {
|
||||
+ return (Witch) super.getEntity();
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return The target of the potion
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public LivingEntity getTarget() {
|
||||
+ return target;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * @return The potion the witch will throw at a player
|
||||
+ */
|
||||
+ @Nullable
|
||||
+ public ItemStack getPotion() {
|
||||
+ return potion;
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Sets the potion to be thrown at a player
|
||||
+ * @param potion The potion
|
||||
+ */
|
||||
+ public void setPotion(@Nullable ItemStack potion) {
|
||||
+ this.potion = potion != null ? potion.clone() : null;
|
||||
+ }
|
||||
|
||||
private static final HandlerList handlers = new HandlerList();
|
||||
|
||||
+ @NotNull
|
||||
public HandlerList getHandlers() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
+ @NotNull
|
||||
public static HandlerList getHandlerList() {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
private boolean cancelled = false;
|
||||
|
||||
+ /**
|
||||
+ * @return Event was cancelled or potion was null
|
||||
+ */
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
- return cancelled;
|
||||
+ return cancelled || potion == null;
|
||||
}
|
||||
|
||||
@Override
|
|
@ -0,0 +1,43 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Thu, 24 May 2018 21:01:13 -0400
|
||||
Subject: [PATCH] Location.toBlockLocation/toCenterLocation()
|
||||
|
||||
Convert location objects to their block coordinates, or the center of the block
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/Location.java b/src/main/java/org/bukkit/Location.java
|
||||
index 3be91f6c9b355c9e8562796d719f5a6ce566d85a..a90010fea189c5ac9a59a0e6d04c0457243a3280 100644
|
||||
--- a/src/main/java/org/bukkit/Location.java
|
||||
+++ b/src/main/java/org/bukkit/Location.java
|
||||
@@ -534,6 +534,31 @@ public class Location implements Cloneable, ConfigurationSerializable {
|
||||
}
|
||||
|
||||
public boolean isChunkLoaded() { return this.getWorld().isChunkLoaded(locToBlock(x) >> 4, locToBlock(z) >> 4); } // Paper
|
||||
+
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * @return A new location where X/Y/Z are on the Block location (integer value of X/Y/Z)
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Location toBlockLocation() {
|
||||
+ Location blockLoc = clone();
|
||||
+ blockLoc.setX(getBlockX());
|
||||
+ blockLoc.setY(getBlockY());
|
||||
+ blockLoc.setZ(getBlockZ());
|
||||
+ return blockLoc;
|
||||
+ }
|
||||
+ /**
|
||||
+ * @return A new location where X/Y/Z are the center of the block
|
||||
+ */
|
||||
+ @NotNull
|
||||
+ public Location toCenterLocation() {
|
||||
+ Location centerLoc = clone();
|
||||
+ centerLoc.setX(getBlockX() + 0.5);
|
||||
+ centerLoc.setY(getBlockY() + 0.5);
|
||||
+ centerLoc.setZ(getBlockZ() + 0.5);
|
||||
+ return centerLoc;
|
||||
+ }
|
||||
+ // Paper end
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null) {
|
44
patches/unapplied/api/0105-PotionEffect-clone-methods.patch
Normal file
44
patches/unapplied/api/0105-PotionEffect-clone-methods.patch
Normal file
|
@ -0,0 +1,44 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sun, 3 Jun 2018 04:10:13 -0400
|
||||
Subject: [PATCH] PotionEffect clone methods
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/potion/PotionEffect.java b/src/main/java/org/bukkit/potion/PotionEffect.java
|
||||
index 60716c627d315b08c3fe03b1a945af60c350711f..74767751199bce03d63f2a9524712656193f850c 100644
|
||||
--- a/src/main/java/org/bukkit/potion/PotionEffect.java
|
||||
+++ b/src/main/java/org/bukkit/potion/PotionEffect.java
|
||||
@@ -101,6 +101,33 @@ public class PotionEffect implements ConfigurationSerializable {
|
||||
this(getEffectType(map), getInt(map, DURATION), getInt(map, AMPLIFIER), getBool(map, AMBIENT, false), getBool(map, PARTICLES, true), getBool(map, ICON, getBool(map, PARTICLES, true)));
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @NotNull
|
||||
+ public PotionEffect withType(@NotNull PotionEffectType type) {
|
||||
+ return new PotionEffect(type, duration, amplifier, ambient, particles, icon);
|
||||
+ }
|
||||
+ @NotNull
|
||||
+ public PotionEffect withDuration(int duration) {
|
||||
+ return new PotionEffect(this.type, duration, amplifier, ambient, particles, icon);
|
||||
+ }
|
||||
+ @NotNull
|
||||
+ public PotionEffect withAmplifier(int amplifier) {
|
||||
+ return new PotionEffect(this.type, duration, amplifier, ambient, particles, icon);
|
||||
+ }
|
||||
+ @NotNull
|
||||
+ public PotionEffect withAmbient(boolean ambient) {
|
||||
+ return new PotionEffect(this.type, duration, amplifier, ambient, particles, icon);
|
||||
+ }
|
||||
+ @NotNull
|
||||
+ public PotionEffect withParticles(boolean particles) {
|
||||
+ return new PotionEffect(this.type, duration, amplifier, ambient, particles, icon);
|
||||
+ }
|
||||
+ @NotNull
|
||||
+ public PotionEffect withIcon(boolean icon) {
|
||||
+ return new PotionEffect(this.type, duration, amplifier, ambient, particles, icon);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@NotNull
|
||||
private static PotionEffectType getEffectType(@NotNull Map<?, ?> map) {
|
||||
int type = getInt(map, TYPE);
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue