1.21.4 (hard fork) - api only, server wip
This commit is contained in:
6
.gitignore
vendored
6
.gitignore
vendored
@@ -6,10 +6,10 @@ build
|
|||||||
|
|
||||||
/run
|
/run
|
||||||
|
|
||||||
/fork-server/build.gradle.kts
|
/parchment-server/build.gradle.kts
|
||||||
/fork-server/src/minecraft
|
/parchment-server/src/minecraft
|
||||||
/paper-server
|
/paper-server
|
||||||
/fork-api/build.gradle.kts
|
/parchment-api/build.gradle.kts
|
||||||
/paper-api
|
/paper-api
|
||||||
/paper-api-generator
|
/paper-api-generator
|
||||||
|
|
||||||
|
|||||||
10
README.md
Normal file
10
README.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
Things I've found while just trying to get this to work:
|
||||||
|
|
||||||
|
- If you've made an update to either of the build.gradle.kts files in api or server, run `./gradlew rebuildPaperSingleFilePatches` after adding to git (no commit)
|
||||||
|
- To create a file patch:
|
||||||
|
- Make the changes you need and have no other staged changes
|
||||||
|
- cd paper-api or paper-server
|
||||||
|
- git add .
|
||||||
|
- git commit --ammend
|
||||||
|
- This ammends it to the specific 'File Patch Commit'
|
||||||
|
- ./gradlew rebuildPaper<Api/Server>FilePatches
|
||||||
@@ -12,23 +12,23 @@ paperweight {
|
|||||||
|
|
||||||
patchFile {
|
patchFile {
|
||||||
path = "paper-server/build.gradle.kts"
|
path = "paper-server/build.gradle.kts"
|
||||||
outputFile = file("fork-server/build.gradle.kts")
|
outputFile = file("parchment-server/build.gradle.kts")
|
||||||
patchFile = file("fork-server/build.gradle.kts.patch")
|
patchFile = file("parchment-server/build.gradle.kts.patch")
|
||||||
}
|
}
|
||||||
patchFile {
|
patchFile {
|
||||||
path = "paper-api/build.gradle.kts"
|
path = "paper-api/build.gradle.kts"
|
||||||
outputFile = file("fork-api/build.gradle.kts")
|
outputFile = file("parchment-api/build.gradle.kts")
|
||||||
patchFile = file("fork-api/build.gradle.kts.patch")
|
patchFile = file("parchment-api/build.gradle.kts.patch")
|
||||||
}
|
}
|
||||||
patchDir("paperApi") {
|
patchDir("paperApi") {
|
||||||
upstreamPath = "paper-api"
|
upstreamPath = "paper-api"
|
||||||
excludes = setOf("build.gradle.kts")
|
excludes = setOf("build.gradle.kts")
|
||||||
patchesDir = file("fork-api/paper-patches")
|
patchesDir = file("parchment-api/paper-patches")
|
||||||
outputDir = file("paper-api")
|
outputDir = file("paper-api")
|
||||||
}
|
}
|
||||||
patchDir("paperApiGenerator") {
|
patchDir("paperApiGenerator") {
|
||||||
upstreamPath = "paper-api-generator"
|
upstreamPath = "paper-api-generator"
|
||||||
patchesDir = file("fork-api-generator/paper-patches")
|
patchesDir = file("parchment-api-generator/paper-patches")
|
||||||
outputDir = file("paper-api-generator")
|
outputDir = file("paper-api-generator")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -49,6 +49,7 @@ subprojects {
|
|||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
maven(paperMavenPublicUrl)
|
maven(paperMavenPublicUrl)
|
||||||
|
maven("https://sonatype.projecteden.gg/repository/maven-public/")
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
@@ -80,12 +81,11 @@ subprojects {
|
|||||||
|
|
||||||
extensions.configure<PublishingExtension> {
|
extensions.configure<PublishingExtension> {
|
||||||
repositories {
|
repositories {
|
||||||
/*
|
maven {
|
||||||
maven("https://repo.papermc.io/repository/maven-snapshots/") {
|
name = "edenSnapshots"
|
||||||
name = "paperSnapshots"
|
url = uri("https://sonatype.projecteden.gg/repository/maven-snapshots/")
|
||||||
credentials(PasswordCredentials::class)
|
credentials(PasswordCredentials::class)
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
group=fork.test
|
group=gg.projecteden.parchment
|
||||||
version=1.21.4-R0.1-SNAPSHOT
|
version=1.21.4-R0.1-SNAPSHOT
|
||||||
mcVersion=1.21.4
|
mcVersion=1.21.4
|
||||||
paperRef=b03d39b5ce6b5046ce6854ddba74e8ae3641c230
|
paperRef=b03d39b5ce6b5046ce6854ddba74e8ae3641c230
|
||||||
@@ -7,3 +7,5 @@ org.gradle.configuration-cache=true
|
|||||||
org.gradle.caching=true
|
org.gradle.caching=true
|
||||||
org.gradle.parallel=true
|
org.gradle.parallel=true
|
||||||
org.gradle.vfs.watch=false
|
org.gradle.vfs.watch=false
|
||||||
|
|
||||||
|
edenVersion = 2.3.0-SNAPSHOT
|
||||||
@@ -1,5 +1,22 @@
|
|||||||
--- a/paper-api/build.gradle.kts
|
--- a/paper-api/build.gradle.kts
|
||||||
+++ b/paper-api/build.gradle.kts
|
+++ b/paper-api/build.gradle.kts
|
||||||
|
@@ -15,6 +_,8 @@
|
||||||
|
val slf4jVersion = "2.0.9"
|
||||||
|
val log4jVersion = "2.17.1"
|
||||||
|
|
||||||
|
+val edenVersion: String by project // Parchment
|
||||||
|
+
|
||||||
|
val apiAndDocs: Configuration by configurations.creating {
|
||||||
|
attributes {
|
||||||
|
attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category.DOCUMENTATION))
|
||||||
|
@@ -39,6 +_,7 @@
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
+ api("gg.projecteden:eden-interfaces:$edenVersion") // Parchment
|
||||||
|
|
||||||
|
// api dependencies are listed transitively to API consumers
|
||||||
|
api("com.google.guava:guava:33.3.1-jre")
|
||||||
@@ -103,6 +_,18 @@
|
@@ -103,6 +_,18 @@
|
||||||
main {
|
main {
|
||||||
java {
|
java {
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
--- a/src/main/java/com/destroystokyo/paper/event/block/BeaconEffectEvent.java
|
||||||
|
+++ b/src/main/java/com/destroystokyo/paper/event/block/BeaconEffectEvent.java
|
||||||
|
@@ -13,7 +_,7 @@
|
||||||
|
* Called when a beacon effect is being applied to a player.
|
||||||
|
*/
|
||||||
|
@NullMarked
|
||||||
|
-public class BeaconEffectEvent extends BlockEvent implements Cancellable {
|
||||||
|
+public class BeaconEffectEvent extends BlockEvent implements Cancellable, gg.projecteden.parchment.HasPlayer { // Parchment
|
||||||
|
|
||||||
|
private static final HandlerList HANDLER_LIST = new HandlerList();
|
||||||
|
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
--- a/src/main/java/com/destroystokyo/paper/event/entity/EndermanAttackPlayerEvent.java
|
||||||
|
+++ b/src/main/java/com/destroystokyo/paper/event/entity/EndermanAttackPlayerEvent.java
|
||||||
|
@@ -38,7 +_,7 @@
|
||||||
|
* at the Enderman, according to Vanilla rules.
|
||||||
|
*/
|
||||||
|
@NullMarked
|
||||||
|
-public class EndermanAttackPlayerEvent extends EntityEvent implements Cancellable {
|
||||||
|
+public class EndermanAttackPlayerEvent extends EntityEvent implements Cancellable, gg.projecteden.parchment.HasPlayer { // Parchment
|
||||||
|
|
||||||
|
private static final HandlerList HANDLER_LIST = new HandlerList();
|
||||||
|
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
--- a/src/main/java/com/destroystokyo/paper/event/entity/TurtleLayEggEvent.java
|
||||||
|
+++ b/src/main/java/com/destroystokyo/paper/event/entity/TurtleLayEggEvent.java
|
||||||
|
@@ -12,7 +_,7 @@
|
||||||
|
* Fired when a Turtle lays eggs
|
||||||
|
*/
|
||||||
|
@NullMarked
|
||||||
|
-public class TurtleLayEggEvent extends EntityEvent implements Cancellable {
|
||||||
|
+public class TurtleLayEggEvent extends EntityEvent implements Cancellable, gg.projecteden.parchment.HasLocation { // Parchment
|
||||||
|
|
||||||
|
private static final HandlerList HANDLER_LIST = new HandlerList();
|
||||||
|
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
--- a/src/main/java/com/destroystokyo/paper/event/entity/TurtleStartDiggingEvent.java
|
||||||
|
+++ b/src/main/java/com/destroystokyo/paper/event/entity/TurtleStartDiggingEvent.java
|
||||||
|
@@ -12,7 +_,7 @@
|
||||||
|
* Fired when a Turtle starts digging to lay eggs
|
||||||
|
*/
|
||||||
|
@NullMarked
|
||||||
|
-public class TurtleStartDiggingEvent extends EntityEvent implements Cancellable {
|
||||||
|
+public class TurtleStartDiggingEvent extends EntityEvent implements Cancellable, gg.projecteden.parchment.HasLocation { // Parchment
|
||||||
|
|
||||||
|
private static final HandlerList HANDLER_LIST = new HandlerList();
|
||||||
|
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
--- a/src/main/java/com/destroystokyo/paper/event/player/PlayerHandshakeEvent.java
|
||||||
|
+++ b/src/main/java/com/destroystokyo/paper/event/player/PlayerHandshakeEvent.java
|
||||||
|
@@ -21,7 +_,7 @@
|
||||||
|
* <p>WARNING: TAMPERING WITH THIS EVENT CAN BE DANGEROUS</p>
|
||||||
|
*/
|
||||||
|
@NullMarked
|
||||||
|
-public class PlayerHandshakeEvent extends Event implements Cancellable {
|
||||||
|
+public class PlayerHandshakeEvent extends Event implements Cancellable, gg.projecteden.api.interfaces.OptionalUniqueId { // Parchment
|
||||||
|
|
||||||
|
private static final HandlerList HANDLER_LIST = new HandlerList();
|
||||||
|
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
--- a/src/main/java/com/destroystokyo/paper/event/profile/PreLookupProfileEvent.java
|
||||||
|
+++ b/src/main/java/com/destroystokyo/paper/event/profile/PreLookupProfileEvent.java
|
||||||
|
@@ -22,7 +_,7 @@
|
||||||
|
* {@link Event#isAsynchronous()}
|
||||||
|
*/
|
||||||
|
@NullMarked
|
||||||
|
-public class PreLookupProfileEvent extends Event {
|
||||||
|
+public class PreLookupProfileEvent extends Event implements gg.projecteden.api.interfaces.OptionalUniqueId { // Parchment
|
||||||
|
|
||||||
|
private static final HandlerList HANDLER_LIST = new HandlerList();
|
||||||
|
|
||||||
|
@@ -52,6 +_,10 @@
|
||||||
|
* @return The UUID of the profile if it has already been provided by a plugin
|
||||||
|
*/
|
||||||
|
public @Nullable UUID getUUID() {
|
||||||
|
+ return this.uuid;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public UUID getUniqueId() {
|
||||||
|
return this.uuid;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
--- a/src/main/java/com/destroystokyo/paper/event/server/AsyncTabCompleteEvent.java
|
||||||
|
+++ b/src/main/java/com/destroystokyo/paper/event/server/AsyncTabCompleteEvent.java
|
||||||
|
@@ -53,7 +_,7 @@
|
||||||
|
* Only 1 process will be allowed to provide completions, the Async Event, or the standard process.
|
||||||
|
*/
|
||||||
|
@NullMarked
|
||||||
|
-public class AsyncTabCompleteEvent extends Event implements Cancellable {
|
||||||
|
+public class AsyncTabCompleteEvent extends Event implements Cancellable, gg.projecteden.parchment.OptionalLocation { // Parchment
|
||||||
|
|
||||||
|
private static final HandlerList HANDLER_LIST = new HandlerList();
|
||||||
|
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
--- a/src/main/java/com/destroystokyo/paper/exception/ServerPluginMessageException.java
|
||||||
|
+++ b/src/main/java/com/destroystokyo/paper/exception/ServerPluginMessageException.java
|
||||||
|
@@ -8,7 +_,7 @@
|
||||||
|
/**
|
||||||
|
* Thrown when an incoming plugin message channel throws an exception
|
||||||
|
*/
|
||||||
|
-public class ServerPluginMessageException extends ServerPluginException {
|
||||||
|
+public class ServerPluginMessageException extends ServerPluginException implements gg.projecteden.parchment.HasPlayer { // Parchment
|
||||||
|
|
||||||
|
private final Player player;
|
||||||
|
private final String channel;
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
--- a/src/main/java/io/papermc/paper/event/packet/PlayerChunkLoadEvent.java
|
||||||
|
+++ b/src/main/java/io/papermc/paper/event/packet/PlayerChunkLoadEvent.java
|
||||||
|
@@ -16,7 +_,7 @@
|
||||||
|
* Not intended for modifying server side state.
|
||||||
|
*/
|
||||||
|
@NullMarked
|
||||||
|
-public class PlayerChunkLoadEvent extends ChunkEvent {
|
||||||
|
+public class PlayerChunkLoadEvent extends ChunkEvent implements gg.projecteden.parchment.HasPlayer { // Parchment
|
||||||
|
|
||||||
|
private static final HandlerList HANDLER_LIST = new HandlerList();
|
||||||
|
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
--- a/src/main/java/io/papermc/paper/event/packet/PlayerChunkUnloadEvent.java
|
||||||
|
+++ b/src/main/java/io/papermc/paper/event/packet/PlayerChunkUnloadEvent.java
|
||||||
|
@@ -14,7 +_,7 @@
|
||||||
|
* Not intended for modifying server side.
|
||||||
|
*/
|
||||||
|
@NullMarked
|
||||||
|
-public class PlayerChunkUnloadEvent extends ChunkEvent {
|
||||||
|
+public class PlayerChunkUnloadEvent extends ChunkEvent implements gg.projecteden.parchment.HasPlayer { // Parchment
|
||||||
|
|
||||||
|
private static final HandlerList HANDLER_LIST = new HandlerList();
|
||||||
|
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
--- a/src/main/java/org/bukkit/ChatColor.java
|
||||||
|
+++ b/src/main/java/org/bukkit/ChatColor.java
|
||||||
|
@@ -13,7 +_,7 @@
|
||||||
|
* @deprecated ChatColor has been deprecated in favor of <a href="https://docs.advntr.dev/text.html">Adventure</a> API. See {@link net.kyori.adventure.text.format.NamedTextColor} for the adventure equivalent of pre-defined text colors
|
||||||
|
*/
|
||||||
|
@Deprecated // Paper
|
||||||
|
-public enum ChatColor {
|
||||||
|
+public enum ChatColor implements net.kyori.adventure.text.format.StyleBuilderApplicable, net.kyori.adventure.text.format.TextFormat { // Parchment
|
||||||
|
/**
|
||||||
|
* Represents black
|
||||||
|
*/
|
||||||
|
@@ -183,6 +_,13 @@
|
||||||
|
public net.md_5.bungee.api.ChatColor asBungee() {
|
||||||
|
return net.md_5.bungee.api.ChatColor.MAGIC;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ // Parchment start
|
||||||
|
+ @Override
|
||||||
|
+ public void styleApply(net.kyori.adventure.text.format.Style.@NotNull Builder style) {
|
||||||
|
+ style.apply(net.kyori.adventure.text.format.TextDecoration.OBFUSCATED);
|
||||||
|
+ }
|
||||||
|
+ // Parchment end
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Makes the text bold.
|
||||||
|
@@ -213,6 +_,13 @@
|
||||||
|
public net.md_5.bungee.api.ChatColor asBungee() {
|
||||||
|
return net.md_5.bungee.api.ChatColor.UNDERLINE;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ // Parchment start
|
||||||
|
+ @Override
|
||||||
|
+ public void styleApply(net.kyori.adventure.text.format.Style.@NotNull Builder style) {
|
||||||
|
+ style.apply(net.kyori.adventure.text.format.TextDecoration.UNDERLINED);
|
||||||
|
+ }
|
||||||
|
+ // Parchment end
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Makes the text italic.
|
||||||
|
@@ -233,6 +_,16 @@
|
||||||
|
public net.md_5.bungee.api.ChatColor asBungee() {
|
||||||
|
return net.md_5.bungee.api.ChatColor.RESET;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ // Parchment start
|
||||||
|
+ @Override
|
||||||
|
+ public void styleApply(net.kyori.adventure.text.format.Style.@NotNull Builder style) {
|
||||||
|
+ style.color(null);
|
||||||
|
+ for (net.kyori.adventure.text.format.TextDecoration decoration : net.kyori.adventure.text.format.TextDecoration.values()) {
|
||||||
|
+ style.decoration(decoration, net.kyori.adventure.text.format.TextDecoration.State.NOT_SET);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ // Parchment end
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
@@ -264,6 +_,16 @@
|
||||||
|
public net.md_5.bungee.api.ChatColor asBungee() {
|
||||||
|
return net.md_5.bungee.api.ChatColor.RESET;
|
||||||
|
};
|
||||||
|
+
|
||||||
|
+ // Parchment start
|
||||||
|
+ @Override
|
||||||
|
+ public void styleApply(net.kyori.adventure.text.format.Style.@NotNull Builder style) {
|
||||||
|
+ if (isColor())
|
||||||
|
+ style.color(net.kyori.adventure.text.format.TextColor.color(asBungee().getColor().getRGB()));
|
||||||
|
+ else
|
||||||
|
+ style.decorate(net.kyori.adventure.text.format.TextDecoration.valueOf(name()));
|
||||||
|
+ }
|
||||||
|
+ // Parchment end
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the char value associated with this color
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
--- a/src/main/java/org/bukkit/Color.java
|
||||||
|
+++ b/src/main/java/org/bukkit/Color.java
|
||||||
|
@@ -17,7 +_,7 @@
|
||||||
|
* but subject to change.
|
||||||
|
*/
|
||||||
|
@SerializableAs("Color")
|
||||||
|
-public final class Color implements ConfigurationSerializable {
|
||||||
|
+public final class Color implements ConfigurationSerializable, net.kyori.adventure.text.format.TextColor { // Parchment
|
||||||
|
private static final int BIT_MASK = 0xff;
|
||||||
|
private static final int DEFAULT_ALPHA = 255;
|
||||||
|
|
||||||
|
@@ -309,6 +_,13 @@
|
||||||
|
public int asARGB() {
|
||||||
|
return getAlpha() << 24 | getRed() << 16 | getGreen() << 8 | getBlue();
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ // Parchment start
|
||||||
|
+ @Override
|
||||||
|
+ public int value() {
|
||||||
|
+ return asRGB();
|
||||||
|
+ }
|
||||||
|
+ // Parchment end
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the color as an BGR integer.
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
--- a/src/main/java/org/bukkit/DyeColor.java
|
||||||
|
+++ b/src/main/java/org/bukkit/DyeColor.java
|
||||||
|
@@ -8,7 +_,7 @@
|
||||||
|
/**
|
||||||
|
* All supported color values for dyes and cloth
|
||||||
|
*/
|
||||||
|
-public enum DyeColor {
|
||||||
|
+public enum DyeColor implements net.kyori.adventure.util.RGBLike, net.kyori.adventure.text.format.StyleBuilderApplicable { // Parchment
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents white dye.
|
||||||
|
@@ -134,6 +_,28 @@
|
||||||
|
public Color getFireworkColor() {
|
||||||
|
return firework;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ // Parchment start
|
||||||
|
+ @Override
|
||||||
|
+ public @org.jetbrains.annotations.Range(from = 0L, to = 255L) int red() {
|
||||||
|
+ return color.getRed();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public @org.jetbrains.annotations.Range(from = 0L, to = 255L) int green() {
|
||||||
|
+ return color.getGreen();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public @org.jetbrains.annotations.Range(from = 0L, to = 255L) int blue() {
|
||||||
|
+ return color.getBlue();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Override
|
||||||
|
+ public void styleApply(net.kyori.adventure.text.format.Style.@org.jetbrains.annotations.NotNull Builder style) {
|
||||||
|
+ style.color(net.kyori.adventure.text.format.TextColor.color(color));
|
||||||
|
+ }
|
||||||
|
+ // Parchment end
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the DyeColor with the given wool data value.
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
--- a/src/main/java/org/bukkit/Location.java
|
||||||
|
+++ b/src/main/java/org/bukkit/Location.java
|
||||||
|
@@ -27,13 +_,20 @@
|
||||||
|
* magnitude than 360 are valid, but may be normalized to any other equivalent
|
||||||
|
* representation by the implementation.
|
||||||
|
*/
|
||||||
|
-public class Location implements Cloneable, ConfigurationSerializable, io.papermc.paper.math.FinePosition {
|
||||||
|
+public class Location implements Cloneable, ConfigurationSerializable, io.papermc.paper.math.FinePosition, gg.projecteden.parchment.HasLocation { // Paper // Parchment
|
||||||
|
private Reference<World> world;
|
||||||
|
private double x;
|
||||||
|
private double y;
|
||||||
|
private double z;
|
||||||
|
private float pitch;
|
||||||
|
private float yaw;
|
||||||
|
+
|
||||||
|
+ // Parchment start
|
||||||
|
+ @Override
|
||||||
|
+ public @NotNull Location getLocation() {
|
||||||
|
+ return this;
|
||||||
|
+ }
|
||||||
|
+ // Parchment end
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new Location with the given coordinates
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
--- a/src/main/java/org/bukkit/OfflinePlayer.java
|
||||||
|
+++ b/src/main/java/org/bukkit/OfflinePlayer.java
|
||||||
|
@@ -19,7 +_,14 @@
|
||||||
|
* player that is stored on the disk and can, thus, be retrieved without the
|
||||||
|
* player needing to be online.
|
||||||
|
*/
|
||||||
|
-public interface OfflinePlayer extends ServerOperator, AnimalTamer, ConfigurationSerializable, io.papermc.paper.persistence.PersistentDataViewHolder { // Paper - Add Offline PDC API
|
||||||
|
+public interface OfflinePlayer extends ServerOperator, AnimalTamer, ConfigurationSerializable, io.papermc.paper.persistence.PersistentDataViewHolder, gg.projecteden.parchment.HasOfflinePlayer, gg.projecteden.parchment.OptionalPlayer { // Parchment
|
||||||
|
+
|
||||||
|
+ // Parchment start
|
||||||
|
+ @Override
|
||||||
|
+ default @org.jetbrains.annotations.NotNull OfflinePlayer getOfflinePlayer() {
|
||||||
|
+ return this;
|
||||||
|
+ }
|
||||||
|
+ // Parchment end
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if this player is currently online
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
--- a/src/main/java/org/bukkit/Raid.java
|
||||||
|
+++ b/src/main/java/org/bukkit/Raid.java
|
||||||
|
@@ -9,7 +_,7 @@
|
||||||
|
/**
|
||||||
|
* Represents a raid event.
|
||||||
|
*/
|
||||||
|
-public interface Raid extends org.bukkit.persistence.PersistentDataHolder { // Paper
|
||||||
|
+public interface Raid extends org.bukkit.persistence.PersistentDataHolder, gg.projecteden.parchment.HasLocation { // Paper // Parchment
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get whether this raid started.
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
--- a/src/main/java/org/bukkit/Vibration.java
|
||||||
|
+++ b/src/main/java/org/bukkit/Vibration.java
|
||||||
|
@@ -74,7 +_,8 @@
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- public static class BlockDestination implements Destination {
|
||||||
|
+ public static class BlockDestination implements Destination, gg.projecteden.parchment.HasLocation { // Parchment
|
||||||
|
+
|
||||||
|
|
||||||
|
private final Location block;
|
||||||
|
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
--- a/src/main/java/org/bukkit/World.java
|
||||||
|
+++ b/src/main/java/org/bukkit/World.java
|
||||||
|
@@ -52,6 +_,36 @@
|
||||||
|
*/
|
||||||
|
public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient, Metadatable, PersistentDataHolder, Keyed, net.kyori.adventure.audience.ForwardingAudience { // Paper
|
||||||
|
|
||||||
|
+ // Parchment start
|
||||||
|
+ /**
|
||||||
|
+ * Returns the item that will result from smelting the input item, if applicable.
|
||||||
|
+ *
|
||||||
|
+ * @param toSmelt the item to simulate smelting
|
||||||
|
+ * @return the resulting item, or null
|
||||||
|
+ */
|
||||||
|
+ @Nullable
|
||||||
|
+ default ItemStack smeltItem(@NotNull ItemStack toSmelt) {
|
||||||
|
+ return smeltItem(toSmelt, gg.projecteden.parchment.inventory.RecipeType.SMELTING);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * Returns the item that will result from smelting the input item, if applicable.
|
||||||
|
+ * <p>
|
||||||
|
+ * Applicable values for {@code recipeType} are
|
||||||
|
+ * {@link gg.projecteden.parchment.inventory.RecipeType#SMELTING SMELTING},
|
||||||
|
+ * {@link gg.projecteden.parchment.inventory.RecipeType#BLASTING BLASTING},
|
||||||
|
+ * {@link gg.projecteden.parchment.inventory.RecipeType#SMOKING SMOKING},
|
||||||
|
+ * and {@link gg.projecteden.parchment.inventory.RecipeType#CAMPFIRE_COOKING CAMPFIRE_COOKING}.
|
||||||
|
+ * An {@link IllegalArgumentException} will be thrown if another value is supplied.
|
||||||
|
+ *
|
||||||
|
+ * @param toSmelt the item to simulate smelting
|
||||||
|
+ * @param recipeType type of furnace to simulate smelting
|
||||||
|
+ * @return the resulting item, or null
|
||||||
|
+ */
|
||||||
|
+ @Nullable
|
||||||
|
+ ItemStack smeltItem(@NotNull ItemStack toSmelt, gg.projecteden.parchment.inventory.@NotNull RecipeType recipeType);
|
||||||
|
+ // Parchment end
|
||||||
|
+
|
||||||
|
// Paper start - void damage configuration
|
||||||
|
/**
|
||||||
|
* Checks if void damage is enabled on this world.
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
--- a/src/main/java/org/bukkit/attribute/AttributeModifier.java
|
||||||
|
+++ b/src/main/java/org/bukkit/attribute/AttributeModifier.java
|
||||||
|
@@ -20,7 +_,7 @@
|
||||||
|
/**
|
||||||
|
* Concrete implementation of an attribute modifier.
|
||||||
|
*/
|
||||||
|
-public class AttributeModifier implements ConfigurationSerializable, Keyed {
|
||||||
|
+public class AttributeModifier implements ConfigurationSerializable, Keyed, gg.projecteden.api.interfaces.HasUniqueId { // Parchment
|
||||||
|
|
||||||
|
private static final Pattern UUID_PATTERN = Pattern.compile("^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$");
|
||||||
|
private final NamespacedKey key;
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
--- a/src/main/java/org/bukkit/block/Block.java
|
||||||
|
+++ b/src/main/java/org/bukkit/block/Block.java
|
||||||
|
@@ -32,7 +_,7 @@
|
||||||
|
* (i.e. lighting and power) may not be able to be safely accessed during world
|
||||||
|
* generation when used in cases like BlockPhysicsEvent!!!!
|
||||||
|
*/
|
||||||
|
-public interface Block extends Metadatable, Translatable, net.kyori.adventure.translation.Translatable { // Paper - translatable
|
||||||
|
+public interface Block extends Metadatable, Translatable, net.kyori.adventure.translation.Translatable, gg.projecteden.parchment.HasLocation { // Paper - translatable // Parchment
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the metadata for this block
|
||||||
|
@@ -593,6 +_,20 @@
|
||||||
|
* @return true if the block was destroyed
|
||||||
|
*/
|
||||||
|
boolean breakNaturally(@NotNull ItemStack tool, boolean triggerEffect, boolean dropExperience);
|
||||||
|
+
|
||||||
|
+ // Parchment Start
|
||||||
|
+ /**
|
||||||
|
+ * Breaks the block and spawns item drops as if a player had broken it
|
||||||
|
+ * with a specific tool
|
||||||
|
+ *
|
||||||
|
+ * @param player The player to break the block as
|
||||||
|
+ * @param tool The tool or item in hand used for digging
|
||||||
|
+ * @param triggerEffect Play the block break particle effect and sound
|
||||||
|
+ * @param dropExperience drop exp if the block normally does so
|
||||||
|
+ * @return true if the block was destroyed
|
||||||
|
+ */
|
||||||
|
+ boolean breakNaturally(Player player, @NotNull ItemStack tool, boolean triggerEffect, boolean dropExperience);
|
||||||
|
+ // Parchment end
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Causes the block to be ticked, this is different from {@link Block#randomTick()},
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
--- a/src/main/java/org/bukkit/block/BlockState.java
|
||||||
|
+++ b/src/main/java/org/bukkit/block/BlockState.java
|
||||||
|
@@ -21,7 +_,7 @@
|
||||||
|
* change the state of the block and you will not know, or they may change the
|
||||||
|
* block to another type entirely, causing your BlockState to become invalid.
|
||||||
|
*/
|
||||||
|
-public interface BlockState extends Metadatable {
|
||||||
|
+public interface BlockState extends Metadatable, gg.projecteden.parchment.HasLocation { // Parchment
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the block represented by this block state.
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
--- a/src/main/java/org/bukkit/block/DoubleChest.java
|
||||||
|
+++ b/src/main/java/org/bukkit/block/DoubleChest.java
|
||||||
|
@@ -11,7 +_,7 @@
|
||||||
|
/**
|
||||||
|
* Represents a double chest.
|
||||||
|
*/
|
||||||
|
-public class DoubleChest implements InventoryHolder {
|
||||||
|
+public class DoubleChest implements InventoryHolder, gg.projecteden.parchment.HasLocation { // Parchment
|
||||||
|
private DoubleChestInventory inventory;
|
||||||
|
|
||||||
|
public DoubleChest(@NotNull DoubleChestInventory chest) {
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
--- a/src/main/java/org/bukkit/entity/AnimalTamer.java
|
||||||
|
+++ b/src/main/java/org/bukkit/entity/AnimalTamer.java
|
||||||
|
@@ -4,7 +_,8 @@
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
-public interface AnimalTamer {
|
||||||
|
+public interface AnimalTamer extends gg.projecteden.api.interfaces.HasUniqueId { // Parchment
|
||||||
|
+
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the name of the specified AnimalTamer.
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
--- a/src/main/java/org/bukkit/entity/Entity.java
|
||||||
|
+++ b/src/main/java/org/bukkit/entity/Entity.java
|
||||||
|
@@ -33,7 +_,7 @@
|
||||||
|
* Not all methods are guaranteed to work/may have side effects when
|
||||||
|
* {@link #isInWorld()} is false.
|
||||||
|
*/
|
||||||
|
-public interface Entity extends Metadatable, CommandSender, Nameable, PersistentDataHolder, net.kyori.adventure.text.event.HoverEventSource<net.kyori.adventure.text.event.HoverEvent.ShowEntity>, net.kyori.adventure.sound.Sound.Emitter { // Paper
|
||||||
|
+public interface Entity extends Metadatable, CommandSender, Nameable, PersistentDataHolder, net.kyori.adventure.text.event.HoverEventSource<net.kyori.adventure.text.event.HoverEvent.ShowEntity>, net.kyori.adventure.sound.Sound.Emitter, gg.projecteden.api.interfaces.HasUniqueId, gg.projecteden.parchment.HasLocation { // Paper // Parchment
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the entity's current position
|
||||||
|
@@ -1196,4 +_,7 @@
|
||||||
|
*/
|
||||||
|
void broadcastHurtAnimation(@NotNull java.util.Collection<Player> players);
|
||||||
|
// Paper end - broadcast hurt animation
|
||||||
|
+
|
||||||
|
+ gg.projecteden.parchment.entity.EntityData getStoredEntityData();
|
||||||
|
+
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
--- a/src/main/java/org/bukkit/entity/EntityType.java
|
||||||
|
+++ b/src/main/java/org/bukkit/entity/EntityType.java
|
||||||
|
@@ -341,6 +_,7 @@
|
||||||
|
/**
|
||||||
|
* An unknown entity without an Entity Class
|
||||||
|
*/
|
||||||
|
+ NPC("npc", NPC.class, -1, true),
|
||||||
|
UNKNOWN(null, null, -1, false);
|
||||||
|
|
||||||
|
private final String name;
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
--- a/src/main/java/org/bukkit/entity/Hanging.java
|
||||||
|
+++ b/src/main/java/org/bukkit/entity/Hanging.java
|
||||||
|
@@ -20,4 +_,22 @@
|
||||||
|
* attach to in order to face the given direction.
|
||||||
|
*/
|
||||||
|
public boolean setFacingDirection(@NotNull BlockFace face, boolean force);
|
||||||
|
+
|
||||||
|
+ // Parchment start
|
||||||
|
+ /**
|
||||||
|
+ * Determines whether the hanging entity is allowed to tick.
|
||||||
|
+ * Ticking is used to validate the hanging entity's placement.
|
||||||
|
+ *
|
||||||
|
+ * @return True if the entity is allowed to tick.
|
||||||
|
+ */
|
||||||
|
+ default boolean canTick() { return true; }
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * Sets whether the hanging entity is allowed to tick.
|
||||||
|
+ * Ticking is used to validate the hanging entity's placement.
|
||||||
|
+ *
|
||||||
|
+ * @param tick True if the entity is allowed to tick.
|
||||||
|
+ */
|
||||||
|
+ default void setCanTick(boolean tick) { throw new UnsupportedOperationException(); }
|
||||||
|
+ // Parchment end
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
--- a/src/main/java/org/bukkit/entity/HumanEntity.java
|
||||||
|
+++ b/src/main/java/org/bukkit/entity/HumanEntity.java
|
||||||
|
@@ -23,7 +_,14 @@
|
||||||
|
/**
|
||||||
|
* Represents a human entity, such as an NPC or a player
|
||||||
|
*/
|
||||||
|
-public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder {
|
||||||
|
+public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder, gg.projecteden.parchment.HasHumanEntity { // Parchment
|
||||||
|
+
|
||||||
|
+ // Parchment start
|
||||||
|
+ @Override
|
||||||
|
+ default @NotNull HumanEntity getPlayer() {
|
||||||
|
+ return this;
|
||||||
|
+ }
|
||||||
|
+ // Parchment end
|
||||||
|
|
||||||
|
// Paper start
|
||||||
|
@Override
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
--- a/src/main/java/org/bukkit/entity/Player.java
|
||||||
|
+++ b/src/main/java/org/bukkit/entity/Player.java
|
||||||
|
@@ -59,7 +_,17 @@
|
||||||
|
/**
|
||||||
|
* Represents a player, connected or not
|
||||||
|
*/
|
||||||
|
-public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginMessageRecipient, net.kyori.adventure.identity.Identified, net.kyori.adventure.bossbar.BossBarViewer, com.destroystokyo.paper.network.NetworkClient { // Paper
|
||||||
|
+public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginMessageRecipient, net.kyori.adventure.identity.Identified, net.kyori.adventure.bossbar.BossBarViewer, com.destroystokyo.paper.network.NetworkClient , gg.projecteden.parchment.HasPlayer { // Paper // Parchment
|
||||||
|
+
|
||||||
|
+ // Parchment start
|
||||||
|
+ /**
|
||||||
|
+ * Returns this player object.
|
||||||
|
+ *
|
||||||
|
+ * @return this player
|
||||||
|
+ */
|
||||||
|
+ @Override
|
||||||
|
+ @NotNull Player getPlayer();
|
||||||
|
+ // Parchment end
|
||||||
|
|
||||||
|
// Paper start
|
||||||
|
@Override
|
||||||
|
@@ -2128,6 +_,17 @@
|
||||||
|
*/
|
||||||
|
public boolean canSee(@NotNull Entity entity);
|
||||||
|
|
||||||
|
+ // Parchment start
|
||||||
|
+ /**
|
||||||
|
+ * Gets a view of the hidden entity UUIDs.
|
||||||
|
+ *
|
||||||
|
+ * @param plugin Plugin that has hidden entities
|
||||||
|
+ * @return a view of hidden entity UUIDs
|
||||||
|
+ */
|
||||||
|
+ public java.util.@NotNull Set<java.util.UUID> getHiddenEntities(@NotNull Plugin plugin);
|
||||||
|
+ // Parchment end
|
||||||
|
+
|
||||||
|
+
|
||||||
|
// Paper start
|
||||||
|
/**
|
||||||
|
* Returns whether the {@code other} player is listed for {@code this}.
|
||||||
|
@@ -3892,4 +_,45 @@
|
||||||
|
*/
|
||||||
|
void sendEntityEffect(org.bukkit.@NotNull EntityEffect effect, @NotNull Entity target);
|
||||||
|
// Paper end - entity effect API
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * Checks if the player will spawn phantoms at night
|
||||||
|
+ * Uses time since last rest statistic
|
||||||
|
+ *
|
||||||
|
+ * {@link #getTimeSinceLastRest()}
|
||||||
|
+ *
|
||||||
|
+ * @return if the player will spawn phantoms at night
|
||||||
|
+ */
|
||||||
|
+ boolean isInsomniac();
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * Sets if the player bypasses phantom spawning if insomniac
|
||||||
|
+ *
|
||||||
|
+ * @param val
|
||||||
|
+ */
|
||||||
|
+ void setBypassInsomnia(boolean val);
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * Does the player bypass phantom spawning if insomniac
|
||||||
|
+ *
|
||||||
|
+ * @return if the player bypasses phantom spawning
|
||||||
|
+ */
|
||||||
|
+ boolean doesBypassInsomnia();
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * Set the time since last rest stat for the player
|
||||||
|
+ * This modifies the phantom spawning timer
|
||||||
|
+ *
|
||||||
|
+ * @param ticks how long since last rest, greater than or equal to 1
|
||||||
|
+ */
|
||||||
|
+ void setTimeSinceLastRest(int ticks);
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * Gets the time since the player last slept
|
||||||
|
+ *
|
||||||
|
+ * @return ticks since the player last slept
|
||||||
|
+ */
|
||||||
|
+ int getTimeSinceLastRest();
|
||||||
|
+// Parchment end
|
||||||
|
+
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
--- a/src/main/java/org/bukkit/event/block/BlockBreakEvent.java
|
||||||
|
+++ b/src/main/java/org/bukkit/event/block/BlockBreakEvent.java
|
||||||
|
@@ -26,7 +_,7 @@
|
||||||
|
* If a Block Break event is cancelled, the block will not break and
|
||||||
|
* experience will not drop.
|
||||||
|
*/
|
||||||
|
-public class BlockBreakEvent extends BlockExpEvent implements Cancellable {
|
||||||
|
+public class BlockBreakEvent extends BlockExpEvent implements Cancellable, gg.projecteden.parchment.HasPlayer { // Parchment
|
||||||
|
private final Player player;
|
||||||
|
private boolean dropItems;
|
||||||
|
private boolean cancel;
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
--- a/src/main/java/org/bukkit/event/block/BlockCanBuildEvent.java
|
||||||
|
+++ b/src/main/java/org/bukkit/event/block/BlockCanBuildEvent.java
|
||||||
|
@@ -19,7 +_,7 @@
|
||||||
|
* #getMaterial()} instead.
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
-public class BlockCanBuildEvent extends BlockEvent {
|
||||||
|
+public class BlockCanBuildEvent extends BlockEvent implements gg.projecteden.parchment.OptionalPlayer { // Parchment
|
||||||
|
private static final HandlerList handlers = new HandlerList();
|
||||||
|
protected boolean buildable;
|
||||||
|
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
--- a/src/main/java/org/bukkit/event/block/BlockDamageEvent.java
|
||||||
|
+++ b/src/main/java/org/bukkit/event/block/BlockDamageEvent.java
|
||||||
|
@@ -13,7 +_,7 @@
|
||||||
|
* If a Block Damage event is cancelled, the block will not be damaged.
|
||||||
|
* @see BlockDamageAbortEvent
|
||||||
|
*/
|
||||||
|
-public class BlockDamageEvent extends BlockEvent implements Cancellable {
|
||||||
|
+public class BlockDamageEvent extends BlockEvent implements Cancellable, gg.projecteden.parchment.HasPlayer { // Parchment
|
||||||
|
private static final HandlerList handlers = new HandlerList();
|
||||||
|
private final Player player;
|
||||||
|
private boolean instaBreak;
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
--- a/src/main/java/org/bukkit/event/block/BlockDropItemEvent.java
|
||||||
|
+++ b/src/main/java/org/bukkit/event/block/BlockDropItemEvent.java
|
||||||
|
@@ -28,7 +_,7 @@
|
||||||
|
* AIR in most cases. Use #getBlockState() for more Information about the broken
|
||||||
|
* block.
|
||||||
|
*/
|
||||||
|
-public class BlockDropItemEvent extends BlockEvent implements Cancellable {
|
||||||
|
+public class BlockDropItemEvent extends BlockEvent implements Cancellable, gg.projecteden.parchment.HasPlayer { // Parchment
|
||||||
|
|
||||||
|
private static final HandlerList handlers = new HandlerList();
|
||||||
|
private final Player player;
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
--- a/src/main/java/org/bukkit/event/block/BlockFertilizeEvent.java
|
||||||
|
+++ b/src/main/java/org/bukkit/event/block/BlockFertilizeEvent.java
|
||||||
|
@@ -15,7 +_,7 @@
|
||||||
|
* block with bonemeal. Will be called after the applicable
|
||||||
|
* {@link StructureGrowEvent}.
|
||||||
|
*/
|
||||||
|
-public class BlockFertilizeEvent extends BlockEvent implements Cancellable {
|
||||||
|
+public class BlockFertilizeEvent extends BlockEvent implements Cancellable, gg.projecteden.parchment.HasPlayer { // Parchment
|
||||||
|
|
||||||
|
private static final HandlerList handlers = new HandlerList();
|
||||||
|
private boolean cancelled;
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
--- a/src/main/java/org/bukkit/event/block/BlockIgniteEvent.java
|
||||||
|
+++ b/src/main/java/org/bukkit/event/block/BlockIgniteEvent.java
|
||||||
|
@@ -14,7 +_,7 @@
|
||||||
|
* <p>
|
||||||
|
* If a Block Ignite event is cancelled, the block will not be ignited.
|
||||||
|
*/
|
||||||
|
-public class BlockIgniteEvent extends BlockEvent implements Cancellable {
|
||||||
|
+public class BlockIgniteEvent extends BlockEvent implements Cancellable, gg.projecteden.parchment.OptionalPlayer { // Parchment
|
||||||
|
private static final HandlerList handlers = new HandlerList();
|
||||||
|
private final IgniteCause cause;
|
||||||
|
private final Entity ignitingEntity;
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
--- a/src/main/java/org/bukkit/event/block/BlockPlaceEvent.java
|
||||||
|
+++ b/src/main/java/org/bukkit/event/block/BlockPlaceEvent.java
|
||||||
|
@@ -14,7 +_,7 @@
|
||||||
|
* <p>
|
||||||
|
* If a Block Place event is cancelled, the block will not be placed.
|
||||||
|
*/
|
||||||
|
-public class BlockPlaceEvent extends BlockEvent implements Cancellable {
|
||||||
|
+public class BlockPlaceEvent extends BlockEvent implements Cancellable, gg.projecteden.parchment.HasPlayer { // Parchment
|
||||||
|
private static final HandlerList handlers = new HandlerList();
|
||||||
|
protected boolean cancel;
|
||||||
|
protected boolean canBuild;
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
--- a/src/main/java/org/bukkit/event/block/SignChangeEvent.java
|
||||||
|
+++ b/src/main/java/org/bukkit/event/block/SignChangeEvent.java
|
||||||
|
@@ -13,7 +_,7 @@
|
||||||
|
* <p>
|
||||||
|
* If a Sign Change event is cancelled, the sign will not be changed.
|
||||||
|
*/
|
||||||
|
-public class SignChangeEvent extends BlockEvent implements Cancellable {
|
||||||
|
+public class SignChangeEvent extends BlockEvent implements Cancellable, gg.projecteden.parchment.HasPlayer { // Parchment
|
||||||
|
private static final HandlerList handlers = new HandlerList();
|
||||||
|
private boolean cancel = false;
|
||||||
|
private final Player player;
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
--- a/src/main/java/org/bukkit/event/entity/EntityDamageByBlockEvent.java
|
||||||
|
+++ b/src/main/java/org/bukkit/event/entity/EntityDamageByBlockEvent.java
|
||||||
|
@@ -20,6 +_,7 @@
|
||||||
|
public class EntityDamageByBlockEvent extends EntityDamageEvent {
|
||||||
|
private final Block damager;
|
||||||
|
private final BlockState damagerState;
|
||||||
|
+ private final org.bukkit.Location location; // Parchment
|
||||||
|
|
||||||
|
@Deprecated(since = "1.20.4", forRemoval = true)
|
||||||
|
public EntityDamageByBlockEvent(@Nullable final Block damager, @NotNull final Entity damagee, @NotNull final DamageCause cause, final double damage) {
|
||||||
|
@@ -30,18 +_,39 @@
|
||||||
|
super(damagee, cause, damageSource, damage);
|
||||||
|
this.damager = damager;
|
||||||
|
this.damagerState = damagerState;
|
||||||
|
+ this.location = damager != null ? damager.getLocation() : null; // Parchment
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated(since = "1.20.4", forRemoval = true)
|
||||||
|
public EntityDamageByBlockEvent(@Nullable final Block damager, @NotNull final Entity damagee, @NotNull final DamageCause cause, @NotNull final Map<DamageModifier, Double> modifiers, @NotNull final Map<DamageModifier, ? extends Function<? super Double, Double>> modifierFunctions) {
|
||||||
|
- this(damager, (damager != null) ? damager.getState() : null, damagee, cause, (damager != null) ? DamageSource.builder(DamageType.GENERIC).withDamageLocation(damager.getLocation()).build() : DamageSource.builder(DamageType.GENERIC).build(), modifiers, modifierFunctions);
|
||||||
|
+ this(damager, (damager != null) ? damager.getState() : null, damagee, cause, (damager != null) ? DamageSource.builder(DamageType.GENERIC).withDamageLocation(damager.getLocation()).build() : DamageSource.builder(DamageType.GENERIC).build(), modifiers, modifierFunctions, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
- public EntityDamageByBlockEvent(@Nullable final Block damager, @Nullable final BlockState damagerState, @NotNull final Entity damagee, @NotNull final DamageCause cause, @NotNull final DamageSource damageSource, @NotNull final Map<DamageModifier, Double> modifiers, @NotNull final Map<DamageModifier, ? extends Function<? super Double, Double>> modifierFunctions) {
|
||||||
|
+ public EntityDamageByBlockEvent(@Nullable final Block damager, @Nullable final BlockState damagerState, @NotNull final Entity damagee, @NotNull final DamageCause cause, @NotNull final DamageSource damageSource, @NotNull final Map<DamageModifier, Double> modifiers, @NotNull final Map<DamageModifier, ? extends Function<? super Double, Double>> modifierFunctions, @Nullable final org.bukkit.Location damageLocation) { // Parchment
|
||||||
|
super(damagee, cause, damageSource, modifiers, modifierFunctions);
|
||||||
|
this.damager = damager;
|
||||||
|
this.damagerState = damagerState;
|
||||||
|
- }
|
||||||
|
+ // Parchment start
|
||||||
|
+ if (damageLocation != null)
|
||||||
|
+ this.location = damageLocation;
|
||||||
|
+ else if (damager != null)
|
||||||
|
+ this.location = damager.getLocation();
|
||||||
|
+ else
|
||||||
|
+ this.location = null;
|
||||||
|
+ // Parchment end
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // Parchment - add Location
|
||||||
|
+ /**
|
||||||
|
+ * Gets the location of the damage source.
|
||||||
|
+ *
|
||||||
|
+ * @return Originating location of the damage source
|
||||||
|
+ */
|
||||||
|
+ @Nullable
|
||||||
|
+ public org.bukkit.Location getLocation() {
|
||||||
|
+ return location;
|
||||||
|
+ }
|
||||||
|
+ // Parchment end
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the block that damaged the player.
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
--- a/src/main/java/org/bukkit/event/entity/EntityEnterLoveModeEvent.java
|
||||||
|
+++ b/src/main/java/org/bukkit/event/entity/EntityEnterLoveModeEvent.java
|
||||||
|
@@ -13,7 +_,7 @@
|
||||||
|
* This can be cancelled but the item will still be consumed that was used to
|
||||||
|
* make the entity enter into love mode.
|
||||||
|
*/
|
||||||
|
-public class EntityEnterLoveModeEvent extends EntityEvent implements Cancellable {
|
||||||
|
+public class EntityEnterLoveModeEvent extends EntityEvent implements Cancellable, gg.projecteden.parchment.OptionalHumanEntity { // Parchment
|
||||||
|
|
||||||
|
private static final HandlerList handlers = new HandlerList();
|
||||||
|
private boolean cancel;
|
||||||
|
@@ -44,9 +_,24 @@
|
||||||
|
* null if there wasn't one.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
- public HumanEntity getHumanEntity() {
|
||||||
|
+ // Parchment start
|
||||||
|
+ @Deprecated
|
||||||
|
+ public final HumanEntity getHumanEntity() {
|
||||||
|
+ return getPlayer();
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * Gets the Human Entity that caused the animal to enter love mode.
|
||||||
|
+ *
|
||||||
|
+ * @return The Human entity that caused the animal to enter love mode, or
|
||||||
|
+ * null if there wasn't one.
|
||||||
|
+ */
|
||||||
|
+ @Override
|
||||||
|
+ @Nullable
|
||||||
|
+ public HumanEntity getPlayer() {
|
||||||
|
return humanEntity;
|
||||||
|
}
|
||||||
|
+ // Parchment end
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the amount of ticks that the animal will fall in love for.
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
--- a/src/main/java/org/bukkit/event/entity/EntityExplodeEvent.java
|
||||||
|
+++ b/src/main/java/org/bukkit/event/entity/EntityExplodeEvent.java
|
||||||
|
@@ -14,7 +_,7 @@
|
||||||
|
* event isn't called if the {@link org.bukkit.GameRule#MOB_GRIEFING}
|
||||||
|
* is disabled as no block interaction will occur.
|
||||||
|
*/
|
||||||
|
-public class EntityExplodeEvent extends EntityEvent implements Cancellable {
|
||||||
|
+public class EntityExplodeEvent extends EntityEvent implements Cancellable, gg.projecteden.parchment.HasLocation { // Parchment
|
||||||
|
private static final HandlerList handlers = new HandlerList();
|
||||||
|
private boolean cancel;
|
||||||
|
private final Location location;
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
--- a/src/main/java/org/bukkit/event/entity/EntityPlaceEvent.java
|
||||||
|
+++ b/src/main/java/org/bukkit/event/entity/EntityPlaceEvent.java
|
||||||
|
@@ -17,7 +_,7 @@
|
||||||
|
* Note that this event is currently only fired for four specific placements:
|
||||||
|
* armor stands, boats, minecarts, and end crystals.
|
||||||
|
*/
|
||||||
|
-public class EntityPlaceEvent extends EntityEvent implements Cancellable {
|
||||||
|
+public class EntityPlaceEvent extends EntityEvent implements Cancellable, gg.projecteden.parchment.OptionalPlayer { // Parchment
|
||||||
|
|
||||||
|
private static final HandlerList handlers = new HandlerList();
|
||||||
|
private boolean cancelled;
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
--- a/src/main/java/org/bukkit/event/entity/EntityPortalEnterEvent.java
|
||||||
|
+++ b/src/main/java/org/bukkit/event/entity/EntityPortalEnterEvent.java
|
||||||
|
@@ -11,7 +_,7 @@
|
||||||
|
* Cancelling this event prevents any further processing of the portal for that tick.
|
||||||
|
* @see io.papermc.paper.event.entity.EntityInsideBlockEvent
|
||||||
|
*/
|
||||||
|
-public class EntityPortalEnterEvent extends EntityEvent implements org.bukkit.event.Cancellable { // Paper
|
||||||
|
+public class EntityPortalEnterEvent extends EntityEvent implements org.bukkit.event.Cancellable, gg.projecteden.parchment.HasLocation { // Parchment
|
||||||
|
private static final HandlerList handlers = new HandlerList();
|
||||||
|
private final Location location;
|
||||||
|
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
--- a/src/main/java/org/bukkit/event/entity/EntitySpawnEvent.java
|
||||||
|
+++ b/src/main/java/org/bukkit/event/entity/EntitySpawnEvent.java
|
||||||
|
@@ -11,7 +_,7 @@
|
||||||
|
* <p>
|
||||||
|
* If an Entity Spawn event is cancelled, the entity will not spawn.
|
||||||
|
*/
|
||||||
|
-public class EntitySpawnEvent extends EntityEvent implements Cancellable {
|
||||||
|
+public class EntitySpawnEvent extends EntityEvent implements Cancellable, gg.projecteden.parchment.HasLocation { // Parchment
|
||||||
|
|
||||||
|
private static final HandlerList handlers = new HandlerList();
|
||||||
|
private boolean canceled;
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
--- a/src/main/java/org/bukkit/event/entity/ItemDespawnEvent.java
|
||||||
|
+++ b/src/main/java/org/bukkit/event/entity/ItemDespawnEvent.java
|
||||||
|
@@ -13,7 +_,7 @@
|
||||||
|
* Cancelling the event results in the item being allowed to exist for 5 more
|
||||||
|
* minutes. This behavior is not guaranteed and may change in future versions.
|
||||||
|
*/
|
||||||
|
-public class ItemDespawnEvent extends EntityEvent implements Cancellable {
|
||||||
|
+public class ItemDespawnEvent extends EntityEvent implements Cancellable, gg.projecteden.parchment.HasLocation { // Parchment
|
||||||
|
private static final HandlerList handlers = new HandlerList();
|
||||||
|
private boolean canceled;
|
||||||
|
private final Location location;
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
--- a/src/main/java/org/bukkit/event/entity/PlayerLeashEntityEvent.java
|
||||||
|
+++ b/src/main/java/org/bukkit/event/entity/PlayerLeashEntityEvent.java
|
||||||
|
@@ -11,7 +_,7 @@
|
||||||
|
/**
|
||||||
|
* Called immediately prior to a creature being leashed by a player.
|
||||||
|
*/
|
||||||
|
-public class PlayerLeashEntityEvent extends Event implements Cancellable {
|
||||||
|
+public class PlayerLeashEntityEvent extends Event implements Cancellable, gg.projecteden.parchment.HasPlayer { // Parchment
|
||||||
|
private static final HandlerList handlers = new HandlerList();
|
||||||
|
private final Entity leashHolder;
|
||||||
|
private final Entity entity;
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
--- a/src/main/java/org/bukkit/event/hanging/HangingPlaceEvent.java
|
||||||
|
+++ b/src/main/java/org/bukkit/event/hanging/HangingPlaceEvent.java
|
||||||
|
@@ -14,7 +_,7 @@
|
||||||
|
/**
|
||||||
|
* Triggered when a hanging entity is created in the world
|
||||||
|
*/
|
||||||
|
-public class HangingPlaceEvent extends HangingEvent implements Cancellable {
|
||||||
|
+public class HangingPlaceEvent extends HangingEvent implements Cancellable, gg.projecteden.parchment.OptionalPlayer { // Parchment
|
||||||
|
private static final HandlerList handlers = new HandlerList();
|
||||||
|
private boolean cancelled;
|
||||||
|
private final Player player;
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
--- a/src/main/java/org/bukkit/event/inventory/FurnaceExtractEvent.java
|
||||||
|
+++ b/src/main/java/org/bukkit/event/inventory/FurnaceExtractEvent.java
|
||||||
|
@@ -13,7 +_,7 @@
|
||||||
|
* {@link org.bukkit.block.Furnace}, {@link org.bukkit.block.Smoker}, or
|
||||||
|
* {@link org.bukkit.block.BlastFurnace}.
|
||||||
|
*/
|
||||||
|
-public class FurnaceExtractEvent extends BlockExpEvent {
|
||||||
|
+public class FurnaceExtractEvent extends BlockExpEvent implements gg.projecteden.parchment.HasPlayer { // Parchment
|
||||||
|
private final Player player;
|
||||||
|
private final Material itemType;
|
||||||
|
private final int itemAmount;
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
--- a/src/main/java/org/bukkit/event/inventory/InventoryCloseEvent.java
|
||||||
|
+++ b/src/main/java/org/bukkit/event/inventory/InventoryCloseEvent.java
|
||||||
|
@@ -28,7 +_,7 @@
|
||||||
|
* on the next tick. Also be aware that this is not an exhaustive list, and
|
||||||
|
* other methods could potentially create issues as well.
|
||||||
|
*/
|
||||||
|
-public class InventoryCloseEvent extends InventoryEvent {
|
||||||
|
+public class InventoryCloseEvent extends InventoryEvent implements gg.projecteden.parchment.HasHumanEntity { // Parchment
|
||||||
|
private static final HandlerList handlers = new HandlerList();
|
||||||
|
// Paper start
|
||||||
|
private final Reason reason;
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
--- a/src/main/java/org/bukkit/event/inventory/InventoryOpenEvent.java
|
||||||
|
+++ b/src/main/java/org/bukkit/event/inventory/InventoryOpenEvent.java
|
||||||
|
@@ -9,7 +_,7 @@
|
||||||
|
/**
|
||||||
|
* Called when a player opens an inventory
|
||||||
|
*/
|
||||||
|
-public class InventoryOpenEvent extends InventoryEvent implements Cancellable {
|
||||||
|
+public class InventoryOpenEvent extends InventoryEvent implements Cancellable, gg.projecteden.parchment.HasHumanEntity { // Parchment
|
||||||
|
private static final HandlerList handlers = new HandlerList();
|
||||||
|
private boolean cancelled;
|
||||||
|
private net.kyori.adventure.text.Component titleOverride; // Paper
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
--- a/src/main/java/org/bukkit/event/player/AsyncPlayerPreLoginEvent.java
|
||||||
|
+++ b/src/main/java/org/bukkit/event/player/AsyncPlayerPreLoginEvent.java
|
||||||
|
@@ -18,7 +_,7 @@
|
||||||
|
* Consider rendering any translatable yourself with {@link net.kyori.adventure.translation.GlobalTranslator#render}
|
||||||
|
* if the client's language is known.
|
||||||
|
*/
|
||||||
|
-public class AsyncPlayerPreLoginEvent extends Event {
|
||||||
|
+public class AsyncPlayerPreLoginEvent extends Event implements gg.projecteden.api.interfaces.HasUniqueId { // Parchment
|
||||||
|
private static final HandlerList handlers = new HandlerList();
|
||||||
|
private Result result;
|
||||||
|
private net.kyori.adventure.text.Component message; // Paper
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
--- a/src/main/java/org/bukkit/event/player/PlayerEvent.java
|
||||||
|
+++ b/src/main/java/org/bukkit/event/player/PlayerEvent.java
|
||||||
|
@@ -7,7 +_,7 @@
|
||||||
|
/**
|
||||||
|
* Represents a player related event
|
||||||
|
*/
|
||||||
|
-public abstract class PlayerEvent extends Event {
|
||||||
|
+public abstract class PlayerEvent extends Event implements gg.projecteden.parchment.HasPlayer { // Parchment
|
||||||
|
protected Player player;
|
||||||
|
|
||||||
|
public PlayerEvent(@NotNull final Player who) {
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
--- a/src/main/java/org/bukkit/event/player/PlayerPreLoginEvent.java
|
||||||
|
+++ b/src/main/java/org/bukkit/event/player/PlayerPreLoginEvent.java
|
||||||
|
@@ -23,7 +_,7 @@
|
||||||
|
*/
|
||||||
|
@Deprecated(since = "1.3.2")
|
||||||
|
@Warning(reason = "This event causes a login thread to synchronize with the main thread")
|
||||||
|
-public class PlayerPreLoginEvent extends Event {
|
||||||
|
+public class PlayerPreLoginEvent extends Event implements gg.projecteden.api.interfaces.HasUniqueId { // Parchment
|
||||||
|
private static final HandlerList handlers = new HandlerList();
|
||||||
|
private Result result;
|
||||||
|
private net.kyori.adventure.text.Component message; // Paper
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
--- a/src/main/java/org/bukkit/event/player/PlayerUnleashEntityEvent.java
|
||||||
|
+++ b/src/main/java/org/bukkit/event/player/PlayerUnleashEntityEvent.java
|
||||||
|
@@ -10,7 +_,7 @@
|
||||||
|
/**
|
||||||
|
* Called prior to an entity being unleashed due to a player's action.
|
||||||
|
*/
|
||||||
|
-public class PlayerUnleashEntityEvent extends EntityUnleashEvent implements Cancellable {
|
||||||
|
+public class PlayerUnleashEntityEvent extends EntityUnleashEvent implements Cancellable, gg.projecteden.parchment.HasPlayer { // Parchment
|
||||||
|
|
||||||
|
private boolean cancelled = false;
|
||||||
|
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
--- a/src/main/java/org/bukkit/event/raid/RaidTriggerEvent.java
|
||||||
|
+++ b/src/main/java/org/bukkit/event/raid/RaidTriggerEvent.java
|
||||||
|
@@ -11,7 +_,7 @@
|
||||||
|
* Called when a {@link Raid} is triggered (e.g: a player with Bad Omen effect
|
||||||
|
* enters a village).
|
||||||
|
*/
|
||||||
|
-public class RaidTriggerEvent extends RaidEvent implements Cancellable {
|
||||||
|
+public class RaidTriggerEvent extends RaidEvent implements Cancellable, gg.projecteden.parchment.HasPlayer { // Parchment
|
||||||
|
|
||||||
|
private static final HandlerList handlers = new HandlerList();
|
||||||
|
//
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
--- a/src/main/java/org/bukkit/event/server/TabCompleteEvent.java
|
||||||
|
+++ b/src/main/java/org/bukkit/event/server/TabCompleteEvent.java
|
||||||
|
@@ -21,7 +_,7 @@
|
||||||
|
* @apiNote Only called for bukkit API commands {@link org.bukkit.command.Command} and
|
||||||
|
* {@link org.bukkit.command.CommandExecutor} and not for brigadier commands ({@link io.papermc.paper.command.brigadier.Commands}).
|
||||||
|
*/
|
||||||
|
-public class TabCompleteEvent extends Event implements Cancellable {
|
||||||
|
+public class TabCompleteEvent extends Event implements Cancellable, gg.projecteden.parchment.OptionalLocation { // Parchment
|
||||||
|
|
||||||
|
private static final HandlerList handlers = new HandlerList();
|
||||||
|
//
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
--- a/src/main/java/org/bukkit/event/world/GenericGameEvent.java
|
||||||
|
+++ b/src/main/java/org/bukkit/event/world/GenericGameEvent.java
|
||||||
|
@@ -15,7 +_,7 @@
|
||||||
|
* Specific Bukkit events should be used where possible, this event is mainly
|
||||||
|
* used internally by Sculk sensors.
|
||||||
|
*/
|
||||||
|
-public class GenericGameEvent extends WorldEvent implements Cancellable {
|
||||||
|
+public class GenericGameEvent extends WorldEvent implements Cancellable, gg.projecteden.parchment.HasLocation { // Parchment
|
||||||
|
|
||||||
|
private static final HandlerList handlers = new HandlerList();
|
||||||
|
private final GameEvent event;
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
--- a/src/main/java/org/bukkit/event/world/StructureGrowEvent.java
|
||||||
|
+++ b/src/main/java/org/bukkit/event/world/StructureGrowEvent.java
|
||||||
|
@@ -14,7 +_,7 @@
|
||||||
|
* Event that is called when an organic structure attempts to grow (Sapling {@literal ->}
|
||||||
|
* Tree), (Mushroom {@literal ->} Huge Mushroom), naturally or using bonemeal.
|
||||||
|
*/
|
||||||
|
-public class StructureGrowEvent extends WorldEvent implements Cancellable {
|
||||||
|
+public class StructureGrowEvent extends WorldEvent implements Cancellable, gg.projecteden.parchment.OptionalPlayer { // Parchment
|
||||||
|
private static final HandlerList handlers = new HandlerList();
|
||||||
|
private boolean cancelled = false;
|
||||||
|
private final Location location;
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
--- a/src/main/java/org/bukkit/inventory/Inventory.java
|
||||||
|
+++ b/src/main/java/org/bukkit/inventory/Inventory.java
|
||||||
|
@@ -25,7 +_,7 @@
|
||||||
|
* @see #getContents()
|
||||||
|
* @see #getStorageContents()
|
||||||
|
*/
|
||||||
|
-public interface Inventory extends Iterable<ItemStack> {
|
||||||
|
+public interface Inventory extends Iterable<ItemStack>, gg.projecteden.parchment.OptionalLocation { // Parchment
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the size of the inventory
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
--- a/src/main/java/org/bukkit/inventory/InventoryView.java
|
||||||
|
+++ b/src/main/java/org/bukkit/inventory/InventoryView.java
|
||||||
|
@@ -9,7 +_,7 @@
|
||||||
|
* Represents a view linking two inventories and a single player (whose
|
||||||
|
* inventory may or may not be one of the two).
|
||||||
|
*/
|
||||||
|
-public interface InventoryView {
|
||||||
|
+public interface InventoryView extends gg.projecteden.parchment.HasHumanEntity { // Parchment
|
||||||
|
public static final int OUTSIDE = -999;
|
||||||
|
/**
|
||||||
|
* Represents various extra properties of certain inventory windows.
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
--- a/src/main/java/org/bukkit/loot/LootContext.java
|
||||||
|
+++ b/src/main/java/org/bukkit/loot/LootContext.java
|
||||||
|
@@ -11,7 +_,7 @@
|
||||||
|
* Represents additional information a {@link LootTable} can use to modify it's
|
||||||
|
* generated loot.
|
||||||
|
*/
|
||||||
|
-public final class LootContext {
|
||||||
|
+public final class LootContext implements gg.projecteden.parchment.HasLocation { // Parchment
|
||||||
|
|
||||||
|
public static final int DEFAULT_LOOT_MODIFIER = -1;
|
||||||
|
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package gg.projecteden.parchment;
|
||||||
|
|
||||||
|
import org.bukkit.entity.HumanEntity;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an object that has a {@link HumanEntity}
|
||||||
|
* @see gg.projecteden.parchment.OptionalHumanEntity
|
||||||
|
*/
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface HasHumanEntity extends OptionalHumanEntity {
|
||||||
|
/**
|
||||||
|
* Gets a {@link HumanEntity} object that this represents
|
||||||
|
*
|
||||||
|
* @return human entity
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@NotNull HumanEntity getPlayer();
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package gg.projecteden.parchment;
|
||||||
|
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an object that has a {@link Location}
|
||||||
|
* @see OptionalLocation
|
||||||
|
*/
|
||||||
|
public interface HasLocation extends OptionalLocation {
|
||||||
|
/**
|
||||||
|
* Gets a {@link Location} attached to this object
|
||||||
|
*
|
||||||
|
* @return attached location
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@NotNull Location getLocation();
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package gg.projecteden.parchment;
|
||||||
|
|
||||||
|
import org.bukkit.OfflinePlayer;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an object that has a {@link OfflinePlayer}
|
||||||
|
*/
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface HasOfflinePlayer {
|
||||||
|
/**
|
||||||
|
* Gets an {@link OfflinePlayer} object that this represents
|
||||||
|
*
|
||||||
|
* @return offline player
|
||||||
|
*/
|
||||||
|
@NotNull OfflinePlayer getOfflinePlayer();
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package gg.projecteden.parchment;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an object that has a {@link Player}
|
||||||
|
* @see gg.projecteden.parchment.OptionalPlayer
|
||||||
|
*/
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface HasPlayer extends OptionalPlayer, HasHumanEntity {
|
||||||
|
/**
|
||||||
|
* Gets a {@link Player} object that this represents
|
||||||
|
*
|
||||||
|
* @return player
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@NotNull Player getPlayer();
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package gg.projecteden.parchment;
|
||||||
|
|
||||||
|
import org.bukkit.entity.HumanEntity;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an object that may have a {@link HumanEntity}
|
||||||
|
* @see HasHumanEntity
|
||||||
|
*/
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface OptionalHumanEntity {
|
||||||
|
/**
|
||||||
|
* Gets a {@link HumanEntity} object that this represents, if there is one
|
||||||
|
*
|
||||||
|
* @return human entity or null
|
||||||
|
*/
|
||||||
|
@Nullable HumanEntity getPlayer();
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package gg.projecteden.parchment;
|
||||||
|
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an object that may have a {@link Location}
|
||||||
|
* @see HasLocation
|
||||||
|
*/
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface OptionalLocation {
|
||||||
|
/**
|
||||||
|
* Gets a {@link Location} attached to this object if present *
|
||||||
|
* @return attached location
|
||||||
|
*/
|
||||||
|
@Nullable Location getLocation();
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package gg.projecteden.parchment;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an object that may have a {@link Player}
|
||||||
|
* @see HasPlayer
|
||||||
|
*/
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface OptionalPlayer extends OptionalHumanEntity {
|
||||||
|
/**
|
||||||
|
* Gets a {@link Player} object that this represents, if there is one. This may be null if the
|
||||||
|
* player is online or the player object being optional.
|
||||||
|
*
|
||||||
|
* @return player or null
|
||||||
|
*/
|
||||||
|
@Nullable Player getPlayer();
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package gg.projecteden.parchment;
|
||||||
|
|
||||||
|
import net.kyori.adventure.audience.Audience;
|
||||||
|
import net.kyori.adventure.audience.ForwardingAudience;
|
||||||
|
import net.kyori.adventure.identity.Identified;
|
||||||
|
import net.kyori.adventure.identity.Identity;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class that may be like a {@link org.bukkit.entity.Player} in that it has a {@link java.util.UUID}, {@link org.bukkit.OfflinePlayer}, {@link Identity}, and a nullable Player.
|
||||||
|
* @see gg.projecteden.parchment.PlayerLike
|
||||||
|
*/
|
||||||
|
public interface OptionalPlayerLike extends OptionalPlayer, gg.projecteden.api.interfaces.HasUniqueId, HasOfflinePlayer, OptionalLocation, Identified, ForwardingAudience.Single {
|
||||||
|
/**
|
||||||
|
* Gets the identity associated with this object
|
||||||
|
*
|
||||||
|
* @return associated identity
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
default @NotNull Identity identity() {
|
||||||
|
return Identity.identity(getUniqueId());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns if the {@link Player} associated with this object is online.
|
||||||
|
*
|
||||||
|
* @return if the player is online
|
||||||
|
*/
|
||||||
|
default boolean isOnline() {
|
||||||
|
return getPlayer() != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default @NotNull Audience audience() {
|
||||||
|
return Objects.requireNonNullElse(getPlayer(), Audience.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default @Nullable Location getLocation() {
|
||||||
|
final Player player = getPlayer();
|
||||||
|
return player == null ? null : player.getLocation();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package gg.projecteden.parchment;
|
||||||
|
|
||||||
|
import net.kyori.adventure.audience.Audience;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class that is like a {@link org.bukkit.entity.Player} in that it has a Player, {@link java.util.UUID}, {@link org.bukkit.OfflinePlayer}, and an {@link net.kyori.adventure.identity.Identity}.
|
||||||
|
* @see gg.projecteden.parchment.OptionalPlayerLike
|
||||||
|
*/
|
||||||
|
public interface PlayerLike extends HasPlayer, HasLocation, OptionalPlayerLike {
|
||||||
|
|
||||||
|
// reduce nullability checks by re-implementing the methods from OptionalPlayerLike
|
||||||
|
// (but without the null checks)
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default @NotNull Audience audience() {
|
||||||
|
return getPlayer();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default boolean isOnline() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default @NotNull Location getLocation() {
|
||||||
|
return getPlayer().getLocation();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,140 @@
|
|||||||
|
package gg.projecteden.parchment.entity;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public final class EntityData {
|
||||||
|
private static final Map<UUID, List<DataSlot>> PARKED = new HashMap<>();
|
||||||
|
private static int DATA_IDX;
|
||||||
|
|
||||||
|
private final List<EntityDataFragment<?>> data = new ArrayList<>();
|
||||||
|
private final Class<?> ownerType;
|
||||||
|
private Entity owner;
|
||||||
|
|
||||||
|
EntityData(Class<?> ownerType) {
|
||||||
|
this.ownerType = ownerType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T extends EntityDataFragment<E>, E extends Entity> EntityDataKey<T, E> createKey(
|
||||||
|
Supplier<T> generator,
|
||||||
|
Class<E> ownerType
|
||||||
|
) {
|
||||||
|
return new EntityDataKey<>(ownerType, generator, EntityData.DATA_IDX);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static EntityData create(Entity entity) {
|
||||||
|
EntityData data = new EntityData(entity.getClass());
|
||||||
|
|
||||||
|
List<DataSlot> slots = EntityData.PARKED.get(entity.getUniqueId());
|
||||||
|
if (slots != null) {
|
||||||
|
for (DataSlot slot : slots) {
|
||||||
|
data.set(slot.idx, slot.data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data.setOwner(entity);
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T extends EntityDataFragment<E>, E extends Entity> T get(EntityDataKey<T, E> key) {
|
||||||
|
while (this.data.size() <= key.getIdx()) {
|
||||||
|
this.data.add(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
T out = cast(this.data.get(key.getIdx()));
|
||||||
|
if (out == null) {
|
||||||
|
this.checkEntityType(key.ownerType);
|
||||||
|
|
||||||
|
out = key.getGenerator().get();
|
||||||
|
out.setOwner(cast(this.owner));
|
||||||
|
|
||||||
|
this.data.set(key.getIdx(), out);
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T extends EntityDataFragment<E>, E extends Entity> boolean clear(EntityDataKey<T, E> key) {
|
||||||
|
if (this.data.size() <= key.getIdx()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.checkEntityType(key.ownerType);
|
||||||
|
return this.data.set(key.getIdx(), null) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void orphan() {
|
||||||
|
for (EntityDataFragment<?> frag : this.data) {
|
||||||
|
if (frag != null) {
|
||||||
|
frag.onOrphan();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<DataSlot> persist = new ArrayList<>();
|
||||||
|
|
||||||
|
for (int i = this.data.size() - 1; i >= 0; i--) {
|
||||||
|
EntityDataFragment<?> frag = this.data.get(i);
|
||||||
|
if (frag != null && frag.isPersistent()) {
|
||||||
|
persist.add(new DataSlot(frag, i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!persist.isEmpty()) {
|
||||||
|
EntityData.PARKED.put(this.owner.getUniqueId(), persist);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void set(int slot, EntityDataFragment<?> data) {
|
||||||
|
while (this.data.size() <= slot) {
|
||||||
|
this.data.add(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.data.set(slot, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setOwner(Entity entity) {
|
||||||
|
Class<?> ownerType = entity.getClass();
|
||||||
|
if (!ownerType.equals(this.ownerType)) {
|
||||||
|
throw new IllegalArgumentException(String.format(
|
||||||
|
"Wrong entity type. (entity=%s@%s, expect=%s@%s)",
|
||||||
|
ownerType, ownerType.getClassLoader(),
|
||||||
|
this.ownerType, this.ownerType.getClassLoader()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.owner = entity;
|
||||||
|
|
||||||
|
for (EntityDataFragment<?> frag : this.data) {
|
||||||
|
if (frag != null) {
|
||||||
|
frag.setOwner(cast(entity));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkEntityType(Class<?> ownerType) {
|
||||||
|
if (!ownerType.isAssignableFrom(this.ownerType)) {
|
||||||
|
throw new IllegalArgumentException(String.format(
|
||||||
|
"Incompatible entity types. (key=%s@%s, expect=%s@%s)",
|
||||||
|
ownerType, ownerType.getClassLoader(),
|
||||||
|
this.ownerType, this.ownerType.getClassLoader()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private <S, T> T cast(S src) {
|
||||||
|
return (T) src;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class DataSlot {
|
||||||
|
private final EntityDataFragment<?> data;
|
||||||
|
private final int idx;
|
||||||
|
|
||||||
|
private DataSlot(EntityDataFragment<?> data, int idx) {
|
||||||
|
this.data = data;
|
||||||
|
this.idx = idx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package gg.projecteden.parchment.entity;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
|
||||||
|
public abstract class EntityDataFragment<E extends Entity> {
|
||||||
|
private E owner;
|
||||||
|
private boolean persistent = true;
|
||||||
|
|
||||||
|
protected EntityDataFragment() {
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void onOwnerChange() {
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void onOrphan() {
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final E getOwner() {
|
||||||
|
return this.owner;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final void setPersistent(boolean persistent) {
|
||||||
|
this.persistent = persistent;
|
||||||
|
}
|
||||||
|
|
||||||
|
final boolean isPersistent() {
|
||||||
|
return this.persistent;
|
||||||
|
}
|
||||||
|
|
||||||
|
final void setOwner(E entity) {
|
||||||
|
this.owner = entity;
|
||||||
|
this.onOwnerChange();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package gg.projecteden.parchment.entity;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public final class EntityDataKey<T extends EntityDataFragment<E>, E extends Entity> {
|
||||||
|
private final Supplier<T> generator;
|
||||||
|
private final int idx;
|
||||||
|
|
||||||
|
final Class<E> ownerType;
|
||||||
|
|
||||||
|
EntityDataKey(Class<E> ownerType, Supplier<T> generator, int idx) {
|
||||||
|
this.generator = generator;
|
||||||
|
this.idx = idx;
|
||||||
|
|
||||||
|
this.ownerType = ownerType;
|
||||||
|
}
|
||||||
|
|
||||||
|
Supplier<T> getGenerator() {
|
||||||
|
return this.generator;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getIdx() {
|
||||||
|
return this.idx;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package gg.projecteden.parchment.entity;
|
||||||
|
|
||||||
|
public final class EntityDataServiceKey<S> {
|
||||||
|
private final Class<S> serviceType;
|
||||||
|
private S service;
|
||||||
|
|
||||||
|
public EntityDataServiceKey(Class<S> serviceType) {
|
||||||
|
this.serviceType = serviceType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public S get() {
|
||||||
|
if (this.service == null) {
|
||||||
|
throw new IllegalStateException("Service is not initialized.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.service;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void set(S service) {
|
||||||
|
if (this.service != null) {
|
||||||
|
throw new IllegalStateException("Service is already initialized.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.serviceType.isInstance(service)) {
|
||||||
|
throw new IllegalArgumentException("Value does not implement service contract.");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.service = service;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
package gg.projecteden.parchment.event.block;
|
||||||
|
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.event.HandlerList;
|
||||||
|
import org.bukkit.event.block.BlockEvent;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a block drops resources in the world. The block will exist in the world at the time.
|
||||||
|
* <p>
|
||||||
|
* This event fires in between {@link org.bukkit.event.block.BlockBreakEvent BlockBreakEvent}
|
||||||
|
* and {@link org.bukkit.event.block.BlockDropItemEvent BlockDropItemEvent}.
|
||||||
|
*/
|
||||||
|
public class BlockDropResourcesEvent extends BlockEvent {
|
||||||
|
private static final HandlerList handlers = new HandlerList();
|
||||||
|
private final @NotNull List<ItemStack> resources;
|
||||||
|
|
||||||
|
public BlockDropResourcesEvent(@NotNull Block block, @NotNull List<ItemStack> resources) {
|
||||||
|
super(block);
|
||||||
|
this.resources = resources;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the resources being dropped by the block. This list is guaranteed to be mutable
|
||||||
|
* and may be safely altered.
|
||||||
|
* @return mutable list of items
|
||||||
|
*/
|
||||||
|
public @NotNull List<ItemStack> getResources() {
|
||||||
|
return resources;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public HandlerList getHandlers() {
|
||||||
|
return handlers;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static HandlerList getHandlerList() {
|
||||||
|
return handlers;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
package gg.projecteden.parchment.event.block;
|
||||||
|
|
||||||
|
import org.bukkit.block.data.BlockData;
|
||||||
|
import org.bukkit.event.Cancellable;
|
||||||
|
import org.bukkit.event.Event;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.event.HandlerList;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class CustomBlockUpdateEvent extends Event implements Cancellable {
|
||||||
|
|
||||||
|
private static final HandlerList handlers = new HandlerList();
|
||||||
|
private boolean cancelled;
|
||||||
|
|
||||||
|
private BlockData block;
|
||||||
|
private UpdateType updateType;
|
||||||
|
private Location location;
|
||||||
|
|
||||||
|
public CustomBlockUpdateEvent(BlockData block, UpdateType updateType, Location location) {
|
||||||
|
this.block = block;
|
||||||
|
this.updateType = updateType;
|
||||||
|
this.location = location;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CustomBlockUpdateEvent(BlockData block, UpdateType updateType) {
|
||||||
|
this.block = block;
|
||||||
|
this.updateType = updateType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCancelled() {
|
||||||
|
return this.cancelled;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCancelled(boolean cancel) {
|
||||||
|
this.cancelled = cancel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BlockData getBlock() {
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UpdateType getUpdateType() {
|
||||||
|
return updateType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Location getLocation() {
|
||||||
|
return location;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public HandlerList getHandlers() {
|
||||||
|
return handlers;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static HandlerList getHandlerList() {
|
||||||
|
return handlers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum UpdateType {
|
||||||
|
POWERED,
|
||||||
|
SHAPE,
|
||||||
|
INSTRUMENT,
|
||||||
|
PITCH
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
package gg.projecteden.parchment.event.entity;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
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;
|
||||||
|
|
||||||
|
public class PreEntityShootBowEvent extends EntityEvent implements Cancellable {
|
||||||
|
private static final HandlerList handlers = new HandlerList();
|
||||||
|
|
||||||
|
private final @NotNull ItemStack bow;
|
||||||
|
private final @NotNull ItemStack arrow;
|
||||||
|
boolean relative = true;
|
||||||
|
boolean cancelled = false;
|
||||||
|
|
||||||
|
public PreEntityShootBowEvent(@NotNull Entity entity, @NotNull ItemStack bow, @NotNull ItemStack arrow) {
|
||||||
|
super(entity);
|
||||||
|
this.bow = bow;
|
||||||
|
this.arrow = arrow;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NotNull ItemStack getBow() {
|
||||||
|
return this.bow;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NotNull ItemStack getArrow() {
|
||||||
|
return this.arrow;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRelative() {
|
||||||
|
return this.relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRelative(boolean relative) {
|
||||||
|
this.relative = relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCancelled() {
|
||||||
|
return this.cancelled;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCancelled(boolean cancel) {
|
||||||
|
this.cancelled = cancel;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull HandlerList getHandlers() {
|
||||||
|
return handlers;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static HandlerList getHandlerList() {
|
||||||
|
return handlers;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,117 @@
|
|||||||
|
package gg.projecteden.parchment.event.player;
|
||||||
|
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This event is fired after determining what action should result from a player interacting with
|
||||||
|
* a respawn anchor.
|
||||||
|
*/
|
||||||
|
public class PlayerUseRespawnAnchorEvent extends PlayerEvent implements Cancellable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents the default possible outcomes of this event.
|
||||||
|
*/
|
||||||
|
public enum RespawnAnchorResult {
|
||||||
|
/**
|
||||||
|
* The player's spawn point will be set
|
||||||
|
*/
|
||||||
|
SET_SPAWN,
|
||||||
|
/**
|
||||||
|
* The respawn anchor will explode due to being used outside the nether
|
||||||
|
*/
|
||||||
|
EXPLODE,
|
||||||
|
/**
|
||||||
|
* The player will charge the respawn anchor
|
||||||
|
*/
|
||||||
|
CHARGE,
|
||||||
|
/**
|
||||||
|
* The respawn anchor will do nothing
|
||||||
|
*/
|
||||||
|
NOTHING
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final HandlerList handlers = new HandlerList();
|
||||||
|
private final Block respawnAnchor;
|
||||||
|
private RespawnAnchorResult respawnAnchorResult;
|
||||||
|
private boolean cancelled = false;
|
||||||
|
|
||||||
|
public PlayerUseRespawnAnchorEvent(@NotNull Player who, @NotNull Block respawnAnchor, @NotNull RespawnAnchorResult respawnAnchorResult) {
|
||||||
|
super(who);
|
||||||
|
this.respawnAnchor = respawnAnchor;
|
||||||
|
this.respawnAnchorResult = respawnAnchorResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the respawn anchor block involved in this event.
|
||||||
|
*
|
||||||
|
* @return the respawn anchor block involved in this event
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public Block getRespawnAnchor() {
|
||||||
|
return this.respawnAnchor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Describes the outcome of the event.
|
||||||
|
*
|
||||||
|
* @return the respawn anchor result for the outcome of the event
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public RespawnAnchorResult getResult() {
|
||||||
|
return this.respawnAnchorResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the outcome of the event.
|
||||||
|
*
|
||||||
|
* @param result event to set
|
||||||
|
*/
|
||||||
|
public void setResult(@NotNull RespawnAnchorResult result) {
|
||||||
|
this.respawnAnchorResult = Preconditions.checkNotNull(result, "result");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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>
|
||||||
|
* A positive value means the respawn anchor will not take any action, as
|
||||||
|
* if it had not been clicked at all.
|
||||||
|
*
|
||||||
|
* @return true if this event is cancelled
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean isCancelled() {
|
||||||
|
return cancelled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the cancellation state of this event. A canceled event will not be
|
||||||
|
* executed in the server, but will still pass to other plugins.
|
||||||
|
* <p>
|
||||||
|
* Canceling this event will prevent use of the respawn anchor, leaving it
|
||||||
|
* as thought it hadn't been clicked at all.
|
||||||
|
*
|
||||||
|
* @param cancel true if you wish to cancel this event
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setCancelled(boolean cancel) {
|
||||||
|
this.cancelled = cancel;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull HandlerList getHandlers() {
|
||||||
|
return handlers;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static HandlerList getHandlerList() {
|
||||||
|
return handlers;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,359 @@
|
|||||||
|
package gg.projecteden.parchment.event.sound;
|
||||||
|
|
||||||
|
import gg.projecteden.parchment.HasLocation;
|
||||||
|
import gg.projecteden.parchment.OptionalHumanEntity;
|
||||||
|
import net.kyori.adventure.sound.Sound;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.entity.HumanEntity;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.Cancellable;
|
||||||
|
import org.bukkit.event.Event;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a sound is sent to a player.
|
||||||
|
* Cancelling this event will prevent the packet from sending.
|
||||||
|
*/
|
||||||
|
public final class SoundEvent extends Event implements Cancellable {
|
||||||
|
private static final Logger LOGGER = org.slf4j.LoggerFactory.getLogger(SoundEvent.class);
|
||||||
|
|
||||||
|
private static final org.bukkit.event.HandlerList handlers = new org.bukkit.event.HandlerList();
|
||||||
|
public static final @NotNull Function<Sound, Double> DEFAULT_DISTANCE_FUNCTION = event -> event.volume() > 1.0F ? (double) (16.0F * event.volume()) : 16.0D;
|
||||||
|
public static final @NotNull Function<SoundEvent, List<Player>> DEFAULT_RECIPIENTS_FUNCTION = new WrappedRecipientsFunction(event -> {
|
||||||
|
final double distance = event.calculateDistance();
|
||||||
|
final Location loc = event.getEmitter().location();
|
||||||
|
return loc.getWorld().getPlayers().stream()
|
||||||
|
.filter(player -> {
|
||||||
|
Location pl = player.getLocation();
|
||||||
|
double x = loc.getX() - pl.getX();
|
||||||
|
double y = loc.getY() - pl.getY();
|
||||||
|
double z = loc.getZ() - pl.getZ();
|
||||||
|
return x * x + y * y + z * z < distance * distance;
|
||||||
|
})
|
||||||
|
.toList();
|
||||||
|
});
|
||||||
|
|
||||||
|
private @Nullable HumanEntity except;
|
||||||
|
private @NotNull Function<@NotNull Sound, @NotNull Double> distanceFunction;
|
||||||
|
private @NotNull Function<@NotNull SoundEvent, @NotNull List<@NotNull Player>> recipientsFunction;
|
||||||
|
private @NotNull Sound sound;
|
||||||
|
private @NotNull Emitter emitter;
|
||||||
|
private boolean cancelled;
|
||||||
|
private @Nullable BiFunction<@NotNull SoundEvent, @NotNull Player, @Nullable Sound> soundOverrideFunction;
|
||||||
|
private @Nullable BiFunction<@NotNull SoundEvent, @NotNull Player, @Nullable Emitter> emitterOverrideFunction;
|
||||||
|
|
||||||
|
public SoundEvent(@Nullable HumanEntity except, @NotNull Sound sound, @NotNull Emitter emitter, @Nullable Function<Sound, Double> distanceFunction, @Nullable Function<SoundEvent, List<Player>> recipientsFunction) {
|
||||||
|
super(true);
|
||||||
|
this.except = except;
|
||||||
|
this.sound = Objects.requireNonNull(sound, "sound cannot be null");
|
||||||
|
this.emitter = Objects.requireNonNull(emitter, "emitter cannot be null");
|
||||||
|
this.distanceFunction = Objects.requireNonNullElse(distanceFunction, DEFAULT_DISTANCE_FUNCTION);
|
||||||
|
this.recipientsFunction = wrapRecipientsFunction(Objects.requireNonNullElse(recipientsFunction, DEFAULT_RECIPIENTS_FUNCTION));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the player that <b>won't</b> be receiving this sound.
|
||||||
|
*
|
||||||
|
* @return player excluded from receiving this sound
|
||||||
|
*/
|
||||||
|
public @Nullable HumanEntity getException() {
|
||||||
|
return except;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the player that <b>won't</b> be receiving this sound.
|
||||||
|
*
|
||||||
|
* @param except player excluded from receiving this sound
|
||||||
|
*/
|
||||||
|
public void setException(@Nullable HumanEntity except) {
|
||||||
|
this.except = except;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the sound that will be sent.
|
||||||
|
*
|
||||||
|
* @return sound that will be sent
|
||||||
|
*/
|
||||||
|
public @NotNull Sound getSound() {
|
||||||
|
return sound;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the sound that will be sent.
|
||||||
|
*
|
||||||
|
* @param sound sound that will be sent
|
||||||
|
*/
|
||||||
|
public void setSound(@NotNull Sound sound) {
|
||||||
|
this.sound = Objects.requireNonNull(sound, "sound cannot be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the emitter which determines how and where the sound will be played from.
|
||||||
|
*
|
||||||
|
* @return emitter which determines how and where the sound will be played from
|
||||||
|
*/
|
||||||
|
public @NotNull Emitter getEmitter() {
|
||||||
|
return emitter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the emitter which determines how and where the sound will be played from.
|
||||||
|
*
|
||||||
|
* @param emitter emitter which determines how and where the sound will be played from
|
||||||
|
*/
|
||||||
|
public void setEmitter(@NotNull Emitter emitter) {
|
||||||
|
this.emitter = Objects.requireNonNull(emitter, "emitter cannot be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the distance of the sound.
|
||||||
|
* <p>
|
||||||
|
* The distance value is dynamically calculated using a
|
||||||
|
* {@link Function Function<SoundEvent, Double>}.
|
||||||
|
* In vanilla Minecraft, the default function is {@link #DEFAULT_DISTANCE_FUNCTION}
|
||||||
|
* ({@code event -> event.getVolume() > 1.0F ? (double) (16.0F * event.getVolume()) : 16.0D}).
|
||||||
|
* </p>
|
||||||
|
* This is used by the vanilla implementation of {@link #calculateRecipients()}, though custom
|
||||||
|
* implementations won't always use this method.
|
||||||
|
*
|
||||||
|
* @return calculated distance
|
||||||
|
* @see #getDistanceFunction()
|
||||||
|
* @see #setDistanceFunction(Function)
|
||||||
|
*/
|
||||||
|
public double calculateDistance() {
|
||||||
|
return distanceFunction.apply(sound);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the function that calculates the distance of the sound.
|
||||||
|
*
|
||||||
|
* @return distance function
|
||||||
|
* @see #calculateDistance()
|
||||||
|
* @see #setDistanceFunction(Function)
|
||||||
|
*/
|
||||||
|
public @NotNull Function<@NotNull Sound, @NotNull Double> getDistanceFunction() {
|
||||||
|
return distanceFunction;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the function that calculates the distance of the sound.
|
||||||
|
*
|
||||||
|
* @param distanceFunction distance function
|
||||||
|
* @see #calculateDistance()
|
||||||
|
* @see #getDistanceFunction()
|
||||||
|
*/
|
||||||
|
public void setDistanceFunction(@NotNull Function<@NotNull Sound, @NotNull Double> distanceFunction) {
|
||||||
|
this.distanceFunction = Objects.requireNonNull(distanceFunction, "distanceFunction cannot be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines which players will receive this sound packet.
|
||||||
|
*
|
||||||
|
* @return immutable list of players
|
||||||
|
* @see #getRecipientsFunction()
|
||||||
|
* @see #setRecipientsFunction(Function)
|
||||||
|
*/
|
||||||
|
public @NotNull List<Player> calculateRecipients() {
|
||||||
|
return recipientsFunction.apply(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the function that determines which players will receive the sound packet.
|
||||||
|
*
|
||||||
|
* @return recipients function
|
||||||
|
* @see #calculateRecipients()
|
||||||
|
* @see #setRecipientsFunction(Function)
|
||||||
|
*/
|
||||||
|
public @NotNull Function<@NotNull SoundEvent, @NotNull List<@NotNull Player>> getRecipientsFunction() {
|
||||||
|
return recipientsFunction;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the function that determines which players will receive the sound packet.
|
||||||
|
* <p>
|
||||||
|
* This function does not need to query {@link #getException()} as this is done automatically.
|
||||||
|
*
|
||||||
|
* @param recipientsFunction recipients function
|
||||||
|
* @see #calculateRecipients()
|
||||||
|
* @see #getRecipientsFunction()
|
||||||
|
*/
|
||||||
|
public void setRecipientsFunction(@NotNull Function<@NotNull SoundEvent, @NotNull List<@NotNull Player>> recipientsFunction) {
|
||||||
|
this.recipientsFunction = wrapRecipientsFunction(Objects.requireNonNull(recipientsFunction, "recipientsFunction cannot be null"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the function that overrides what {@link Sound} is sent to a {@link Player}.
|
||||||
|
*
|
||||||
|
* @return sound override function (or {@code null} if not overridden)
|
||||||
|
*/
|
||||||
|
public @Nullable BiFunction<@NotNull SoundEvent, @NotNull Player, @Nullable Sound> getSoundOverrideFunction() {
|
||||||
|
return soundOverrideFunction;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the function that overrides what {@link Sound} is sent to a {@link Player}.
|
||||||
|
*
|
||||||
|
* @param soundOverrideFunction function which accepts a sound event and a player and returns
|
||||||
|
* a sound (or {@code null} if the default sound should be used)
|
||||||
|
*/
|
||||||
|
public void setSoundOverrideFunction(@Nullable BiFunction<@NotNull SoundEvent, @NotNull Player, @Nullable Sound> soundOverrideFunction) {
|
||||||
|
this.soundOverrideFunction = soundOverrideFunction;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the sound that will be sent to a {@link Player}.
|
||||||
|
*
|
||||||
|
* @param player player to calculate the sound for
|
||||||
|
* @return sound that will be sent to the player
|
||||||
|
*/
|
||||||
|
public @NotNull Sound calculateSound(@NotNull Player player) {
|
||||||
|
if (soundOverrideFunction != null) {
|
||||||
|
try {
|
||||||
|
Sound override = soundOverrideFunction.apply(this, player);
|
||||||
|
if (override != null) {
|
||||||
|
return override;
|
||||||
|
}
|
||||||
|
} catch (Throwable e) {
|
||||||
|
LOGGER.error("Error while overriding sound for player " + player.getName(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sound;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the function that overrides what {@link Emitter} is used when playing this sound to a
|
||||||
|
* {@link Player}.
|
||||||
|
*
|
||||||
|
* @return emitter override function (or {@code null} if not overridden)
|
||||||
|
*/
|
||||||
|
public @Nullable BiFunction<@NotNull SoundEvent, @NotNull Player, @Nullable Emitter> getEmitterOverrideFunction() {
|
||||||
|
return emitterOverrideFunction;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the function that overrides what {@link Emitter} is used when playing this sound to a
|
||||||
|
* {@link Player}.
|
||||||
|
*
|
||||||
|
* @param emitterOverrideFunction function which accepts a sound event and a player and returns
|
||||||
|
* an emitter
|
||||||
|
* (or {@code null} if the default emitter should be used)
|
||||||
|
*/
|
||||||
|
public void setEmitterOverrideFunction(@Nullable BiFunction<@NotNull SoundEvent, @NotNull Player, @Nullable Emitter> emitterOverrideFunction) {
|
||||||
|
this.emitterOverrideFunction = emitterOverrideFunction;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the emitter that will be used when playing this sound to a {@link Player}.
|
||||||
|
*
|
||||||
|
* @param player player to calculate the emitter for
|
||||||
|
* @return emitter that will be used when playing the sound to the player
|
||||||
|
*/
|
||||||
|
public @NotNull Emitter calculateEmitter(@NotNull Player player) {
|
||||||
|
if (emitterOverrideFunction != null) {
|
||||||
|
try {
|
||||||
|
Emitter override = emitterOverrideFunction.apply(this, player);
|
||||||
|
if (override != null) {
|
||||||
|
return override;
|
||||||
|
}
|
||||||
|
} catch (Throwable e) {
|
||||||
|
LOGGER.error("Error while overriding emitter for player " + player.getName(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return emitter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCancelled() {
|
||||||
|
return cancelled;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCancelled(boolean cancelled) {
|
||||||
|
this.cancelled = cancelled;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static org.bukkit.event.HandlerList getHandlerList() {
|
||||||
|
return handlers;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull org.bukkit.event.HandlerList getHandlers() {
|
||||||
|
return handlers;
|
||||||
|
}
|
||||||
|
|
||||||
|
private record WrappedRecipientsFunction(@NotNull Function<SoundEvent, List<Player>> wrapped) implements Function<SoundEvent, List<Player>> {
|
||||||
|
@Override
|
||||||
|
public @NotNull List<Player> apply(@NotNull SoundEvent event) {
|
||||||
|
List<Player> recipients = wrapped.apply(event);
|
||||||
|
HumanEntity except = event.getException();
|
||||||
|
if (except != null) {
|
||||||
|
List<Player> filteredRecipients = new ArrayList<>(recipients.size());
|
||||||
|
for (Player player : recipients) {
|
||||||
|
if (!player.getUniqueId().equals(except.getUniqueId()))
|
||||||
|
filteredRecipients.add(player);
|
||||||
|
}
|
||||||
|
return filteredRecipients;
|
||||||
|
}
|
||||||
|
return recipients;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private static Function<SoundEvent, List<Player>> wrapRecipientsFunction(@NotNull Function<SoundEvent, List<Player>> recipientsFunction) {
|
||||||
|
if (recipientsFunction instanceof WrappedRecipientsFunction)
|
||||||
|
return recipientsFunction;
|
||||||
|
else
|
||||||
|
return new WrappedRecipientsFunction(recipientsFunction);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The class which determines where a sound will emit from.
|
||||||
|
*/
|
||||||
|
public sealed interface Emitter extends HasLocation permits EntityEmitter, LocationEmitter {
|
||||||
|
/**
|
||||||
|
* Gets the location at which the sound will be played.
|
||||||
|
*
|
||||||
|
* @return sound's location
|
||||||
|
* @deprecated use {@link #getLocation()} instead
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
@Deprecated
|
||||||
|
default Location location() {
|
||||||
|
return getLocation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An emitter which plays a sound from an entity.
|
||||||
|
*
|
||||||
|
* @param entity the entity from which the sound will be played
|
||||||
|
*/
|
||||||
|
public record EntityEmitter(@NotNull Entity entity) implements Emitter {
|
||||||
|
@Override
|
||||||
|
public @NotNull Location getLocation() {
|
||||||
|
return entity.getLocation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An emitter which plays a sound from a location.
|
||||||
|
*
|
||||||
|
* @param location the location from which the sound will be played
|
||||||
|
*/
|
||||||
|
public record LocationEmitter(@NotNull Location location) implements Emitter {
|
||||||
|
@Override
|
||||||
|
public @NotNull Location getLocation() {
|
||||||
|
return location;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
package gg.projecteden.parchment.inventory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A type of crafting recipe.
|
||||||
|
*/
|
||||||
|
public enum RecipeType {
|
||||||
|
/**
|
||||||
|
* Recipes crafted in the standard crafting table.
|
||||||
|
*/
|
||||||
|
CRAFTING(false),
|
||||||
|
/**
|
||||||
|
* Recipes for smelting an item inside a furnace.
|
||||||
|
*/
|
||||||
|
SMELTING(true),
|
||||||
|
/**
|
||||||
|
* Recipes for smelting an item inside a blasting furnace.
|
||||||
|
*/
|
||||||
|
BLASTING(true),
|
||||||
|
/**
|
||||||
|
* Recipes for smelting an item inside a smoker.
|
||||||
|
*/
|
||||||
|
SMOKING(true),
|
||||||
|
/**
|
||||||
|
* Recipes for cooking an item on a campfire.
|
||||||
|
*/
|
||||||
|
CAMPFIRE_COOKING(true),
|
||||||
|
/**
|
||||||
|
* Recipes for carving stones in a stonecutter.
|
||||||
|
*/
|
||||||
|
STONECUTTING(true),
|
||||||
|
/**
|
||||||
|
* Recipes for smithing an item in a smithing table.
|
||||||
|
*/
|
||||||
|
SMITHING(false),
|
||||||
|
;
|
||||||
|
|
||||||
|
private final boolean singleInput;
|
||||||
|
|
||||||
|
RecipeType(boolean singleInput) {
|
||||||
|
this.singleInput = singleInput;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if the recipe only accepts a single item for input.
|
||||||
|
* @return true if the recipe only accepts a single item for input
|
||||||
|
*/
|
||||||
|
public boolean isSingleInput() {
|
||||||
|
return singleInput;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,123 @@
|
|||||||
|
package gg.projecteden.parchment.sidebar;
|
||||||
|
|
||||||
|
import gg.projecteden.parchment.entity.EntityData;
|
||||||
|
import gg.projecteden.parchment.entity.EntityDataFragment;
|
||||||
|
import gg.projecteden.parchment.entity.EntityDataKey;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public final class Sidebar extends EntityDataFragment<Player> {
|
||||||
|
private static final EntityDataKey<Sidebar, Player> DATA_KEY = EntityData.createKey(Sidebar::new, Player.class);
|
||||||
|
|
||||||
|
private final SidebarBuffer[] buffer = new SidebarBuffer[2];
|
||||||
|
|
||||||
|
private final StageImpl stage = new StageImpl();
|
||||||
|
private final Runnable layoutListener;
|
||||||
|
|
||||||
|
private SidebarLayout layout;
|
||||||
|
|
||||||
|
private boolean visible;
|
||||||
|
private int back;
|
||||||
|
|
||||||
|
public static Sidebar get(Player player) {
|
||||||
|
Objects.requireNonNull(player);
|
||||||
|
|
||||||
|
return player.getStoredEntityData().get(Sidebar.DATA_KEY);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Sidebar() {
|
||||||
|
this.buffer[0] = SidebarBufferUtilSpec.IMPL_KEY.get().create("_sidebar_l");
|
||||||
|
this.buffer[1] = SidebarBufferUtilSpec.IMPL_KEY.get().create("_sidebar_r");
|
||||||
|
|
||||||
|
this.layoutListener = () -> {
|
||||||
|
this.layout.update(this.stage);
|
||||||
|
this.flush();
|
||||||
|
};
|
||||||
|
|
||||||
|
this.setPersistent(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void applyLayout(SidebarLayout layout) {
|
||||||
|
if (this.layout != null) {
|
||||||
|
this.layout.unsubscribe(this.layoutListener);
|
||||||
|
this.buffer[this.back].clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.layout = layout;
|
||||||
|
|
||||||
|
if (layout == null) {
|
||||||
|
this.hide();
|
||||||
|
} else {
|
||||||
|
layout.setup(this.stage);
|
||||||
|
this.flush();
|
||||||
|
|
||||||
|
layout.subscribe(this.layoutListener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setTitle(String title) {
|
||||||
|
this.buffer[this.back].setTitle(title);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setLine(int idx, String value, String display) {
|
||||||
|
if (value == null) {
|
||||||
|
this.buffer[this.back].clearLine(idx);
|
||||||
|
} else {
|
||||||
|
this.buffer[this.back].setLine(idx, value, display);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void flush() {
|
||||||
|
SidebarBuffer front = this.buffer[this.back];
|
||||||
|
SidebarBuffer back = this.buffer[this.back ^ 1];
|
||||||
|
boolean shouldShow = !this.visible;
|
||||||
|
|
||||||
|
if (front.hasDiverged(back)) {
|
||||||
|
front.pushChanges();
|
||||||
|
|
||||||
|
back.sync(front);
|
||||||
|
this.back ^= 1;
|
||||||
|
|
||||||
|
shouldShow = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shouldShow) {
|
||||||
|
front.setActive();
|
||||||
|
this.visible = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void hide() {
|
||||||
|
SidebarBufferUtilSpec.IMPL_KEY.get().hideSidebar(this.getOwner());
|
||||||
|
this.visible = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onOwnerChange() {
|
||||||
|
this.buffer[0].setOwner(this.getOwner());
|
||||||
|
this.buffer[1].setOwner(this.getOwner());
|
||||||
|
|
||||||
|
if (this.visible) {
|
||||||
|
this.buffer[this.back ^ 1].setActive();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final class StageImpl implements SidebarStage {
|
||||||
|
@Override
|
||||||
|
public void setTitle(String title) {
|
||||||
|
Sidebar.this.setTitle(title);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLine(int line, String value) {
|
||||||
|
this.setLine(line, value, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLine(int line, String value, String display) {
|
||||||
|
Sidebar.this.setLine(line, value, display);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
package gg.projecteden.parchment.sidebar;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public abstract class SidebarBuffer {
|
||||||
|
|
||||||
|
@SuppressWarnings("StringOperationCanBeSimplified")
|
||||||
|
private static final String AUTO_SPACE = new String();
|
||||||
|
protected final String name;
|
||||||
|
protected final int size;
|
||||||
|
protected final String[] liveLines;
|
||||||
|
protected final String[] stagedLines;
|
||||||
|
protected final String[] liveDisplays;
|
||||||
|
protected final String[] stagedDisplays;
|
||||||
|
|
||||||
|
protected String liveTitle = "";
|
||||||
|
protected String stagedTitle = "";
|
||||||
|
|
||||||
|
protected SidebarBuffer(String name, int size) {
|
||||||
|
this.name = name;
|
||||||
|
this.size = size;
|
||||||
|
this.liveLines = new String[size];
|
||||||
|
this.stagedLines = new String[size];
|
||||||
|
this.liveDisplays = new String[size];
|
||||||
|
this.stagedDisplays = new String[size];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void setActive();
|
||||||
|
|
||||||
|
protected abstract void pushChanges();
|
||||||
|
|
||||||
|
protected abstract void setOwner(Player player);
|
||||||
|
|
||||||
|
protected abstract boolean checkTitle(String title);
|
||||||
|
|
||||||
|
protected abstract boolean checkLine(String line);
|
||||||
|
|
||||||
|
void setTitle(String title) {
|
||||||
|
this.stagedTitle = Objects.requireNonNullElse(title, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
void setLine(int line, String value, String display) {
|
||||||
|
Objects.requireNonNull(value);
|
||||||
|
if (line < 0 || line > this.size - 1) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.stagedLines[line] = value;
|
||||||
|
this.stagedDisplays[line] = display;
|
||||||
|
|
||||||
|
for (int i = line - 1; i >= 0; i--) {
|
||||||
|
if (this.stagedLines[i] == null) {
|
||||||
|
this.stagedLines[i] = SidebarBuffer.AUTO_SPACE;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void clearLine(int line) {
|
||||||
|
if (line < 0 || line > this.size - 1) {
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.stagedLines[line] = SidebarBuffer.AUTO_SPACE;
|
||||||
|
|
||||||
|
if (line + 1 == this.size || this.stagedLines[line + 1] == null) {
|
||||||
|
for (int i = line; i >= 0; i--) {
|
||||||
|
if (this.stagedLines[i] == SidebarBuffer.AUTO_SPACE) {
|
||||||
|
this.stagedLines[i] = null;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sync(SidebarBuffer live) {
|
||||||
|
this.stagedTitle = live.liveTitle;
|
||||||
|
System.arraycopy(live.liveLines, 0, this.stagedLines, 0, this.size);
|
||||||
|
System.arraycopy(live.liveDisplays, 0, this.stagedDisplays, 0, this.size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear() {
|
||||||
|
this.stagedTitle = "";
|
||||||
|
Arrays.fill(this.stagedLines, null);
|
||||||
|
Arrays.fill(this.stagedDisplays, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean hasDiverged(SidebarBuffer live) {
|
||||||
|
boolean out = !Objects.equals(this.stagedTitle, live.liveTitle);
|
||||||
|
out = out || !Arrays.equals(this.stagedLines, live.liveLines);
|
||||||
|
out = out || !Arrays.equals(this.stagedDisplays, live.liveDisplays);
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package gg.projecteden.parchment.sidebar;
|
||||||
|
|
||||||
|
import gg.projecteden.parchment.entity.EntityDataServiceKey;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
public interface SidebarBufferUtilSpec {
|
||||||
|
EntityDataServiceKey<SidebarBufferUtilSpec> IMPL_KEY = new EntityDataServiceKey<>(SidebarBufferUtilSpec.class);
|
||||||
|
|
||||||
|
SidebarBuffer create(String bufferName);
|
||||||
|
|
||||||
|
void hideSidebar(Player player);
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
package gg.projecteden.parchment.sidebar;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A sidebar layout. Subclasses can describe custom layouts by using the
|
||||||
|
* {@link #setup(SidebarStage)} and {@link #update(SidebarStage)} hooks.
|
||||||
|
*/
|
||||||
|
public abstract class SidebarLayout {
|
||||||
|
private final Set<Runnable> subscribers = new HashSet<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pushes an update to all subscribers.
|
||||||
|
*/
|
||||||
|
public final void refresh() {
|
||||||
|
synchronized (this.subscribers) {
|
||||||
|
for (Runnable s : this.subscribers) {
|
||||||
|
s.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs when the layout is first applied.
|
||||||
|
*
|
||||||
|
* <p> The provided sidebar stage may be used to create the first
|
||||||
|
* frame of sidebar data, which will be pushed to the client upon
|
||||||
|
* exit of this method.
|
||||||
|
*
|
||||||
|
* @param stage The sidebar stage. Using it outside this method will
|
||||||
|
* result in undefined behavior.
|
||||||
|
*/
|
||||||
|
protected void setup(SidebarStage stage) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs when a refresh is requested.
|
||||||
|
*
|
||||||
|
* <p> The provided sidebar stage may be used to update the existing
|
||||||
|
* sidebar data, which will be pushed to the client upon exit of
|
||||||
|
* this method. Sidebar data from previous hook calls will stay the
|
||||||
|
* same unless explicitly changed here.
|
||||||
|
*
|
||||||
|
* @param stage The sidebar stage. Using it outside this method will
|
||||||
|
* result in undefined behavior.
|
||||||
|
*/
|
||||||
|
protected void update(SidebarStage stage) {
|
||||||
|
}
|
||||||
|
|
||||||
|
final void subscribe(Runnable listener) {
|
||||||
|
this.subscribers.add(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
final void unsubscribe(Runnable listener) {
|
||||||
|
this.subscribers.remove(listener);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package gg.projecteden.parchment.sidebar;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An abstracted sidebar stage.
|
||||||
|
*/
|
||||||
|
public interface SidebarStage {
|
||||||
|
/**
|
||||||
|
* Stages a new title.
|
||||||
|
*
|
||||||
|
* @param title The new title.
|
||||||
|
*/
|
||||||
|
void setTitle(String title);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stages a new line at the provided index.
|
||||||
|
*
|
||||||
|
* @param line The line index.
|
||||||
|
* @param value The new line.
|
||||||
|
*/
|
||||||
|
void setLine(int line, String value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stages a new line at the provided index
|
||||||
|
* Uses the display as the right aligned text
|
||||||
|
*
|
||||||
|
* @param line The line index
|
||||||
|
* @param value The new line
|
||||||
|
* @param display The right aligned text
|
||||||
|
*/
|
||||||
|
void setLine(int line, String value, String display);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
// macheOldPath = file("F:\\Projects\\PaperTooling\\mache\\versions\\1.21.4\\src\\main\\java")
|
// macheOldPath = file("F:\\Projects\\PaperTooling\\mache\\versions\\1.21.4\\src\\main\\java")
|
||||||
// gitFilePatches = true
|
// gitFilePatches = true
|
||||||
|
|
||||||
+ val fork = forks.register("fork") {
|
+ val fork = forks.register("parchment") {
|
||||||
+ upstream.patchDir("paperServer") {
|
+ upstream.patchDir("paperServer") {
|
||||||
+ upstreamPath = "paper-server"
|
+ upstreamPath = "paper-server"
|
||||||
+ excludes = setOf("src/minecraft", "patches", "build.gradle.kts")
|
+ excludes = setOf("src/minecraft", "patches", "build.gradle.kts")
|
||||||
@@ -52,3 +52,23 @@
|
|||||||
implementation("ca.spottedleaf:concurrentutil:0.0.2")
|
implementation("ca.spottedleaf:concurrentutil:0.0.2")
|
||||||
implementation("org.jline:jline-terminal-ffm:3.27.1") // use ffm on java 22+
|
implementation("org.jline:jline-terminal-ffm:3.27.1") // use ffm on java 22+
|
||||||
implementation("org.jline:jline-terminal-jni:3.27.1") // fall back to jni on java 21
|
implementation("org.jline:jline-terminal-jni:3.27.1") // fall back to jni on java 21
|
||||||
|
@@ -192,14 +_,14 @@
|
||||||
|
val gitBranch = git.exec(providers, "rev-parse", "--abbrev-ref", "HEAD").get().trim()
|
||||||
|
attributes(
|
||||||
|
"Main-Class" to "org.bukkit.craftbukkit.Main",
|
||||||
|
- "Implementation-Title" to "Paper",
|
||||||
|
+ "Implementation-Title" to "Parchment",
|
||||||
|
"Implementation-Version" to implementationVersion,
|
||||||
|
"Implementation-Vendor" to date,
|
||||||
|
- "Specification-Title" to "Paper",
|
||||||
|
+ "Specification-Title" to "Parchment",
|
||||||
|
"Specification-Version" to project.version,
|
||||||
|
- "Specification-Vendor" to "Paper Team",
|
||||||
|
- "Brand-Id" to "papermc:paper",
|
||||||
|
- "Brand-Name" to "Paper",
|
||||||
|
+ "Specification-Vendor" to "Project Eden",
|
||||||
|
+ "Brand-Id" to "projectedengg:parchment",
|
||||||
|
+ "Brand-Name" to "Parchment",
|
||||||
|
"Build-Number" to (build ?: ""),
|
||||||
|
"Build-Time" to buildTime.toString(),
|
||||||
|
"Git-Branch" to gitBranch,
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package gg.projecteden.parchment.entity;
|
||||||
|
|
||||||
|
import gg.projecteden.parchment.sidebar.SidebarBufferUtil;
|
||||||
|
import gg.projecteden.parchment.sidebar.SidebarBufferUtilSpec;
|
||||||
|
|
||||||
|
public class EntityDataServices {
|
||||||
|
|
||||||
|
private static boolean initialized;
|
||||||
|
|
||||||
|
public static void init() {
|
||||||
|
if (initialized) {
|
||||||
|
throw new RuntimeException("EntityData Services already initialized");
|
||||||
|
}
|
||||||
|
initialized = true;
|
||||||
|
|
||||||
|
// Initialize Services Here
|
||||||
|
SidebarBufferUtilSpec.IMPL_KEY.set(new SidebarBufferUtil());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package gg.projecteden.parchment.event.sound;
|
||||||
|
|
||||||
|
import io.papermc.paper.adventure.PaperAdventure;
|
||||||
|
import net.kyori.adventure.sound.Sound;
|
||||||
|
import net.minecraft.sounds.SoundEvent;
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
public class ParchmentSoundEvent {
|
||||||
|
public static final Function<Sound, Double> DISTANCE_FUNCTION = sound -> {
|
||||||
|
Optional<SoundEvent> soundEvent = PaperAdventure.asVanillaSound(sound.name());
|
||||||
|
if (soundEvent.isPresent())
|
||||||
|
return Double.valueOf(soundEvent.get().getRange(sound.volume()));
|
||||||
|
return gg.projecteden.parchment.event.sound.SoundEvent.DEFAULT_DISTANCE_FUNCTION.apply(sound);
|
||||||
|
};
|
||||||
|
|
||||||
|
public static gg.projecteden.parchment.event.sound.SoundEvent.Emitter createEmitter(Level level, double x, double y, double z) {
|
||||||
|
return new gg.projecteden.parchment.event.sound.SoundEvent.LocationEmitter(new Location(level.getWorld(), x, y, z));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static gg.projecteden.parchment.event.sound.SoundEvent.Emitter createEmitter(Entity entity) {
|
||||||
|
return new gg.projecteden.parchment.event.sound.SoundEvent.EntityEmitter(entity.getBukkitEntity());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package gg.projecteden.parchment.inventory;
|
||||||
|
|
||||||
|
import net.minecraft.world.item.crafting.AbstractCookingRecipe;
|
||||||
|
|
||||||
|
public class CraftRecipeType {
|
||||||
|
public static net.minecraft.world.item.crafting.RecipeType asNMS(RecipeType recipeType) {
|
||||||
|
return switch (recipeType) {
|
||||||
|
case CRAFTING -> net.minecraft.world.item.crafting.RecipeType.CRAFTING;
|
||||||
|
case SMELTING -> net.minecraft.world.item.crafting.RecipeType.SMELTING;
|
||||||
|
case BLASTING -> net.minecraft.world.item.crafting.RecipeType.BLASTING;
|
||||||
|
case SMOKING -> net.minecraft.world.item.crafting.RecipeType.SMOKING;
|
||||||
|
case CAMPFIRE_COOKING -> net.minecraft.world.item.crafting.RecipeType.CAMPFIRE_COOKING;
|
||||||
|
case STONECUTTING -> net.minecraft.world.item.crafting.RecipeType.STONECUTTING;
|
||||||
|
case SMITHING -> net.minecraft.world.item.crafting.RecipeType.SMITHING;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RecipeType asBukkit(net.minecraft.world.item.crafting.RecipeType recipeType) {
|
||||||
|
if (recipeType == net.minecraft.world.item.crafting.RecipeType.CRAFTING) {
|
||||||
|
return RecipeType.CRAFTING;
|
||||||
|
} else if (recipeType == net.minecraft.world.item.crafting.RecipeType.SMELTING) {
|
||||||
|
return RecipeType.SMELTING;
|
||||||
|
} else if (recipeType == net.minecraft.world.item.crafting.RecipeType.BLASTING) {
|
||||||
|
return RecipeType.BLASTING;
|
||||||
|
} else if (recipeType == net.minecraft.world.item.crafting.RecipeType.SMOKING) {
|
||||||
|
return RecipeType.SMOKING;
|
||||||
|
} else if (recipeType == net.minecraft.world.item.crafting.RecipeType.CAMPFIRE_COOKING) {
|
||||||
|
return RecipeType.CAMPFIRE_COOKING;
|
||||||
|
} else if (recipeType == net.minecraft.world.item.crafting.RecipeType.STONECUTTING) {
|
||||||
|
return RecipeType.STONECUTTING;
|
||||||
|
} else if (recipeType == net.minecraft.world.item.crafting.RecipeType.SMITHING) {
|
||||||
|
return RecipeType.SMITHING;
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("Unknown recipe type");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static net.minecraft.world.item.crafting.RecipeType<AbstractCookingRecipe> asCookingRecipe(RecipeType recipeType) {
|
||||||
|
try {
|
||||||
|
return (net.minecraft.world.item.crafting.RecipeType<AbstractCookingRecipe>) asNMS(recipeType);
|
||||||
|
} catch (ClassCastException exc) {
|
||||||
|
throw new IllegalArgumentException("Recipe type must be a cooking recipe");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,151 @@
|
|||||||
|
package gg.projecteden.parchment.inventory;
|
||||||
|
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
|
import net.minecraft.world.Container;
|
||||||
|
import net.minecraft.world.entity.player.Player;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.craftbukkit.entity.CraftHumanEntity;
|
||||||
|
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
||||||
|
import org.bukkit.entity.HumanEntity;
|
||||||
|
import org.bukkit.inventory.InventoryHolder;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A container which holds only one item and returns similar values to that of
|
||||||
|
* {@link net.minecraft.world.SimpleContainer SimpleContainer}, meaning it will raise
|
||||||
|
* {@link IndexOutOfBoundsException IndexOutOfBoundsExceptions} and return empty item stacks
|
||||||
|
* where applicable to mirror that class.
|
||||||
|
*/
|
||||||
|
public class SingletonContainer implements net.minecraft.world.Container {
|
||||||
|
|
||||||
|
private @NotNull ItemStack item;
|
||||||
|
private int maxStackSize = Container.MAX_STACK;
|
||||||
|
|
||||||
|
public SingletonContainer() {
|
||||||
|
this.item = ItemStack.EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SingletonContainer(@NotNull ItemStack item) {
|
||||||
|
this.item = Preconditions.checkNotNull(item, "item");
|
||||||
|
}
|
||||||
|
|
||||||
|
public SingletonContainer(org.bukkit.inventory.@NotNull ItemStack item) {
|
||||||
|
this.item = CraftItemStack.asNMSCopy(Preconditions.checkNotNull(item, "item"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public SingletonContainer(@NotNull Material material) {
|
||||||
|
this(new org.bukkit.inventory.ItemStack(Preconditions.checkNotNull(material, "material")));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void throwIndexException(int index) {
|
||||||
|
throw new IndexOutOfBoundsException("Received slot " + index + ", expected 0");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getContainerSize() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return item.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack getItem(int slot) {
|
||||||
|
if (slot < 0) {
|
||||||
|
throwIndexException(slot);
|
||||||
|
}
|
||||||
|
return slot == 0 ? item : ItemStack.EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack removeItem(int slot, int amount) {
|
||||||
|
if (slot < 0) {
|
||||||
|
throwIndexException(slot);
|
||||||
|
}
|
||||||
|
ItemStack itemStack = slot == 0 && !item.isEmpty() ? item.split(amount) : ItemStack.EMPTY;
|
||||||
|
if (!itemStack.isEmpty()) {
|
||||||
|
setChanged();
|
||||||
|
}
|
||||||
|
return itemStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack removeItemNoUpdate(int slot) {
|
||||||
|
if (slot != 0) {
|
||||||
|
throwIndexException(slot);
|
||||||
|
}
|
||||||
|
ItemStack oldItem = item;
|
||||||
|
item = ItemStack.EMPTY;
|
||||||
|
return oldItem.isEmpty() ? ItemStack.EMPTY : oldItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setItem(int slot, ItemStack stack) {
|
||||||
|
if (slot != 0) {
|
||||||
|
throwIndexException(slot);
|
||||||
|
}
|
||||||
|
item = stack;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxStackSize() {
|
||||||
|
return maxStackSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMaxStackSize(int size) {
|
||||||
|
maxStackSize = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setChanged() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean stillValid(Player player) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ItemStack> getContents() {
|
||||||
|
return Collections.singletonList(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onOpen(CraftHumanEntity who) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClose(CraftHumanEntity who) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<HumanEntity> getViewers() {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InventoryHolder getOwner() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Location getLocation() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearContent() {
|
||||||
|
item = ItemStack.EMPTY;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,182 @@
|
|||||||
|
package gg.projecteden.parchment.sidebar;
|
||||||
|
|
||||||
|
import gg.projecteden.parchment.util.StringUtils;
|
||||||
|
import net.minecraft.network.Connection;
|
||||||
|
import net.minecraft.network.chat.Component;
|
||||||
|
import net.minecraft.network.chat.numbers.BlankFormat;
|
||||||
|
import net.minecraft.network.chat.numbers.FixedFormat;
|
||||||
|
import net.minecraft.network.chat.numbers.NumberFormat;
|
||||||
|
import net.minecraft.network.protocol.game.*;
|
||||||
|
import net.minecraft.server.dedicated.DedicatedServer;
|
||||||
|
import net.minecraft.world.scores.DisplaySlot;
|
||||||
|
import net.minecraft.world.scores.Objective;
|
||||||
|
import net.minecraft.world.scores.PlayerTeam;
|
||||||
|
import net.minecraft.world.scores.Team;
|
||||||
|
import net.minecraft.world.scores.criteria.ObjectiveCriteria;
|
||||||
|
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public class SidebarBufferImpl extends SidebarBuffer {
|
||||||
|
|
||||||
|
private static final int NAME_LIMIT = 38;
|
||||||
|
private static final int AFFIX_LIMIT = 16;
|
||||||
|
private static final int SIZE = 15;
|
||||||
|
|
||||||
|
static final int SIDEBAR_SLOT = 1;
|
||||||
|
private final Objective objective = new Objective(DedicatedServer.getServer().getScoreboard(), this.name,
|
||||||
|
ObjectiveCriteria.DUMMY, Component.literal(this.stagedTitle), ObjectiveCriteria.RenderType.INTEGER,
|
||||||
|
false, null);
|
||||||
|
|
||||||
|
private Connection connection;
|
||||||
|
|
||||||
|
SidebarBufferImpl(String name) {
|
||||||
|
super(name, SidebarBufferImpl.SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setActive() {
|
||||||
|
objective.setDisplayName(Component.literal(StringUtils.colorize(this.stagedTitle)));
|
||||||
|
ClientboundSetObjectivePacket packet = new ClientboundSetObjectivePacket(this.objective, ClientboundSetObjectivePacket.METHOD_CHANGE);
|
||||||
|
ClientboundSetDisplayObjectivePacket packet2 = new ClientboundSetDisplayObjectivePacket(DisplaySlot.SIDEBAR, this.objective);
|
||||||
|
|
||||||
|
this.connection.send(packet);
|
||||||
|
this.connection.send(packet2);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void pushChanges() {
|
||||||
|
if (!Objects.equals(this.liveTitle, this.stagedTitle)) {
|
||||||
|
this.liveTitle = this.stagedTitle;
|
||||||
|
|
||||||
|
ClientboundSetObjectivePacket packet = new ClientboundSetObjectivePacket(this.objective, ClientboundSetObjectivePacket.METHOD_CHANGE);
|
||||||
|
|
||||||
|
this.connection.send(packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
int liveEnd = this.size;
|
||||||
|
for (int i = 0; i < this.size; i++) {
|
||||||
|
if (this.liveLines[i] == null) {
|
||||||
|
liveEnd = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int stagedEnd = this.size;
|
||||||
|
for (int i = 0; i < this.size; i++) {
|
||||||
|
if (this.stagedLines[i] == null) {
|
||||||
|
stagedEnd = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int maxEnd = Math.max(liveEnd, stagedEnd);
|
||||||
|
int liveIdx = liveEnd - maxEnd;
|
||||||
|
int stagedIdx = stagedEnd - maxEnd;
|
||||||
|
|
||||||
|
for (int i = 0; i < this.size; i++) {
|
||||||
|
String live = liveIdx >= 0 ? this.liveLines[liveIdx] : null;
|
||||||
|
String staged = stagedIdx >= 0 ? this.stagedLines[stagedIdx] : null;
|
||||||
|
|
||||||
|
String liveDisplay = liveIdx >= 0 ? this.liveDisplays[liveIdx] : null;
|
||||||
|
String stagedDisplay = stagedIdx >= 0 ? this.stagedDisplays[stagedIdx] : null;
|
||||||
|
|
||||||
|
if (!Objects.equals(live, staged) || !Objects.equals(liveDisplay, stagedDisplay)) {
|
||||||
|
if (live != null) {
|
||||||
|
this.sendDelete(live, liveEnd - liveIdx);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (staged != null) {
|
||||||
|
this.sendCreate(staged, stagedEnd - stagedIdx, this.stagedDisplays[stagedIdx]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
liveIdx++;
|
||||||
|
stagedIdx++;
|
||||||
|
}
|
||||||
|
|
||||||
|
System.arraycopy(this.stagedLines, 0, this.liveLines, 0, this.size);
|
||||||
|
System.arraycopy(this.stagedDisplays, 0, this.liveDisplays, 0, this.size);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setOwner(Player player) {
|
||||||
|
this.connection = ((CraftPlayer) player).getHandle().connection.connection;
|
||||||
|
|
||||||
|
ClientboundSetObjectivePacket packet = new ClientboundSetObjectivePacket(this.objective, ClientboundSetObjectivePacket.METHOD_ADD);
|
||||||
|
this.connection.send(packet);
|
||||||
|
|
||||||
|
for (int i = 0; i < this.size; i++) {
|
||||||
|
String live = this.liveLines[i];
|
||||||
|
|
||||||
|
if (live != null) {
|
||||||
|
this.sendCreate(live, i, stagedDisplays[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean checkTitle(String line) {
|
||||||
|
return line.length() <= 32;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean checkLine(String line) {
|
||||||
|
return line.length() <= SidebarBufferImpl.NAME_LIMIT + SidebarBufferImpl.AFFIX_LIMIT * 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendCreate(String value, int line, String display) {
|
||||||
|
String id = "\u00a7" + (char) ('\u0080' + line);
|
||||||
|
value = StringUtils.colorize(value);
|
||||||
|
|
||||||
|
if (value.length() > SidebarBufferImpl.NAME_LIMIT) {
|
||||||
|
String prefix = value.substring(0, SidebarBufferImpl.AFFIX_LIMIT);
|
||||||
|
String suffix = "";
|
||||||
|
|
||||||
|
value = value.substring(SidebarBufferImpl.AFFIX_LIMIT);
|
||||||
|
|
||||||
|
if (value.length() > SidebarBufferImpl.NAME_LIMIT) {
|
||||||
|
suffix = value.substring(SidebarBufferImpl.NAME_LIMIT);
|
||||||
|
value = value.substring(0, SidebarBufferImpl.NAME_LIMIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
PlayerTeam team = new PlayerTeam(DedicatedServer.getServer().getScoreboard(), this.getTeamName(line));
|
||||||
|
team.setPlayerPrefix(Component.literal(prefix));
|
||||||
|
team.setPlayerSuffix(Component.literal(suffix));
|
||||||
|
team.setNameTagVisibility(Team.Visibility.NEVER);
|
||||||
|
team.setCollisionRule(Team.CollisionRule.NEVER);
|
||||||
|
team.getPlayers().add(id + value);
|
||||||
|
ClientboundSetPlayerTeamPacket packet = ClientboundSetPlayerTeamPacket.createAddOrModifyPacket(team, true);
|
||||||
|
|
||||||
|
this.connection.send(packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
java.util.Optional<NumberFormat> numberFormat = java.util.Optional.of((display == null || display.isEmpty() || display.isBlank()) ? BlankFormat.INSTANCE : new FixedFormat(Component.literal(StringUtils.colorize(display))));
|
||||||
|
ClientboundSetScorePacket packet = new ClientboundSetScorePacket(id + value, this.name, line, Optional.empty(), numberFormat);
|
||||||
|
|
||||||
|
this.connection.send(packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendDelete(String value, int line) {
|
||||||
|
String id = "\u00a7" + (char) ('\u0080' + line);
|
||||||
|
|
||||||
|
value = StringUtils.colorize(value);
|
||||||
|
|
||||||
|
if (value.length() > SidebarBufferImpl.NAME_LIMIT) {
|
||||||
|
value = value.substring(
|
||||||
|
SidebarBufferImpl.AFFIX_LIMIT,
|
||||||
|
Math.min(value.length(), SidebarBufferImpl.AFFIX_LIMIT + SidebarBufferImpl.NAME_LIMIT)
|
||||||
|
);
|
||||||
|
|
||||||
|
ClientboundSetPlayerTeamPacket packet = ClientboundSetPlayerTeamPacket.createRemovePacket(DedicatedServer.getServer().getScoreboard().getPlayerTeam(this.getTeamName(line)));
|
||||||
|
this.connection.send(packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
ClientboundResetScorePacket packet = new ClientboundResetScorePacket(id + value, this.name);
|
||||||
|
this.connection.send(packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getTeamName(int line) {
|
||||||
|
return this.name + "/" + Integer.toUnsignedString(line, 32);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package gg.projecteden.parchment.sidebar;
|
||||||
|
|
||||||
|
import net.minecraft.network.protocol.game.ClientboundSetDisplayObjectivePacket;
|
||||||
|
import net.minecraft.world.scores.DisplaySlot;
|
||||||
|
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
public class SidebarBufferUtil implements SidebarBufferUtilSpec {
|
||||||
|
@Override
|
||||||
|
public SidebarBuffer create(String name) {
|
||||||
|
return new SidebarBufferImpl(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void hideSidebar(Player player) {
|
||||||
|
ClientboundSetDisplayObjectivePacket packet = new ClientboundSetDisplayObjectivePacket(DisplaySlot.SIDEBAR, null);
|
||||||
|
((CraftPlayer) player).getHandle().connection.send(packet);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package gg.projecteden.parchment.util;
|
||||||
|
|
||||||
|
import net.md_5.bungee.api.ChatColor;
|
||||||
|
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class StringUtils {
|
||||||
|
|
||||||
|
private static final String colorChar = "§";
|
||||||
|
private static final String altColorChar = "&";
|
||||||
|
private static final String colorCharsRegex = "[" + colorChar + altColorChar + "]";
|
||||||
|
private static final Pattern hexPattern = Pattern.compile(colorCharsRegex + "#[a-fA-F\\d]{6}");
|
||||||
|
|
||||||
|
public static String colorize(String input) {
|
||||||
|
if (input == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
Matcher matcher = hexPattern.matcher(input);
|
||||||
|
if (!matcher.find()) break;
|
||||||
|
|
||||||
|
String color = matcher.group();
|
||||||
|
input = input.replace(color, ChatColor.of(color.replaceFirst(colorCharsRegex, "")).toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
return ChatColor.translateAlternateColorCodes(altColorChar.charAt(0), input);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -10,7 +10,7 @@ plugins {
|
|||||||
id("org.gradle.toolchains.foojay-resolver-convention") version "0.9.0"
|
id("org.gradle.toolchains.foojay-resolver-convention") version "0.9.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
rootProject.name = "fork"
|
rootProject.name = "Parchment"
|
||||||
|
|
||||||
include("fork-api")
|
include("parchment-api")
|
||||||
include("fork-server")
|
include("parchment-server")
|
||||||
|
|||||||
Reference in New Issue
Block a user