More more more more more more work
This commit is contained in:
parent
7409d8fed7
commit
f51c531b94
42 changed files with 58 additions and 57 deletions
|
@ -0,0 +1,55 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Wed, 15 Aug 2018 01:16:34 -0400
|
||||
Subject: [PATCH] Ability to get Tile Entities from a chunk without snapshots
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
|
||||
@@ -0,0 +0,0 @@ public class CraftChunk implements Chunk {
|
||||
|
||||
@Override
|
||||
public BlockState[] getTileEntities() {
|
||||
+ // Paper start
|
||||
+ return getTileEntities(true);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public BlockState[] getTileEntities(boolean useSnapshot) {
|
||||
+ // Paper end
|
||||
if (!this.isLoaded()) {
|
||||
this.getWorld().getChunkAt(x, z); // Transient load for this tick
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class CraftChunk implements Chunk {
|
||||
BlockState[] entities = new BlockState[chunk.blockEntities.size()];
|
||||
|
||||
for (BlockPos position : chunk.blockEntities.keySet()) {
|
||||
- entities[index++] = this.worldServer.getWorld().getBlockAt(position.getX(), position.getY(), position.getZ()).getState();
|
||||
+ // Paper start
|
||||
+ entities[index++] = this.worldServer.getWorld().getBlockAt(position.getX(), position.getY(), position.getZ()).getState(useSnapshot);
|
||||
+ }
|
||||
+
|
||||
+ return entities;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public Collection<BlockState> getTileEntities(Predicate<Block> blockPredicate, boolean useSnapshot) {
|
||||
+ Preconditions.checkNotNull(blockPredicate, "blockPredicate");
|
||||
+ if (!this.isLoaded()) {
|
||||
+ this.getWorld().getChunkAt(this.x, this.z); // Transient load for this tick
|
||||
+ }
|
||||
+ ChunkAccess chunk = this.getHandle(ChunkStatus.FULL);
|
||||
+
|
||||
+ java.util.List<BlockState> entities = new java.util.ArrayList<>();
|
||||
+
|
||||
+ for (BlockPos position : chunk.blockEntities.keySet()) {
|
||||
+ Block block = this.worldServer.getWorld().getBlockAt(position.getX(), position.getY(), position.getZ());
|
||||
+ if (blockPredicate.test(block)) {
|
||||
+ entities.add(block.getState(useSnapshot));
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
return entities;
|
|
@ -0,0 +1,129 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sat, 21 Jul 2018 08:25:40 -0400
|
||||
Subject: [PATCH] Add Debug Entities option to debug dupe uuid issues
|
||||
|
||||
Add -Ddebug.entities=true to your JVM flags to gain more information
|
||||
|
||||
1.17: Needs to be reworked for new entity storage system
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
} else {
|
||||
ChunkMap.TrackedEntity playerchunkmap_entitytracker = new ChunkMap.TrackedEntity(entity, i, j, entitytypes.trackDeltas());
|
||||
|
||||
+ entity.tracker = playerchunkmap_entitytracker; // Paper - Fast access to tracker
|
||||
this.entityMap.put(entity.getId(), playerchunkmap_entitytracker);
|
||||
playerchunkmap_entitytracker.updatePlayers(this.level.players());
|
||||
if (entity instanceof ServerPlayer) {
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
if (playerchunkmap_entitytracker1 != null) {
|
||||
playerchunkmap_entitytracker1.broadcastRemoved();
|
||||
}
|
||||
-
|
||||
+ entity.tracker = null; // Paper - We're no longer tracked
|
||||
}
|
||||
|
||||
protected void tick() {
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -0,0 +0,0 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
||||
public final LevelStorageSource.LevelStorageAccess convertable;
|
||||
public final UUID uuid;
|
||||
public boolean hasPhysicsEvent = true; // Paper
|
||||
+ public static Throwable getAddToWorldStackTrace(Entity entity) {
|
||||
+ return new Throwable(entity + " Added to world at " + new java.util.Date());
|
||||
+ }
|
||||
|
||||
@Override public LevelChunk getChunkIfLoaded(int x, int z) { // Paper - this was added in world too but keeping here for NMS ABI
|
||||
return this.chunkSource.getChunk(x, z, false);
|
||||
@@ -0,0 +0,0 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
||||
// CraftBukkit start
|
||||
private boolean addEntity(Entity entity, CreatureSpawnEvent.SpawnReason spawnReason) {
|
||||
org.spigotmc.AsyncCatcher.catchOp("entity add"); // Spigot
|
||||
+ // Paper start
|
||||
+ if (entity.valid) {
|
||||
+ MinecraftServer.LOGGER.error("Attempted Double World add on " + entity, new Throwable());
|
||||
+
|
||||
+ if (DEBUG_ENTITIES) {
|
||||
+ Throwable thr = entity.addedToWorldStack;
|
||||
+ if (thr == null) {
|
||||
+ MinecraftServer.LOGGER.error("Double add entity has no add stacktrace");
|
||||
+ } else {
|
||||
+ MinecraftServer.LOGGER.error("Double add stacktrace: ", thr);
|
||||
+ }
|
||||
+ }
|
||||
+ return true;
|
||||
+ }
|
||||
+ // Paper end
|
||||
if (entity.isRemoved()) {
|
||||
+ // Paper start
|
||||
+ if (DEBUG_ENTITIES) {
|
||||
+ new Throwable("Tried to add entity " + entity + " but it was marked as removed already").printStackTrace(); // CraftBukkit
|
||||
+ getAddToWorldStackTrace(entity).printStackTrace();
|
||||
+ }
|
||||
+ // Paper end
|
||||
// WorldServer.LOGGER.warn("Tried to add entity {} but it was marked as removed already", EntityTypes.getKey(entity.getType())); // CraftBukkit
|
||||
return false;
|
||||
} else {
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
|
||||
public com.destroystokyo.paper.loottable.PaperLootableInventoryData lootableData; // Paper
|
||||
private CraftEntity bukkitEntity;
|
||||
|
||||
+ public @org.jetbrains.annotations.Nullable net.minecraft.server.level.ChunkMap.TrackedEntity tracker; // Paper
|
||||
+ public @Nullable Throwable addedToWorldStack; // Paper - entity debug
|
||||
public CraftEntity getBukkitEntity() {
|
||||
if (this.bukkitEntity == null) {
|
||||
this.bukkitEntity = CraftEntity.getEntity(this.level.getCraftServer(), this);
|
||||
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/Level.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
public boolean pvpMode;
|
||||
public boolean keepSpawnInMemory = true;
|
||||
public org.bukkit.generator.ChunkGenerator generator;
|
||||
+ public static final boolean DEBUG_ENTITIES = Boolean.getBoolean("debug.entities"); // Paper
|
||||
|
||||
public boolean preventPoiUpdated = false; // CraftBukkit - SPIGOT-5710
|
||||
public boolean captureBlockStates = false;
|
||||
diff --git a/src/main/java/net/minecraft/world/level/entity/EntityLookup.java b/src/main/java/net/minecraft/world/level/entity/EntityLookup.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/entity/EntityLookup.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/entity/EntityLookup.java
|
||||
@@ -0,0 +0,0 @@ public class EntityLookup<T extends EntityAccess> {
|
||||
UUID uUID = entity.getUUID();
|
||||
if (this.byUuid.containsKey(uUID)) {
|
||||
LOGGER.warn("Duplicate entity UUID {}: {}", uUID, entity);
|
||||
+ // Paper start - extra debug info
|
||||
+ if (entity instanceof net.minecraft.world.entity.Entity entityCast) {
|
||||
+ if (net.minecraft.server.level.ServerLevel.DEBUG_ENTITIES) {
|
||||
+ entityCast.addedToWorldStack = net.minecraft.server.level.ServerLevel.getAddToWorldStackTrace(entityCast);
|
||||
+ }
|
||||
+
|
||||
+ T old = this.byUuid.get(entity.getUUID());
|
||||
+ if (old instanceof net.minecraft.world.entity.Entity oldCast && old != null && oldCast.getId() != entity.getId() && oldCast.valid) {
|
||||
+ LOGGER.error("Overwrote an existing entity " + oldCast + " with " + entity);
|
||||
+ if (net.minecraft.server.level.ServerLevel.DEBUG_ENTITIES) {
|
||||
+ if (oldCast.addedToWorldStack != null) {
|
||||
+ oldCast.addedToWorldStack.printStackTrace();
|
||||
+ } else {
|
||||
+ LOGGER.error("Oddly, the old entity was not added to the world in the normal way. Plugins?");
|
||||
+ }
|
||||
+ entityCast.addedToWorldStack.printStackTrace();
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
} else {
|
||||
this.byUuid.put(uUID, entity);
|
||||
this.byId.put(entity.getId(), entity);
|
159
patches/server/Add-Early-Warning-Feature-to-WatchDog.patch
Normal file
159
patches/server/Add-Early-Warning-Feature-to-WatchDog.patch
Normal file
|
@ -0,0 +1,159 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: miclebrick <miclebrick@outlook.com>
|
||||
Date: Wed, 8 Aug 2018 15:30:52 -0400
|
||||
Subject: [PATCH] Add Early Warning Feature to WatchDog
|
||||
|
||||
Detect when the server has been hung for a long duration, and start printing
|
||||
thread dumps at an interval until the point of crash.
|
||||
|
||||
This will help diagnose what was going on in that time before the crash.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
this.status = this.buildServerStatus();
|
||||
|
||||
// Spigot start
|
||||
+ org.spigotmc.WatchdogThread.hasStarted = true; // Paper
|
||||
Arrays.fill( recentTps, 20 );
|
||||
long start = System.nanoTime(), curTime, tickSection = start; // Paper - Further improve server tick loop
|
||||
lastTick = start - TICK_TIME; // Paper
|
||||
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
@@ -0,0 +0,0 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
|
||||
// Paper start
|
||||
paperConfigurations.initializeGlobalConfiguration();
|
||||
paperConfigurations.initializeWorldDefaultsConfiguration();
|
||||
+ org.spigotmc.WatchdogThread.doStart(org.spigotmc.SpigotConfig.timeoutTime, org.spigotmc.SpigotConfig.restartOnCrash);
|
||||
io.papermc.paper.command.PaperCommands.registerCommands(this);
|
||||
com.destroystokyo.paper.Metrics.PaperMetrics.startMetrics();
|
||||
com.destroystokyo.paper.VersionHistoryManager.INSTANCE.getClass(); // load version history now
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -0,0 +0,0 @@ public final class CraftServer implements Server {
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
+ org.spigotmc.WatchdogThread.hasStarted = false; // Paper - Disable watchdog early timeout on reload
|
||||
this.reloadCount++;
|
||||
this.configuration = YamlConfiguration.loadConfiguration(this.getConfigFile());
|
||||
this.commandsConfiguration = YamlConfiguration.loadConfiguration(this.getCommandsConfigFile());
|
||||
@@ -0,0 +0,0 @@ public final class CraftServer implements Server {
|
||||
this.enablePlugins(PluginLoadOrder.STARTUP);
|
||||
this.enablePlugins(PluginLoadOrder.POSTWORLD);
|
||||
this.getPluginManager().callEvent(new ServerLoadEvent(ServerLoadEvent.LoadType.RELOAD));
|
||||
+ org.spigotmc.WatchdogThread.hasStarted = true; // Paper - Disable watchdog early timeout on reload
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/spigotmc/SpigotConfig.java
|
||||
+++ b/src/main/java/org/spigotmc/SpigotConfig.java
|
||||
@@ -0,0 +0,0 @@ public class SpigotConfig
|
||||
SpigotConfig.restartScript = SpigotConfig.getString( "settings.restart-script", SpigotConfig.restartScript );
|
||||
SpigotConfig.restartMessage = SpigotConfig.transform( SpigotConfig.getString( "messages.restart", "Server is restarting" ) );
|
||||
SpigotConfig.commands.put( "restart", new RestartCommand( "restart" ) );
|
||||
- WatchdogThread.doStart( timeoutTime, restartOnCrash );
|
||||
+ // WatchdogThread.doStart( timeoutTime, restartOnCrash ); // Paper - moved to after paper config initialization
|
||||
}
|
||||
|
||||
public static boolean bungee;
|
||||
diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/spigotmc/WatchdogThread.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/spigotmc/WatchdogThread.java
|
||||
+++ b/src/main/java/org/spigotmc/WatchdogThread.java
|
||||
@@ -0,0 +0,0 @@ public class WatchdogThread extends Thread
|
||||
private static WatchdogThread instance;
|
||||
private long timeoutTime;
|
||||
private boolean restart;
|
||||
+ private final long earlyWarningEvery; // Paper - Timeout time for just printing a dump but not restarting
|
||||
+ private final long earlyWarningDelay; // Paper
|
||||
+ public static volatile boolean hasStarted; // Paper
|
||||
+ private long lastEarlyWarning; // Paper - Keep track of short dump times to avoid spamming console with short dumps
|
||||
private volatile long lastTick;
|
||||
private volatile boolean stopping;
|
||||
|
||||
@@ -0,0 +0,0 @@ public class WatchdogThread extends Thread
|
||||
super( "Paper Watchdog Thread" );
|
||||
this.timeoutTime = timeoutTime;
|
||||
this.restart = restart;
|
||||
+ earlyWarningEvery = Math.min(io.papermc.paper.configuration.GlobalConfiguration.get().watchdog.earlyWarningEvery, timeoutTime); // Paper
|
||||
+ earlyWarningDelay = Math.min(io.papermc.paper.configuration.GlobalConfiguration.get().watchdog.earlyWarningDelay, timeoutTime); // Paper
|
||||
}
|
||||
|
||||
private static long monotonicMillis()
|
||||
@@ -0,0 +0,0 @@ public class WatchdogThread extends Thread
|
||||
while ( !this.stopping )
|
||||
{
|
||||
//
|
||||
- if ( this.lastTick != 0 && this.timeoutTime > 0 && WatchdogThread.monotonicMillis() > this.lastTick + this.timeoutTime && !Boolean.getBoolean("disable.watchdog")) // Paper - Add property to disable
|
||||
+ // Paper start
|
||||
+ Logger log = Bukkit.getServer().getLogger();
|
||||
+ long currentTime = WatchdogThread.monotonicMillis();
|
||||
+ if ( this.lastTick != 0 && this.timeoutTime > 0 && currentTime > this.lastTick + this.earlyWarningEvery && !Boolean.getBoolean("disable.watchdog")) // Paper - Add property to disable
|
||||
{
|
||||
- Logger log = Bukkit.getServer().getLogger();
|
||||
+ boolean isLongTimeout = currentTime > lastTick + timeoutTime;
|
||||
+ // Don't spam early warning dumps
|
||||
+ if ( !isLongTimeout && (earlyWarningEvery <= 0 || !hasStarted || currentTime < lastEarlyWarning + earlyWarningEvery || currentTime < lastTick + earlyWarningDelay)) continue;
|
||||
+ if ( !isLongTimeout && MinecraftServer.getServer().hasStopped()) continue; // Don't spam early watchdog warnings during shutdown, we'll come back to this...
|
||||
+ lastEarlyWarning = currentTime;
|
||||
+ if (isLongTimeout) {
|
||||
+ // Paper end
|
||||
log.log( Level.SEVERE, "------------------------------" );
|
||||
log.log( Level.SEVERE, "The server has stopped responding! This is (probably) not a Paper bug." ); // Paper
|
||||
log.log( Level.SEVERE, "If you see a plugin in the Server thread dump below, then please report it to that author" );
|
||||
@@ -0,0 +0,0 @@ public class WatchdogThread extends Thread
|
||||
}
|
||||
}
|
||||
// Paper end
|
||||
+ } else
|
||||
+ {
|
||||
+ log.log(Level.SEVERE, "--- DO NOT REPORT THIS TO PAPER - THIS IS NOT A BUG OR A CRASH - " + Bukkit.getServer().getVersion() + " ---");
|
||||
+ log.log(Level.SEVERE, "The server has not responded for " + (currentTime - lastTick) / 1000 + " seconds! Creating thread dump");
|
||||
+ }
|
||||
+ // Paper end - Different message for short timeout
|
||||
log.log( Level.SEVERE, "------------------------------" );
|
||||
log.log( Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Paper!):" ); // Paper
|
||||
WatchdogThread.dumpThread( ManagementFactory.getThreadMXBean().getThreadInfo( MinecraftServer.getServer().serverThread.getId(), Integer.MAX_VALUE ), log );
|
||||
log.log( Level.SEVERE, "------------------------------" );
|
||||
//
|
||||
+ // Paper start - Only print full dump on long timeouts
|
||||
+ if ( isLongTimeout )
|
||||
+ {
|
||||
log.log( Level.SEVERE, "Entire Thread Dump:" );
|
||||
ThreadInfo[] threads = ManagementFactory.getThreadMXBean().dumpAllThreads( true, true );
|
||||
for ( ThreadInfo thread : threads )
|
||||
{
|
||||
WatchdogThread.dumpThread( thread, log );
|
||||
}
|
||||
+ } else {
|
||||
+ log.log(Level.SEVERE, "--- DO NOT REPORT THIS TO PAPER - THIS IS NOT A BUG OR A CRASH ---");
|
||||
+ }
|
||||
+
|
||||
log.log( Level.SEVERE, "------------------------------" );
|
||||
|
||||
+ if ( isLongTimeout )
|
||||
+ {
|
||||
if ( this.restart && !MinecraftServer.getServer().hasStopped() )
|
||||
{
|
||||
RestartCommand.restart();
|
||||
}
|
||||
break;
|
||||
+ } // Paper end
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
- sleep( 10000 );
|
||||
+ sleep( 1000 ); // Paper - Reduce check time to every second instead of every ten seconds, more consistent and allows for short timeout
|
||||
} catch ( InterruptedException ex )
|
||||
{
|
||||
interrupt();
|
60
patches/server/Add-More-Creeper-API.patch
Normal file
60
patches/server/Add-More-Creeper-API.patch
Normal file
|
@ -0,0 +1,60 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Fri, 24 Aug 2018 11:50:26 -0500
|
||||
Subject: [PATCH] Add More Creeper API
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/Creeper.java b/src/main/java/net/minecraft/world/entity/monster/Creeper.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Creeper.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Creeper.java
|
||||
@@ -0,0 +0,0 @@ public class Creeper extends Monster implements PowerableMob {
|
||||
}
|
||||
|
||||
if (nbt.getBoolean("ignited")) {
|
||||
- this.ignite();
|
||||
+ this.entityData.set(Creeper.DATA_IS_IGNITED, true); // Paper - set directly to avoid firing event
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class Creeper extends Monster implements PowerableMob {
|
||||
}
|
||||
|
||||
public void ignite() {
|
||||
- this.entityData.set(Creeper.DATA_IS_IGNITED, true);
|
||||
+ // Paper start
|
||||
+ setIgnited(true);
|
||||
+ }
|
||||
+
|
||||
+ public void setIgnited(boolean ignited) {
|
||||
+ if (isIgnited() != ignited) {
|
||||
+ com.destroystokyo.paper.event.entity.CreeperIgniteEvent event = new com.destroystokyo.paper.event.entity.CreeperIgniteEvent((org.bukkit.entity.Creeper) getBukkitEntity(), ignited);
|
||||
+ if (event.callEvent()) {
|
||||
+ this.entityData.set(Creeper.DATA_IS_IGNITED, event.isIgnited());
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
public boolean canDropMobsSkull() {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftCreeper.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftCreeper.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftCreeper.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftCreeper.java
|
||||
@@ -0,0 +0,0 @@ public class CraftCreeper extends CraftMonster implements Creeper {
|
||||
public EntityType getType() {
|
||||
return EntityType.CREEPER;
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public void setIgnited(boolean ignited) {
|
||||
+ getHandle().setIgnited(ignited);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isIgnited() {
|
||||
+ return getHandle().isIgnited();
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
97
patches/server/Add-PhantomPreSpawnEvent.patch
Normal file
97
patches/server/Add-PhantomPreSpawnEvent.patch
Normal file
|
@ -0,0 +1,97 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Sat, 25 Aug 2018 19:56:51 -0500
|
||||
Subject: [PATCH] Add PhantomPreSpawnEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/Phantom.java b/src/main/java/net/minecraft/world/entity/monster/Phantom.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Phantom.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Phantom.java
|
||||
@@ -0,0 +0,0 @@ public class Phantom extends FlyingMob implements Enemy {
|
||||
}
|
||||
|
||||
this.setPhantomSize(nbt.getInt("Size"));
|
||||
+ // Paper start
|
||||
+ if (nbt.hasUUID("Paper.SpawningEntity")) {
|
||||
+ this.spawningEntity = nbt.getUUID("Paper.SpawningEntity");
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -0,0 +0,0 @@ public class Phantom extends FlyingMob implements Enemy {
|
||||
nbt.putInt("AY", this.anchorPoint.getY());
|
||||
nbt.putInt("AZ", this.anchorPoint.getZ());
|
||||
nbt.putInt("Size", this.getPhantomSize());
|
||||
+ // Paper start
|
||||
+ if (this.spawningEntity != null) {
|
||||
+ nbt.putUUID("Paper.SpawningEntity", this.spawningEntity);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -0,0 +0,0 @@ public class Phantom extends FlyingMob implements Enemy {
|
||||
return (double) this.getEyeHeight();
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ java.util.UUID spawningEntity;
|
||||
+
|
||||
+ public java.util.UUID getSpawningEntity() {
|
||||
+ return spawningEntity;
|
||||
+ }
|
||||
+ public void setSpawningEntity(java.util.UUID entity) { this.spawningEntity = entity; }
|
||||
+ // Paper end
|
||||
private static enum AttackPhase {
|
||||
|
||||
CIRCLE, SWOOP;
|
||||
diff --git a/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java b/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java
|
||||
@@ -0,0 +0,0 @@ package net.minecraft.world.level.levelgen;
|
||||
import java.util.Iterator;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
+import io.papermc.paper.util.MCUtil;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.stats.ServerStatsCounter;
|
||||
@@ -0,0 +0,0 @@ public class PhantomSpawner implements CustomSpawner {
|
||||
int k = 1 + randomsource.nextInt(difficultydamagescaler.getDifficulty().getId() + 1);
|
||||
|
||||
for (int l = 0; l < k; ++l) {
|
||||
+ // Paper start
|
||||
+ com.destroystokyo.paper.event.entity.PhantomPreSpawnEvent event = new com.destroystokyo.paper.event.entity.PhantomPreSpawnEvent(MCUtil.toLocation(world, blockposition1), ((ServerPlayer) entityhuman).getBukkitEntity(), org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NATURAL);
|
||||
+ if (!event.callEvent()) {
|
||||
+ if (event.shouldAbortSpawn()) {
|
||||
+ break;
|
||||
+ }
|
||||
+ continue;
|
||||
+ }
|
||||
+ // Paper end
|
||||
Phantom entityphantom = (Phantom) EntityType.PHANTOM.create(world);
|
||||
|
||||
if (entityphantom != null) {
|
||||
+ entityphantom.setSpawningEntity(entityhuman.getUUID()); // Paper
|
||||
entityphantom.moveTo(blockposition1, 0.0F, 0.0F);
|
||||
groupdataentity = entityphantom.finalizeSpawn(world, difficultydamagescaler, MobSpawnType.NATURAL, groupdataentity, (CompoundTag) null);
|
||||
world.addFreshEntityWithPassengers(entityphantom, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NATURAL); // CraftBukkit
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPhantom.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPhantom.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPhantom.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPhantom.java
|
||||
@@ -0,0 +0,0 @@ public class CraftPhantom extends CraftFlying implements Phantom, CraftEnemy {
|
||||
public EntityType getType() {
|
||||
return EntityType.PHANTOM;
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public java.util.UUID getSpawningEntity() {
|
||||
+ return getHandle().getSpawningEntity();
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
117
patches/server/Add-TNTPrimeEvent.patch
Normal file
117
patches/server/Add-TNTPrimeEvent.patch
Normal file
|
@ -0,0 +1,117 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Vainomaa <mikroskeem@mikroskeem.eu>
|
||||
Date: Mon, 16 Jul 2018 00:05:05 +0300
|
||||
Subject: [PATCH] Add TNTPrimeEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java
|
||||
@@ -0,0 +0,0 @@ public class EnderDragon extends Mob implements Enemy {
|
||||
});
|
||||
craftBlock.getNMS().spawnAfterBreak((ServerLevel) this.level(), blockposition, ItemStack.EMPTY, false);
|
||||
}
|
||||
+ // Paper start - TNTPrimeEvent
|
||||
+ org.bukkit.block.Block tntBlock = level.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ());
|
||||
+ if(!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.EXPLOSION, explosionSource.getIndirectSourceEntity().getBukkitEntity()).callEvent())
|
||||
+ continue;
|
||||
+ // Paper end
|
||||
nmsBlock.wasExploded(this.level(), blockposition, explosionSource);
|
||||
|
||||
this.level().removeBlock(blockposition, false);
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/FireBlock.java b/src/main/java/net/minecraft/world/level/block/FireBlock.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/FireBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/FireBlock.java
|
||||
@@ -0,0 +0,0 @@ public class FireBlock extends BaseFireBlock {
|
||||
|
||||
world.setBlock(blockposition, this.getStateWithAge(world, blockposition, l), 3);
|
||||
} else {
|
||||
- world.removeBlock(blockposition, false);
|
||||
+ if(iblockdata.getBlock() != Blocks.TNT) world.removeBlock(blockposition, false); // Paper - TNTPrimeEvent - We might be cancelling it below, move the setAir down
|
||||
}
|
||||
|
||||
Block block = iblockdata.getBlock();
|
||||
|
||||
if (block instanceof TntBlock) {
|
||||
+ // Paper start - TNTPrimeEvent
|
||||
+ org.bukkit.block.Block tntBlock = io.papermc.paper.util.MCUtil.toBukkitBlock(world, blockposition);
|
||||
+ if (!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.FIRE, null).callEvent()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ world.removeBlock(blockposition, false);
|
||||
+ // Paper end
|
||||
TntBlock.explode(world, blockposition);
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/TntBlock.java b/src/main/java/net/minecraft/world/level/block/TntBlock.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/TntBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/TntBlock.java
|
||||
@@ -0,0 +0,0 @@ public class TntBlock extends Block {
|
||||
public void onPlace(BlockState state, Level world, BlockPos pos, BlockState oldState, boolean notify) {
|
||||
if (!oldState.is(state.getBlock())) {
|
||||
if (world.hasNeighborSignal(pos) && CraftEventFactory.callTNTPrimeEvent(world, pos, PrimeCause.REDSTONE, null, null)) { // CraftBukkit - TNTPrimeEvent
|
||||
+ // Paper start - TNTPrimeEvent
|
||||
+ org.bukkit.block.Block tntBlock = io.papermc.paper.util.MCUtil.toBukkitBlock(world, pos);
|
||||
+ if (!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.REDSTONE, null).callEvent()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end
|
||||
TntBlock.explode(world, pos);
|
||||
world.removeBlock(pos, false);
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class TntBlock extends Block {
|
||||
@Override
|
||||
public void neighborChanged(BlockState state, Level world, BlockPos pos, Block sourceBlock, BlockPos sourcePos, boolean notify) {
|
||||
if (world.hasNeighborSignal(pos) && CraftEventFactory.callTNTPrimeEvent(world, pos, PrimeCause.REDSTONE, null, sourcePos)) { // CraftBukkit - TNTPrimeEvent
|
||||
+ // Paper start - TNTPrimeEvent
|
||||
+ org.bukkit.block.Block tntBlock = io.papermc.paper.util.MCUtil.toBukkitBlock(world, pos);
|
||||
+ if (!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.REDSTONE, null).callEvent()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end
|
||||
TntBlock.explode(world, pos);
|
||||
world.removeBlock(pos, false);
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class TntBlock extends Block {
|
||||
@Override
|
||||
public void wasExploded(Level world, BlockPos pos, Explosion explosion) {
|
||||
if (!world.isClientSide) {
|
||||
+ // Paper start - TNTPrimeEvent
|
||||
+ org.bukkit.block.Block tntBlock = io.papermc.paper.util.MCUtil.toBukkitBlock(world, pos);
|
||||
+ org.bukkit.entity.Entity source = explosion.source != null ? explosion.source.getBukkitEntity() : null;
|
||||
+ if (!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.EXPLOSION, source).callEvent()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end
|
||||
PrimedTnt entitytntprimed = new PrimedTnt(world, (double) pos.getX() + 0.5D, (double) pos.getY(), (double) pos.getZ() + 0.5D, explosion.getIndirectSourceEntity());
|
||||
int i = entitytntprimed.getFuse();
|
||||
|
||||
@@ -0,0 +0,0 @@ public class TntBlock extends Block {
|
||||
return InteractionResult.CONSUME;
|
||||
}
|
||||
// CraftBukkit end
|
||||
+ // Paper start - TNTPrimeEvent
|
||||
+ org.bukkit.block.Block tntBlock = io.papermc.paper.util.MCUtil.toBukkitBlock(world, pos);
|
||||
+ if (!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.ITEM, player.getBukkitEntity()).callEvent()) {
|
||||
+ return InteractionResult.FAIL;
|
||||
+ }
|
||||
+ // Paper end
|
||||
TntBlock.explode(world, pos, player);
|
||||
world.setBlock(pos, Blocks.AIR.defaultBlockState(), 11);
|
||||
Item item = itemstack.getItem();
|
||||
@@ -0,0 +0,0 @@ public class TntBlock extends Block {
|
||||
return;
|
||||
}
|
||||
// CraftBukkit end
|
||||
+ // Paper start - TNTPrimeEvent
|
||||
+ org.bukkit.block.Block tntBlock = io.papermc.paper.util.MCUtil.toBukkitBlock(world, blockposition);
|
||||
+ if (!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.PROJECTILE, projectile.getBukkitEntity()).callEvent()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end
|
||||
TntBlock.explode(world, blockposition, entity instanceof LivingEntity ? (LivingEntity) entity : null);
|
||||
world.removeBlock(blockposition, false);
|
||||
}
|
|
@ -23,7 +23,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
this.player.setShiftKeyDown(true);
|
||||
+
|
||||
+ // Paper start - Hang on!
|
||||
+ if (this.player.level.paperConfig().entities.behavior.parrotsAreUnaffectedByPlayerMovement) {
|
||||
+ if (this.player.level().paperConfig().entities.behavior.parrotsAreUnaffectedByPlayerMovement) {
|
||||
+ this.player.removeEntitiesOnShoulder();
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
|
69
patches/server/Add-ray-tracing-methods-to-LivingEntity.patch
Normal file
69
patches/server/Add-ray-tracing-methods-to-LivingEntity.patch
Normal file
|
@ -0,0 +1,69 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Mon, 3 Sep 2018 18:20:03 -0500
|
||||
Subject: [PATCH] Add ray tracing methods to LivingEntity
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
}
|
||||
|
||||
// Paper start
|
||||
+
|
||||
+ public HitResult getRayTrace(int maxDistance, ClipContext.Fluid fluidCollisionOption) {
|
||||
+ if (maxDistance < 1 || maxDistance > 120) {
|
||||
+ throw new IllegalArgumentException("maxDistance must be between 1-120");
|
||||
+ }
|
||||
+
|
||||
+ Vec3 start = new Vec3(getX(), getY() + getEyeHeight(), getZ());
|
||||
+ org.bukkit.util.Vector dir = getBukkitEntity().getLocation().getDirection().multiply(maxDistance);
|
||||
+ Vec3 end = new Vec3(start.x + dir.getX(), start.y + dir.getY(), start.z + dir.getZ());
|
||||
+ ClipContext raytrace = new ClipContext(start, end, ClipContext.Block.OUTLINE, fluidCollisionOption, this);
|
||||
+
|
||||
+ return level.clip(raytrace);
|
||||
+ }
|
||||
+
|
||||
public int shieldBlockingDelay = level.paperConfig().misc.shieldBlockingDelay;
|
||||
|
||||
public int getShieldBlockingDelay() {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
@@ -0,0 +0,0 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
|
||||
return blocks.get(0);
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public Block getTargetBlock(int maxDistance, com.destroystokyo.paper.block.TargetBlockInfo.FluidMode fluidMode) {
|
||||
+ return this.getTargetBlockExact(maxDistance, fluidMode.bukkit);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public org.bukkit.block.BlockFace getTargetBlockFace(int maxDistance, com.destroystokyo.paper.block.TargetBlockInfo.FluidMode fluidMode) {
|
||||
+ return this.getTargetBlockFace(maxDistance, fluidMode.bukkit);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public org.bukkit.block.BlockFace getTargetBlockFace(int maxDistance, org.bukkit.FluidCollisionMode fluidMode) {
|
||||
+ RayTraceResult result = this.rayTraceBlocks(maxDistance, fluidMode);
|
||||
+ return result != null ? result.getHitBlockFace() : null;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public com.destroystokyo.paper.block.TargetBlockInfo getTargetBlockInfo(int maxDistance, com.destroystokyo.paper.block.TargetBlockInfo.FluidMode fluidMode) {
|
||||
+ RayTraceResult result = this.rayTraceBlocks(maxDistance, fluidMode.bukkit);
|
||||
+ if (result != null && result.getHitBlock() != null && result.getHitBlockFace() != null) {
|
||||
+ return new com.destroystokyo.paper.block.TargetBlockInfo(result.getHitBlock(), result.getHitBlockFace());
|
||||
+ }
|
||||
+ return null;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public List<Block> getLastTwoTargetBlocks(Set<Material> transparent, int maxDistance) {
|
||||
return this.getLineOfSight(transparent, maxDistance, 2);
|
31
patches/server/Allow-chests-to-be-placed-with-NBT-data.patch
Normal file
31
patches/server/Allow-chests-to-be-placed-with-NBT-data.patch
Normal file
|
@ -0,0 +1,31 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Sat, 8 Sep 2018 18:43:31 -0500
|
||||
Subject: [PATCH] Allow chests to be placed with NBT data
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
@@ -0,0 +0,0 @@ public final class ItemStack {
|
||||
enuminteractionresult = InteractionResult.FAIL; // cancel placement
|
||||
// PAIL: Remove this when MC-99075 fixed
|
||||
placeEvent.getPlayer().updateInventory();
|
||||
+ world.capturedTileEntities.clear(); // Paper - clear out tile entities as chests and such will pop loot
|
||||
// revert back all captured blocks
|
||||
world.preventPoiUpdated = true; // CraftBukkit - SPIGOT-5710
|
||||
for (BlockState blockstate : blocks) {
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/ChestBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/ChestBlockEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/ChestBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/ChestBlockEntity.java
|
||||
@@ -0,0 +0,0 @@ public class ChestBlockEntity extends RandomizableContainerBlockEntity implement
|
||||
// CraftBukkit start
|
||||
@Override
|
||||
public boolean onlyOpCanSetNbt() {
|
||||
- return true;
|
||||
+ return false; // Paper
|
||||
}
|
||||
// CraftBukkit end
|
||||
}
|
145
patches/server/Allow-disabling-armour-stand-ticking.patch
Normal file
145
patches/server/Allow-disabling-armour-stand-ticking.patch
Normal file
|
@ -0,0 +1,145 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Riley Park <rileysebastianpark@gmail.com>
|
||||
Date: Wed, 15 Aug 2018 01:26:09 -0700
|
||||
Subject: [PATCH] Allow disabling armour stand ticking
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
@@ -0,0 +0,0 @@ public class ArmorStand extends LivingEntity {
|
||||
public Rotations leftLegPose;
|
||||
public Rotations rightLegPose;
|
||||
public boolean canMove = true; // Paper
|
||||
+ // Paper start - Allow ArmorStands not to tick
|
||||
+ public boolean canTick = true;
|
||||
+ public boolean canTickSetByAPI = false;
|
||||
+ private boolean noTickPoseDirty = false;
|
||||
+ private boolean noTickEquipmentDirty = false;
|
||||
+ // Paper end
|
||||
|
||||
public ArmorStand(EntityType<? extends ArmorStand> type, Level world) {
|
||||
super(type, world);
|
||||
+ if (world != null) this.canTick = world.paperConfig().entities.armorStands.tick; // Paper - armour stand ticking
|
||||
this.handItems = NonNullList.withSize(2, ItemStack.EMPTY);
|
||||
this.armorItems = NonNullList.withSize(4, ItemStack.EMPTY);
|
||||
this.headPose = ArmorStand.DEFAULT_HEAD_POSE;
|
||||
@@ -0,0 +0,0 @@ public class ArmorStand extends LivingEntity {
|
||||
this.onEquipItem(enumitemslot, (ItemStack) this.armorItems.set(enumitemslot.getIndex(), itemstack), itemstack, silent); // CraftBukkit
|
||||
}
|
||||
|
||||
+ this.noTickEquipmentDirty = true; // Paper - Allow equipment to be updated even when tick disabled
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -0,0 +0,0 @@ public class ArmorStand extends LivingEntity {
|
||||
}
|
||||
|
||||
nbt.put("Pose", this.writePose());
|
||||
+ if (this.canTickSetByAPI) nbt.putBoolean("Paper.CanTickOverride", this.canTick); // Paper - persist no tick setting
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -0,0 +0,0 @@ public class ArmorStand extends LivingEntity {
|
||||
this.setNoBasePlate(nbt.getBoolean("NoBasePlate"));
|
||||
this.setMarker(nbt.getBoolean("Marker"));
|
||||
this.noPhysics = !this.hasPhysics();
|
||||
+ // Paper start - persist no tick
|
||||
+ if (nbt.contains("Paper.CanTickOverride")) {
|
||||
+ this.canTick = nbt.getBoolean("Paper.CanTickOverride");
|
||||
+ this.canTickSetByAPI = true;
|
||||
+ }
|
||||
+ // Paper end
|
||||
CompoundTag nbttagcompound1 = nbt.getCompound("Pose");
|
||||
|
||||
this.readPose(nbttagcompound1);
|
||||
@@ -0,0 +0,0 @@ public class ArmorStand extends LivingEntity {
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
+ // Paper start
|
||||
+ if (!this.canTick) {
|
||||
+ if (this.noTickPoseDirty) {
|
||||
+ this.noTickPoseDirty = false;
|
||||
+ this.updatePose();
|
||||
+ }
|
||||
+
|
||||
+ if (this.noTickEquipmentDirty) {
|
||||
+ this.noTickEquipmentDirty = false;
|
||||
+ this.detectEquipmentUpdates();
|
||||
+ }
|
||||
+
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
super.tick();
|
||||
+ // Paper start - Split into separate method
|
||||
+ updatePose();
|
||||
+ }
|
||||
+
|
||||
+ public void updatePose() {
|
||||
+ // Paper end
|
||||
Rotations vector3f = (Rotations) this.entityData.get(ArmorStand.DATA_HEAD_POSE);
|
||||
|
||||
if (!this.headPose.equals(vector3f)) {
|
||||
@@ -0,0 +0,0 @@ public class ArmorStand extends LivingEntity {
|
||||
public void setHeadPose(Rotations angle) {
|
||||
this.headPose = angle;
|
||||
this.entityData.set(ArmorStand.DATA_HEAD_POSE, angle);
|
||||
+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking
|
||||
}
|
||||
|
||||
public void setBodyPose(Rotations angle) {
|
||||
this.bodyPose = angle;
|
||||
this.entityData.set(ArmorStand.DATA_BODY_POSE, angle);
|
||||
+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking
|
||||
}
|
||||
|
||||
public void setLeftArmPose(Rotations angle) {
|
||||
this.leftArmPose = angle;
|
||||
this.entityData.set(ArmorStand.DATA_LEFT_ARM_POSE, angle);
|
||||
+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking
|
||||
}
|
||||
|
||||
public void setRightArmPose(Rotations angle) {
|
||||
this.rightArmPose = angle;
|
||||
this.entityData.set(ArmorStand.DATA_RIGHT_ARM_POSE, angle);
|
||||
+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking
|
||||
}
|
||||
|
||||
public void setLeftLegPose(Rotations angle) {
|
||||
this.leftLegPose = angle;
|
||||
this.entityData.set(ArmorStand.DATA_LEFT_LEG_POSE, angle);
|
||||
+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking
|
||||
}
|
||||
|
||||
public void setRightLegPose(Rotations angle) {
|
||||
this.rightLegPose = angle;
|
||||
this.entityData.set(ArmorStand.DATA_RIGHT_LEG_POSE, angle);
|
||||
+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking
|
||||
}
|
||||
|
||||
public Rotations getHeadPose() {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java
|
||||
@@ -0,0 +0,0 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand {
|
||||
public void setCanMove(boolean move) {
|
||||
getHandle().canMove = move;
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean canTick() {
|
||||
+ return this.getHandle().canTick;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setCanTick(final boolean tick) {
|
||||
+ this.getHandle().canTick = tick;
|
||||
+ this.getHandle().canTickSetByAPI = true;
|
||||
+ }
|
||||
// Paper end
|
||||
}
|
27
patches/server/AnvilDamageEvent.patch
Normal file
27
patches/server/AnvilDamageEvent.patch
Normal file
|
@ -0,0 +1,27 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Fri, 20 Jul 2018 23:37:03 -0500
|
||||
Subject: [PATCH] AnvilDamageEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/inventory/AnvilMenu.java b/src/main/java/net/minecraft/world/inventory/AnvilMenu.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/inventory/AnvilMenu.java
|
||||
+++ b/src/main/java/net/minecraft/world/inventory/AnvilMenu.java
|
||||
@@ -0,0 +0,0 @@ public class AnvilMenu extends ItemCombinerMenu {
|
||||
if (!player.getAbilities().instabuild && iblockdata.is(BlockTags.ANVIL) && player.getRandom().nextFloat() < 0.12F) {
|
||||
BlockState iblockdata1 = AnvilBlock.damage(iblockdata);
|
||||
|
||||
+ // Paper start
|
||||
+ com.destroystokyo.paper.event.block.AnvilDamagedEvent event = new com.destroystokyo.paper.event.block.AnvilDamagedEvent(getBukkitView(), iblockdata1 != null ? org.bukkit.craftbukkit.block.data.CraftBlockData.fromData(iblockdata1) : null);
|
||||
+ if (!event.callEvent()) {
|
||||
+ return;
|
||||
+ } else if (event.getDamageState() == com.destroystokyo.paper.event.block.AnvilDamagedEvent.DamageState.BROKEN) {
|
||||
+ iblockdata1 = null;
|
||||
+ } else {
|
||||
+ iblockdata1 = ((org.bukkit.craftbukkit.block.data.CraftBlockData) event.getDamageState().getMaterial().createBlockData()).getState().setValue(AnvilBlock.FACING, iblockdata.getValue(AnvilBlock.FACING));
|
||||
+ }
|
||||
+ // Paper end
|
||||
if (iblockdata1 == null) {
|
||||
world.removeBlock(blockposition, false);
|
||||
world.levelEvent(1029, blockposition, 0);
|
|
@ -0,0 +1,52 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shane Freeder <theboyetronic@gmail.com>
|
||||
Date: Sun, 29 Jul 2018 05:02:15 +0100
|
||||
Subject: [PATCH] Break up and make tab spam limits configurable
|
||||
|
||||
Due to the changes in 1.13, clients will send a tab completion request
|
||||
for all bukkit commands in order to factor in the lack of support for
|
||||
brigadier and provide backwards support in the API.
|
||||
|
||||
Craftbukkit, however; has moved the chat spam limiter to also interact
|
||||
with the tab completion request, which while good for avoiding abuse,
|
||||
causes 1.13 clients to easilly be kicked from a server in bukkit due
|
||||
to this. Removing the spam limit could cause issues for servers, however,
|
||||
there is no way for servers to manipulate this without blindly cancelling
|
||||
kick events, which only causes additional complications. This also causes
|
||||
issues in that the tab spam limit and chat share the same field but different
|
||||
limits, meaning that a player having typed a long command may be kicked from
|
||||
the server.
|
||||
|
||||
Splitting the field up and making it configurable allows for server owners
|
||||
to take the burden of this into their own hand without having to rely on
|
||||
plugins doing unsafe things.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
|
||||
private long keepAliveChallenge;
|
||||
// CraftBukkit start - multithreaded fields
|
||||
private final AtomicInteger chatSpamTickCount = new AtomicInteger();
|
||||
+ private final java.util.concurrent.atomic.AtomicInteger tabSpamLimiter = new java.util.concurrent.atomic.AtomicInteger(); // Paper - configurable tab spam limits
|
||||
// CraftBukkit end
|
||||
private int dropSpamTickCount;
|
||||
private double firstGoodX;
|
||||
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
|
||||
this.server.getProfiler().pop();
|
||||
// CraftBukkit start
|
||||
for (int spam; (spam = this.chatSpamTickCount.get()) > 0 && !this.chatSpamTickCount.compareAndSet(spam, spam - 1); ) ;
|
||||
+ if (tabSpamLimiter.get() > 0) tabSpamLimiter.getAndDecrement(); // Paper - split to seperate variable
|
||||
/* Use thread-safe field access instead
|
||||
if (this.chatSpamTickCount > 0) {
|
||||
--this.chatSpamTickCount;
|
||||
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
|
||||
public void handleCustomCommandSuggestions(ServerboundCommandSuggestionPacket packet) {
|
||||
// PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); // Paper - run this async
|
||||
// CraftBukkit start
|
||||
- if (this.chatSpamTickCount.addAndGet(1) > 500 && !this.server.getPlayerList().isOp(this.player.getGameProfile())) {
|
||||
+ if (this.chatSpamTickCount.addAndGet(io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.tabSpamIncrement) > io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.tabSpamLimit && !this.server.getPlayerList().isOp(this.player.getGameProfile())) { // Paper start - split and make configurable
|
||||
server.scheduleOnMain(() -> this.disconnect(Component.translatable("disconnect.spam", new Object[0]))); // Paper
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Byteflux <byte@byteflux.net>
|
||||
Date: Wed, 8 Aug 2018 16:33:21 -0600
|
||||
Subject: [PATCH] Configurable speed for water flowing over lava
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/LiquidBlock.java b/src/main/java/net/minecraft/world/level/block/LiquidBlock.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/LiquidBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/LiquidBlock.java
|
||||
@@ -0,0 +0,0 @@ public class LiquidBlock extends Block implements BucketPickup {
|
||||
@Override
|
||||
public void onPlace(BlockState state, Level world, BlockPos pos, BlockState oldState, boolean notify) {
|
||||
if (this.shouldSpreadLiquid(world, pos, state)) {
|
||||
- world.scheduleTick(pos, state.getFluidState().getType(), this.fluid.getTickDelay(world));
|
||||
+ world.scheduleTick(pos, state.getFluidState().getType(), this.getFlowSpeed(world, pos)); // Paper
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+ // Paper start - Get flow speed. Throttle if its water and flowing adjacent to lava
|
||||
+ public int getFlowSpeed(Level world, BlockPos blockposition) {
|
||||
+ if (this.material == net.minecraft.world.level.material.Material.WATER) {
|
||||
+ if (
|
||||
+ world.getMaterialIfLoaded(blockposition.north(1)) == net.minecraft.world.level.material.Material.LAVA ||
|
||||
+ world.getMaterialIfLoaded(blockposition.south(1)) == net.minecraft.world.level.material.Material.LAVA ||
|
||||
+ world.getMaterialIfLoaded(blockposition.west(1)) == net.minecraft.world.level.material.Material.LAVA ||
|
||||
+ world.getMaterialIfLoaded(blockposition.east(1)) == net.minecraft.world.level.material.Material.LAVA
|
||||
+ ) {
|
||||
+ return world.paperConfig().environment.waterOverLavaFlowSpeed;
|
||||
+ }
|
||||
+ }
|
||||
+ return this.fluid.getTickDelay(world);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) {
|
||||
if (state.getFluidState().isSource() || neighborState.getFluidState().isSource()) {
|
||||
@@ -0,0 +0,0 @@ public class LiquidBlock extends Block implements BucketPickup {
|
||||
@Override
|
||||
public void neighborChanged(BlockState state, Level world, BlockPos pos, Block sourceBlock, BlockPos sourcePos, boolean notify) {
|
||||
if (this.shouldSpreadLiquid(world, pos, state)) {
|
||||
- world.scheduleTick(pos, state.getFluidState().getType(), this.fluid.getTickDelay(world));
|
||||
+ world.scheduleTick(pos, state.getFluidState().getType(), this.getFlowSpeed(world, pos)); // Paper
|
||||
}
|
||||
|
||||
}
|
|
@ -15,7 +15,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
this.setDeltaMovement(this.getDeltaMovement().multiply(0.6D, 1.0D, 0.6D));
|
||||
- this.setSprinting(false);
|
||||
+ // Paper start - Configuration option to disable automatic sprint interruption
|
||||
+ if (!level.paperConfig().misc.disableSprintInterruptionOnAttack) {
|
||||
+ if (!this.level().paperConfig().misc.disableSprintInterruptionOnAttack) {
|
||||
+ this.setSprinting(false);
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
|
64
patches/server/Don-t-call-getItemMeta-on-hasItemMeta.patch
Normal file
64
patches/server/Don-t-call-getItemMeta-on-hasItemMeta.patch
Normal file
|
@ -0,0 +1,64 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Hugo Manrique <hugmanrique@gmail.com>
|
||||
Date: Thu, 26 Jul 2018 14:10:23 +0200
|
||||
Subject: [PATCH] Don't call getItemMeta on hasItemMeta
|
||||
|
||||
Spigot 1.13 checks if any field (which are manually copied from the ItemStack's "tag" NBT tag) on the ItemMeta class of an ItemStack is set.
|
||||
|
||||
We could just check if the "tag" NBT tag is empty, albeit that would break some plugins. The only general tag added on 1.13 is "Damage", and we can just check if the "tag" NBT tag contains any other tag that's not "Damage" (https://minecraft.gamepedia.com/Player.dat_format#Item_structure) making the `hasItemStack` method behave as before.
|
||||
|
||||
Returns true if getDamage() == 0 or has damage tag or other tag is set.
|
||||
Check the `ItemMetaTest#testTaggedButNotMeta` method to see how this method behaves.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
@@ -0,0 +0,0 @@ public final class CraftItemStack extends ItemStack {
|
||||
|
||||
@Override
|
||||
public boolean hasItemMeta() {
|
||||
- return CraftItemStack.hasItemMeta(this.handle) && !CraftItemFactory.instance().equals(this.getItemMeta(), null);
|
||||
+ return CraftItemStack.hasItemMeta(this.handle) && (this.handle.getDamageValue() != 0 || (this.handle.getTag() != null && this.handle.getTag().tags.size() >= (this.handle.getTag().contains(CraftMetaItem.DAMAGE.NBT) ? 2 : 1))); // Paper - keep 1.12 CraftBukkit behavior without calling getItemMeta
|
||||
}
|
||||
|
||||
static boolean hasItemMeta(net.minecraft.world.item.ItemStack item) {
|
||||
diff --git a/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaTest.java b/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaTest.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaTest.java
|
||||
+++ b/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaTest.java
|
||||
@@ -0,0 +0,0 @@ public class ItemMetaTest extends AbstractTestingBase {
|
||||
assertThat(itemMeta.hasConflictingEnchant(null), is(false));
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ private void testItemMeta(ItemStack stack) {
|
||||
+ assertThat("Should not have ItemMeta", stack.hasItemMeta(), is(false));
|
||||
+
|
||||
+ stack.setDurability((short) 0);
|
||||
+ assertThat("ItemStack with zero durability should not have ItemMeta", stack.hasItemMeta(), is(false));
|
||||
+
|
||||
+ stack.setDurability((short) 2);
|
||||
+ assertThat("ItemStack with non-zero durability should have ItemMeta", stack.hasItemMeta(), is(true));
|
||||
+
|
||||
+ stack.setLore(java.util.Collections.singletonList("Lore"));
|
||||
+ assertThat("ItemStack with lore and durability should have ItemMeta", stack.hasItemMeta(), is(true));
|
||||
+
|
||||
+ stack.setDurability((short) 0);
|
||||
+ assertThat("ItemStack with lore should have ItemMeta", stack.hasItemMeta(), is(true));
|
||||
+
|
||||
+ stack.setLore(null);
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testHasItemMeta() {
|
||||
+ ItemStack itemStack = new ItemStack(Material.SHEARS);
|
||||
+
|
||||
+ testItemMeta(itemStack);
|
||||
+ testItemMeta(CraftItemStack.asCraftCopy(itemStack));
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Test
|
||||
public void testConflictingStoredEnchantment() {
|
||||
EnchantmentStorageMeta itemMeta = (EnchantmentStorageMeta) Bukkit.getItemFactory().getItemMeta(Material.ENCHANTED_BOOK);
|
53
patches/server/EnderDragon-Events.patch
Normal file
53
patches/server/EnderDragon-Events.patch
Normal file
|
@ -0,0 +1,53 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Sat, 21 Jul 2018 01:51:27 -0500
|
||||
Subject: [PATCH] EnderDragon Events
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonSittingFlamingPhase.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonSittingFlamingPhase.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonSittingFlamingPhase.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonSittingFlamingPhase.java
|
||||
@@ -0,0 +0,0 @@ public class DragonSittingFlamingPhase extends AbstractDragonSittingPhase {
|
||||
this.flame.setDuration(200);
|
||||
this.flame.setParticle(ParticleTypes.DRAGON_BREATH);
|
||||
this.flame.addEffect(new MobEffectInstance(MobEffects.HARM));
|
||||
+ if (new com.destroystokyo.paper.event.entity.EnderDragonFlameEvent((org.bukkit.entity.EnderDragon) this.dragon.getBukkitEntity(), (org.bukkit.entity.AreaEffectCloud) this.flame.getBukkitEntity()).callEvent()) { // Paper
|
||||
this.dragon.level().addFreshEntity(this.flame);
|
||||
+ // Paper start
|
||||
+ } else {
|
||||
+ this.end();
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonStrafePlayerPhase.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonStrafePlayerPhase.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonStrafePlayerPhase.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonStrafePlayerPhase.java
|
||||
@@ -0,0 +0,0 @@ public class DragonStrafePlayerPhase extends AbstractDragonPhaseInstance {
|
||||
|
||||
DragonFireball dragonFireball = new DragonFireball(this.dragon.level(), this.dragon, r, s, t);
|
||||
dragonFireball.moveTo(o, p, q, 0.0F, 0.0F);
|
||||
+ if (new com.destroystokyo.paper.event.entity.EnderDragonShootFireballEvent((org.bukkit.entity.EnderDragon) dragon.getBukkitEntity(), (org.bukkit.entity.DragonFireball) dragonFireball.getBukkitEntity()).callEvent()) // Paper
|
||||
this.dragon.level().addFreshEntity(dragonFireball);
|
||||
+ else dragonFireball.discard(); // Paper
|
||||
this.fireballCharge = 0;
|
||||
if (this.currentPath != null) {
|
||||
while(!this.currentPath.isDone()) {
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/projectile/DragonFireball.java b/src/main/java/net/minecraft/world/entity/projectile/DragonFireball.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/DragonFireball.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/DragonFireball.java
|
||||
@@ -0,0 +0,0 @@ public class DragonFireball extends AbstractHurtingProjectile {
|
||||
}
|
||||
}
|
||||
|
||||
+ if (new com.destroystokyo.paper.event.entity.EnderDragonFireballHitEvent((org.bukkit.entity.DragonFireball) this.getBukkitEntity(), list.stream().map(LivingEntity::getBukkitLivingEntity).collect(java.util.stream.Collectors.toList()), (org.bukkit.entity.AreaEffectCloud) areaEffectCloud.getBukkitEntity()).callEvent()) { // Paper
|
||||
this.level().levelEvent(2006, this.blockPosition(), this.isSilent() ? -1 : 1);
|
||||
this.level().addFreshEntity(areaEffectCloud);
|
||||
+ } else areaEffectCloud.discard(); // Paper
|
||||
this.discard();
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Tue, 4 Sep 2018 15:02:00 -0500
|
||||
Subject: [PATCH] Expose attack cooldown methods for Player
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
|
||||
return this.adventure$pointers;
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public float getCooldownPeriod() {
|
||||
+ return getHandle().getCurrentItemAttackStrengthDelay();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public float getCooledAttackStrength(float adjustTicks) {
|
||||
+ return getHandle().getAttackStrengthScale(adjustTicks);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void resetCooldown() {
|
||||
+ getHandle().resetAttackStrengthTicker();
|
||||
+ }
|
||||
// Paper end
|
||||
// Spigot start
|
||||
private final Player.Spigot spigot = new Player.Spigot()
|
44
patches/server/Fix-NBT-type-issues.patch
Normal file
44
patches/server/Fix-NBT-type-issues.patch
Normal file
|
@ -0,0 +1,44 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Fri, 3 Aug 2018 00:04:54 -0400
|
||||
Subject: [PATCH] Fix NBT type issues
|
||||
|
||||
Addresses two issues:
|
||||
- MC-135506: Experience should save as Integers
|
||||
- Allay duplication cooldown is saved and exposed as a long, but loaded as an int
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/ExperienceOrb.java b/src/main/java/net/minecraft/world/entity/ExperienceOrb.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ExperienceOrb.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ExperienceOrb.java
|
||||
@@ -0,0 +0,0 @@ public class ExperienceOrb extends Entity {
|
||||
public void addAdditionalSaveData(CompoundTag nbt) {
|
||||
nbt.putShort("Health", (short) this.health);
|
||||
nbt.putShort("Age", (short) this.age);
|
||||
- nbt.putShort("Value", (short) this.value);
|
||||
+ nbt.putInt("Value", this.value); // Paper - save as Integer
|
||||
nbt.putInt("Count", this.count);
|
||||
this.savePaperNBT(nbt); // Paper
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class ExperienceOrb extends Entity {
|
||||
public void readAdditionalSaveData(CompoundTag nbt) {
|
||||
this.health = nbt.getShort("Health");
|
||||
this.age = nbt.getShort("Age");
|
||||
- this.value = nbt.getShort("Value");
|
||||
+ this.value = nbt.getInt("Value"); // Paper - load as Integer
|
||||
this.count = Math.max(nbt.getInt("Count"), 1);
|
||||
this.loadPaperNBT(nbt); // Paper
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/allay/Allay.java b/src/main/java/net/minecraft/world/entity/animal/allay/Allay.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/allay/Allay.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/allay/Allay.java
|
||||
@@ -0,0 +0,0 @@ public class Allay extends PathfinderMob implements InventoryCarrier, VibrationS
|
||||
});
|
||||
}
|
||||
|
||||
- this.duplicationCooldown = (long) nbt.getInt("DuplicationCooldown");
|
||||
+ this.duplicationCooldown = nbt.getLong("DuplicationCooldown"); // Paper - Load as long
|
||||
this.entityData.set(Allay.DATA_CAN_DUPLICATE, nbt.getBoolean("CanDuplicate"));
|
||||
}
|
||||
|
167
patches/server/Implement-Expanded-ArmorStand-API.patch
Normal file
167
patches/server/Implement-Expanded-ArmorStand-API.patch
Normal file
|
@ -0,0 +1,167 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: willies952002 <admin@domnian.com>
|
||||
Date: Thu, 26 Jul 2018 02:25:46 -0400
|
||||
Subject: [PATCH] Implement Expanded ArmorStand API
|
||||
|
||||
Adds the following:
|
||||
- Add proper methods for getting and setting items in both hands. Deprecates old methods
|
||||
- Enable/Disable slot interactions
|
||||
- Allow using degrees for ArmorStand rotations (via new Rotations class)
|
||||
|
||||
== AT ==
|
||||
public net.minecraft.world.entity.decoration.ArmorStand isDisabled(Lnet/minecraft/world/entity/EquipmentSlot;)Z
|
||||
|
||||
Co-authored-by: SoSeDiK <mrsosedik@gmail.com>
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java
|
||||
@@ -0,0 +0,0 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand {
|
||||
getHandle().canMove = move;
|
||||
}
|
||||
|
||||
+ @Override
|
||||
+ public ItemStack getItem(org.bukkit.inventory.EquipmentSlot slot) {
|
||||
+ com.google.common.base.Preconditions.checkNotNull(slot, "slot");
|
||||
+ return getHandle().getItemBySlot(org.bukkit.craftbukkit.CraftEquipmentSlot.getNMS(slot)).asBukkitMirror();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setItem(org.bukkit.inventory.EquipmentSlot slot, ItemStack item) {
|
||||
+ com.google.common.base.Preconditions.checkNotNull(slot, "slot");
|
||||
+ switch (slot) {
|
||||
+ case HAND:
|
||||
+ getEquipment().setItemInMainHand(item);
|
||||
+ return;
|
||||
+ case OFF_HAND:
|
||||
+ getEquipment().setItemInOffHand(item);
|
||||
+ return;
|
||||
+ case FEET:
|
||||
+ setBoots(item);
|
||||
+ return;
|
||||
+ case LEGS:
|
||||
+ setLeggings(item);
|
||||
+ return;
|
||||
+ case CHEST:
|
||||
+ setChestplate(item);
|
||||
+ return;
|
||||
+ case HEAD:
|
||||
+ setHelmet(item);
|
||||
+ return;
|
||||
+ }
|
||||
+ throw new UnsupportedOperationException(slot.name());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public java.util.Set<org.bukkit.inventory.EquipmentSlot> getDisabledSlots() {
|
||||
+ java.util.Set<org.bukkit.inventory.EquipmentSlot> disabled = new java.util.HashSet<>();
|
||||
+ for (org.bukkit.inventory.EquipmentSlot slot : org.bukkit.inventory.EquipmentSlot.values()) {
|
||||
+ if (this.isSlotDisabled(slot)) {
|
||||
+ disabled.add(slot);
|
||||
+ }
|
||||
+ }
|
||||
+ return disabled;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setDisabledSlots(org.bukkit.inventory.EquipmentSlot... slots) {
|
||||
+ int disabled = 0;
|
||||
+ for (org.bukkit.inventory.EquipmentSlot slot : slots) {
|
||||
+ if (slot == org.bukkit.inventory.EquipmentSlot.OFF_HAND) continue;
|
||||
+ net.minecraft.world.entity.EquipmentSlot nmsSlot = org.bukkit.craftbukkit.CraftEquipmentSlot.getNMS(slot);
|
||||
+ disabled += (1 << nmsSlot.getFilterFlag()) + (1 << (nmsSlot.getFilterFlag() + 8)) + (1 << (nmsSlot.getFilterFlag() + 16));
|
||||
+ }
|
||||
+ getHandle().disabledSlots = disabled;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void addDisabledSlots(org.bukkit.inventory.EquipmentSlot... slots) {
|
||||
+ java.util.Set<org.bukkit.inventory.EquipmentSlot> disabled = getDisabledSlots();
|
||||
+ java.util.Collections.addAll(disabled, slots);
|
||||
+ setDisabledSlots(disabled.toArray(new org.bukkit.inventory.EquipmentSlot[0]));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void removeDisabledSlots(org.bukkit.inventory.EquipmentSlot... slots) {
|
||||
+ java.util.Set<org.bukkit.inventory.EquipmentSlot> disabled = getDisabledSlots();
|
||||
+ for (final org.bukkit.inventory.EquipmentSlot slot : slots) disabled.remove(slot);
|
||||
+ setDisabledSlots(disabled.toArray(new org.bukkit.inventory.EquipmentSlot[0]));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isSlotDisabled(org.bukkit.inventory.EquipmentSlot slot) {
|
||||
+ return getHandle().isDisabled(org.bukkit.craftbukkit.CraftEquipmentSlot.getNMS(slot));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public io.papermc.paper.math.Rotations getBodyRotations() {
|
||||
+ return fromNMSRotations(getHandle().bodyPose);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setBodyRotations(io.papermc.paper.math.Rotations rotations) {
|
||||
+ getHandle().setBodyPose(toNMSRotations(rotations));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public io.papermc.paper.math.Rotations getLeftArmRotations() {
|
||||
+ return fromNMSRotations(getHandle().leftArmPose);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setLeftArmRotations(io.papermc.paper.math.Rotations rotations) {
|
||||
+ getHandle().setLeftArmPose(toNMSRotations(rotations));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public io.papermc.paper.math.Rotations getRightArmRotations() {
|
||||
+ return fromNMSRotations(getHandle().rightArmPose);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setRightArmRotations(io.papermc.paper.math.Rotations rotations) {
|
||||
+ getHandle().setRightArmPose(toNMSRotations(rotations));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public io.papermc.paper.math.Rotations getLeftLegRotations() {
|
||||
+ return fromNMSRotations(getHandle().leftLegPose);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setLeftLegRotations(io.papermc.paper.math.Rotations rotations) {
|
||||
+ getHandle().setLeftLegPose(toNMSRotations(rotations));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public io.papermc.paper.math.Rotations getRightLegRotations() {
|
||||
+ return fromNMSRotations(getHandle().rightLegPose);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setRightLegRotations(io.papermc.paper.math.Rotations rotations) {
|
||||
+ getHandle().setRightLegPose(toNMSRotations(rotations));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public io.papermc.paper.math.Rotations getHeadRotations() {
|
||||
+ return fromNMSRotations(getHandle().headPose);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setHeadRotations(io.papermc.paper.math.Rotations rotations) {
|
||||
+ getHandle().setHeadPose(toNMSRotations(rotations));
|
||||
+ }
|
||||
+
|
||||
+ private static io.papermc.paper.math.Rotations fromNMSRotations(Rotations old) {
|
||||
+ return io.papermc.paper.math.Rotations.ofDegrees(old.getX(), old.getY(), old.getZ());
|
||||
+ }
|
||||
+
|
||||
+ private static Rotations toNMSRotations(io.papermc.paper.math.Rotations old) {
|
||||
+ return new Rotations((float) old.x(), (float) old.y(), (float) old.z());
|
||||
+ }
|
||||
+
|
||||
@Override
|
||||
public boolean canTick() {
|
||||
return this.getHandle().canTick;
|
63
patches/server/Improve-BlockPosition-inlining.patch
Normal file
63
patches/server/Improve-BlockPosition-inlining.patch
Normal file
|
@ -0,0 +1,63 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Techcable <Techcable@outlook.com>
|
||||
Date: Wed, 30 Nov 2016 20:56:58 -0600
|
||||
Subject: [PATCH] Improve BlockPosition inlining
|
||||
|
||||
Normally the JVM can inline virtual getters by having two sets of code, one is the 'optimized' code and the other is the 'deoptimized' code.
|
||||
If a single type is used 99% of the time, then its worth it to inline, and to revert to 'deoptimized' the 1% of the time we encounter other types.
|
||||
But if two types are encountered commonly, then the JVM can't inline them both, and the call overhead remains.
|
||||
|
||||
This scenario also occurs with BlockPos and MutableBlockPos.
|
||||
The variables in BlockPos are final, so MutableBlockPos can't modify them.
|
||||
MutableBlockPos fixes this by adding custom mutable variables, and overriding the getters to access them.
|
||||
|
||||
This approach with utility methods that operate on MutableBlockPos and BlockPos.
|
||||
Specific examples are BlockPosition.up(), and World.isValidLocation().
|
||||
It makes these simple methods much slower than they need to be.
|
||||
|
||||
This should result in an across the board speedup in anything that accesses blocks or does logic with positions.
|
||||
|
||||
This is based upon conclusions drawn from inspecting the assenmbly generated bythe JIT compiler on my microbenchmarks.
|
||||
They had 'callq' (invoke) instead of 'mov' (get from memory) instructions.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/core/Vec3i.java b/src/main/java/net/minecraft/core/Vec3i.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/core/Vec3i.java
|
||||
+++ b/src/main/java/net/minecraft/core/Vec3i.java
|
||||
@@ -0,0 +0,0 @@ public class Vec3i implements Comparable<Vec3i> {
|
||||
}
|
||||
|
||||
@Override
|
||||
- public boolean equals(Object object) {
|
||||
+ public final boolean equals(Object object) { // Paper
|
||||
if (this == object) {
|
||||
return true;
|
||||
} else if (!(object instanceof Vec3i)) {
|
||||
@@ -0,0 +0,0 @@ public class Vec3i implements Comparable<Vec3i> {
|
||||
}
|
||||
|
||||
@Override
|
||||
- public int hashCode() {
|
||||
+ public final int hashCode() { // Paper
|
||||
return (this.getY() + this.getZ() * 31) * 31 + this.getX();
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ public class Vec3i implements Comparable<Vec3i> {
|
||||
}
|
||||
}
|
||||
|
||||
- public int getX() {
|
||||
+ public final int getX() { // Paper
|
||||
return this.x;
|
||||
}
|
||||
|
||||
- public int getY() {
|
||||
+ public final int getY() { // Paper
|
||||
return this.y;
|
||||
}
|
||||
|
||||
- public int getZ() {
|
||||
+ public final int getZ() { // Paper
|
||||
return this.z;
|
||||
}
|
||||
|
|
@ -34,7 +34,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
// CraftBukkit end
|
||||
+ // Paper start - remove player from map on drop
|
||||
+ if (itemstack.getItem() == Items.FILLED_MAP) {
|
||||
+ net.minecraft.world.level.saveddata.maps.MapItemSavedData worldmap = net.minecraft.world.item.MapItem.getSavedData(itemstack, this.level);
|
||||
+ net.minecraft.world.level.saveddata.maps.MapItemSavedData worldmap = net.minecraft.world.item.MapItem.getSavedData(itemstack, this.level());
|
||||
+ if (worldmap != null) {
|
||||
+ worldmap.tickCarriedBy(this, itemstack);
|
||||
+ }
|
||||
|
|
444
patches/server/Improve-death-events.patch
Normal file
444
patches/server/Improve-death-events.patch
Normal file
|
@ -0,0 +1,444 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Phoenix616 <mail@moep.tv>
|
||||
Date: Tue, 21 Aug 2018 01:39:35 +0100
|
||||
Subject: [PATCH] Improve death events
|
||||
|
||||
This adds the ability to cancel the death events and to modify the sound
|
||||
an entity makes when dying. (In cases were no sound should it will be
|
||||
called with shouldPlaySound set to false allowing unsilencing of silent
|
||||
entities)
|
||||
|
||||
It makes handling of entity deaths a lot nicer as you no longer need
|
||||
to listen on the damage event and calculate if the entity dies yourself
|
||||
to cancel the death which has the benefit of also receiving the dropped
|
||||
items and experience which is otherwise only properly possible by using
|
||||
internal code.
|
||||
|
||||
== AT ==
|
||||
public net.minecraft.world.entity.LivingEntity getDeathSound()Lnet/minecraft/sounds/SoundEvent;
|
||||
public net.minecraft.world.entity.LivingEntity getSoundVolume()F
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
|
||||
public int latency;
|
||||
public boolean wonGame;
|
||||
private int containerUpdateDelay; // Paper
|
||||
+ // Paper start - cancellable death event
|
||||
+ public boolean queueHealthUpdatePacket = false;
|
||||
+ public net.minecraft.network.protocol.game.ClientboundSetHealthPacket queuedHealthUpdatePacket;
|
||||
+ // Paper end
|
||||
|
||||
// CraftBukkit start
|
||||
public String displayName;
|
||||
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
|
||||
String deathmessage = defaultMessage.getString();
|
||||
this.keepLevel = keepInventory; // SPIGOT-2222: pre-set keepLevel
|
||||
org.bukkit.event.entity.PlayerDeathEvent event = CraftEventFactory.callPlayerDeathEvent(this, loot, PaperAdventure.asAdventure(defaultMessage), defaultMessage.getString(), keepInventory); // Paper - Adventure
|
||||
+ // Paper start - cancellable death event
|
||||
+ if (event.isCancelled()) {
|
||||
+ // make compatible with plugins that might have already set the health in an event listener
|
||||
+ if (this.getHealth() <= 0) {
|
||||
+ this.setHealth((float) event.getReviveHealth());
|
||||
+ }
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
// SPIGOT-943 - only call if they have an inventory open
|
||||
if (this.containerMenu != this.inventoryMenu) {
|
||||
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
|
||||
}
|
||||
}
|
||||
}
|
||||
-
|
||||
- return super.hurt(source, amount);
|
||||
+ // Paper start - cancellable death events
|
||||
+ //return super.hurt(source, amount);
|
||||
+ this.queueHealthUpdatePacket = true;
|
||||
+ boolean damaged = super.hurt(source, amount);
|
||||
+ this.queueHealthUpdatePacket = false;
|
||||
+ if (this.queuedHealthUpdatePacket != null) {
|
||||
+ this.connection.send(this.queuedHealthUpdatePacket);
|
||||
+ this.queuedHealthUpdatePacket = null;
|
||||
+ }
|
||||
+ return damaged;
|
||||
+ // Paper end
|
||||
}
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
public Set<UUID> collidableExemptions = new HashSet<>();
|
||||
public boolean bukkitPickUpLoot;
|
||||
public org.bukkit.craftbukkit.entity.CraftLivingEntity getBukkitLivingEntity() { return (org.bukkit.craftbukkit.entity.CraftLivingEntity) super.getBukkitEntity(); } // Paper
|
||||
+ public boolean silentDeath = false; // Paper - mark entity as dying silently for cancellable death event
|
||||
|
||||
@Override
|
||||
public float getBukkitYaw() {
|
||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
if (knockbackCancelled) this.level.broadcastEntityEvent(this, (byte) 2); // Paper - Disable explosion knockback
|
||||
if (this.isDeadOrDying()) {
|
||||
if (!this.checkTotemDeathProtection(source)) {
|
||||
- SoundEvent soundeffect = this.getDeathSound();
|
||||
-
|
||||
- if (flag1 && soundeffect != null) {
|
||||
- this.playSound(soundeffect, this.getSoundVolume(), this.getVoicePitch());
|
||||
- }
|
||||
+ // Paper start - moved into CraftEventFactory event caller for cancellable death event
|
||||
+ this.silentDeath = !flag1; // mark entity as dying silently
|
||||
+ // Paper end
|
||||
|
||||
this.die(source);
|
||||
+ this.silentDeath = false; // Paper - cancellable death event - reset to default
|
||||
}
|
||||
} else if (flag1) {
|
||||
this.playHurtSound(source);
|
||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
if (!this.isRemoved() && !this.dead) {
|
||||
Entity entity = damageSource.getEntity();
|
||||
LivingEntity entityliving = this.getKillCredit();
|
||||
-
|
||||
+ /* // Paper - move down to make death event cancellable - this is the awardKillScore below
|
||||
if (this.deathScore >= 0 && entityliving != null) {
|
||||
entityliving.awardKillScore(this, this.deathScore, damageSource);
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
if (!this.level().isClientSide && this.hasCustomName()) {
|
||||
if (org.spigotmc.SpigotConfig.logNamedDeaths) LivingEntity.LOGGER.info("Named entity {} died: {}", this, this.getCombatTracker().getDeathMessage().getString()); // Spigot
|
||||
}
|
||||
+ */ // Paper - move down to make death event cancellable - this is the awardKillScore below
|
||||
|
||||
this.dead = true;
|
||||
- this.getCombatTracker().recheckStatus();
|
||||
+ // Paper - moved into if below
|
||||
Level world = this.level();
|
||||
|
||||
if (world instanceof ServerLevel) {
|
||||
ServerLevel worldserver = (ServerLevel) world;
|
||||
+ // Paper - move below into if for onKill
|
||||
+
|
||||
+ // Paper start
|
||||
+ org.bukkit.event.entity.EntityDeathEvent deathEvent = this.dropAllDeathLoot(damageSource);
|
||||
+ if (deathEvent == null || !deathEvent.isCancelled()) {
|
||||
+ if (this.deathScore >= 0 && entityliving != null) {
|
||||
+ entityliving.awardKillScore(this, this.deathScore, damageSource);
|
||||
+ }
|
||||
+ // Paper start - clear equipment if event is not cancelled
|
||||
+ if (this instanceof Mob) {
|
||||
+ for (EquipmentSlot slot : this.clearedEquipmentSlots) {
|
||||
+ this.setItemSlot(slot, ItemStack.EMPTY);
|
||||
+ }
|
||||
+ this.clearedEquipmentSlots.clear();
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
+ if (this.isSleeping()) {
|
||||
+ this.stopSleeping();
|
||||
+ }
|
||||
|
||||
- if (entity == null || entity.killedEntity(worldserver, this)) {
|
||||
+ if (!this.level().isClientSide && this.hasCustomName()) {
|
||||
+ if (org.spigotmc.SpigotConfig.logNamedDeaths) LivingEntity.LOGGER.info("Named entity {} died: {}", this, this.getCombatTracker().getDeathMessage().getString()); // Spigot
|
||||
+ }
|
||||
+
|
||||
+ this.getCombatTracker().recheckStatus();
|
||||
+ if (entity != null) {
|
||||
+ entity.wasKilled((ServerLevel) this.level(), this);
|
||||
+ }
|
||||
this.gameEvent(GameEvent.ENTITY_DIE);
|
||||
- this.dropAllDeathLoot(damageSource);
|
||||
- this.createWitherRose(entityliving);
|
||||
}
|
||||
|
||||
- this.level().broadcastEntityEvent(this, (byte) 3);
|
||||
+ // Paper end
|
||||
+ this.createWitherRose(entityliving);
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ if (this.dead) { // Paper
|
||||
+ this.level().broadcastEntityEvent(this, (byte) 3);
|
||||
this.setPose(Pose.DYING);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
if (!this.level().isClientSide) {
|
||||
boolean flag = false;
|
||||
|
||||
- if (adversary instanceof WitherBoss) {
|
||||
+ if (this.dead && adversary instanceof WitherBoss) { // Paper
|
||||
if (this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) {
|
||||
BlockPos blockposition = this.blockPosition();
|
||||
BlockState iblockdata = Blocks.WITHER_ROSE.defaultBlockState();
|
||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
}
|
||||
}
|
||||
|
||||
- protected void dropAllDeathLoot(DamageSource source) {
|
||||
+ // Paper start
|
||||
+ protected boolean clearEquipmentSlots = true;
|
||||
+ protected Set<EquipmentSlot> clearedEquipmentSlots = new java.util.HashSet<>();
|
||||
+ protected org.bukkit.event.entity.EntityDeathEvent dropAllDeathLoot(DamageSource source) {
|
||||
+ // Paper end
|
||||
Entity entity = source.getEntity();
|
||||
int i;
|
||||
|
||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
this.dropEquipment(); // CraftBukkit - from below
|
||||
if (this.shouldDropLoot() && this.level().getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) {
|
||||
this.dropFromLootTable(source, flag);
|
||||
+ // Paper start
|
||||
+ final boolean prev = this.clearEquipmentSlots;
|
||||
+ this.clearEquipmentSlots = false;
|
||||
+ this.clearedEquipmentSlots.clear();
|
||||
+ // Paper end
|
||||
this.dropCustomDeathLoot(source, i, flag);
|
||||
+ this.clearEquipmentSlots = prev; // Paper
|
||||
}
|
||||
// CraftBukkit start - Call death event
|
||||
- CraftEventFactory.callEntityDeathEvent(this, this.drops);
|
||||
+ org.bukkit.event.entity.EntityDeathEvent deathEvent = CraftEventFactory.callEntityDeathEvent(this, this.drops); // Paper
|
||||
+ this.postDeathDropItems(deathEvent); // Paper
|
||||
this.drops = new ArrayList<>();
|
||||
// CraftBukkit end
|
||||
|
||||
// this.dropInventory();// CraftBukkit - moved up
|
||||
this.dropExperience();
|
||||
+ return deathEvent; // Paper
|
||||
}
|
||||
|
||||
protected void dropEquipment() {}
|
||||
+ protected void postDeathDropItems(org.bukkit.event.entity.EntityDeathEvent event) {} // Paper - method for post death logic that cannot be ran before the event is potentially cancelled
|
||||
|
||||
// CraftBukkit start
|
||||
public int getExpReward() {
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Mob.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Mob.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Mob extends LivingEntity implements Targeting {
|
||||
}
|
||||
|
||||
this.spawnAtLocation(itemstack);
|
||||
+ if (this.clearEquipmentSlots) { // Paper
|
||||
this.setItemSlot(enumitemslot, ItemStack.EMPTY);
|
||||
+ // Paper start
|
||||
+ } else {
|
||||
+ this.clearedEquipmentSlots.add(enumitemslot);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/Fox.java b/src/main/java/net/minecraft/world/entity/animal/Fox.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/Fox.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/Fox.java
|
||||
@@ -0,0 +0,0 @@ public class Fox extends Animal implements VariantHolder<Fox.Type> {
|
||||
}
|
||||
|
||||
@Override
|
||||
- protected void dropAllDeathLoot(DamageSource source) {
|
||||
- ItemStack itemstack = this.getItemBySlot(EquipmentSlot.MAINHAND);
|
||||
+ // Paper start - Cancellable death event
|
||||
+ protected org.bukkit.event.entity.EntityDeathEvent dropAllDeathLoot(DamageSource source) {
|
||||
+ ItemStack itemstack = this.getItemBySlot(EquipmentSlot.MAINHAND).copy(); // Paper - modified by supercall
|
||||
+
|
||||
+ org.bukkit.event.entity.EntityDeathEvent deathEvent = super.dropAllDeathLoot(source);
|
||||
+
|
||||
+ // Below is code to drop
|
||||
+
|
||||
+ if (deathEvent == null || deathEvent.isCancelled()) {
|
||||
+ return deathEvent;
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
if (!itemstack.isEmpty()) {
|
||||
this.spawnAtLocation(itemstack);
|
||||
this.setItemSlot(EquipmentSlot.MAINHAND, ItemStack.EMPTY);
|
||||
}
|
||||
|
||||
- super.dropAllDeathLoot(source);
|
||||
+ return deathEvent; // Paper
|
||||
}
|
||||
|
||||
public static boolean isPathClear(Fox fox, LivingEntity chasedEntity) {
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/AbstractChestedHorse.java b/src/main/java/net/minecraft/world/entity/animal/horse/AbstractChestedHorse.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/horse/AbstractChestedHorse.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/horse/AbstractChestedHorse.java
|
||||
@@ -0,0 +0,0 @@ public abstract class AbstractChestedHorse extends AbstractHorse {
|
||||
this.spawnAtLocation(Blocks.CHEST);
|
||||
}
|
||||
|
||||
- this.setChest(false);
|
||||
+ //this.setCarryingChest(false); // Paper - moved to post death logic
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ protected void postDeathDropItems(org.bukkit.event.entity.EntityDeathEvent event) {
|
||||
+ if (this.hasChest() && (event == null || !event.isCancelled())) {
|
||||
+ this.setChest(false);
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public void addAdditionalSaveData(CompoundTag nbt) {
|
||||
super.addAdditionalSaveData(nbt);
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
@@ -0,0 +0,0 @@ public class ArmorStand extends LivingEntity {
|
||||
this.gameEvent(GameEvent.ENTITY_DAMAGE, source.getEntity());
|
||||
this.lastHit = i;
|
||||
} else {
|
||||
- this.brokenByPlayer(source);
|
||||
+ org.bukkit.event.entity.EntityDeathEvent event = this.brokenByPlayer(source); // Paper
|
||||
this.showBreakingParticles();
|
||||
+ if (!event.isCancelled()) // Paper
|
||||
this.discard(); // CraftBukkit - SPIGOT-4890: remain as this.discard() since above damagesource method will call death event
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ public class ArmorStand extends LivingEntity {
|
||||
|
||||
}
|
||||
|
||||
- private void brokenByPlayer(DamageSource damageSource) {
|
||||
+ private org.bukkit.event.entity.EntityDeathEvent brokenByPlayer(DamageSource damageSource) { // Paper
|
||||
ItemStack itemstack = new ItemStack(Items.ARMOR_STAND);
|
||||
|
||||
if (this.hasCustomName()) {
|
||||
@@ -0,0 +0,0 @@ public class ArmorStand extends LivingEntity {
|
||||
}
|
||||
|
||||
drops.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asBukkitCopy(itemstack)); // CraftBukkit - add to drops
|
||||
- this.brokenByAnything(damageSource);
|
||||
+ return this.brokenByAnything(damageSource); // Paper
|
||||
}
|
||||
|
||||
- private void brokenByAnything(DamageSource damageSource) {
|
||||
+ private org.bukkit.event.entity.EntityDeathEvent brokenByAnything(DamageSource damageSource) { // Paper
|
||||
this.playBrokenSound();
|
||||
// this.dropAllDeathLoot(damagesource); // CraftBukkit - moved down
|
||||
|
||||
@@ -0,0 +0,0 @@ public class ArmorStand extends LivingEntity {
|
||||
this.armorItems.set(i, ItemStack.EMPTY);
|
||||
}
|
||||
}
|
||||
- this.dropAllDeathLoot(damageSource); // CraftBukkit - moved from above
|
||||
+ return this.dropAllDeathLoot(damageSource); // CraftBukkit - moved from above // Paper
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ public class ArmorStand extends LivingEntity {
|
||||
|
||||
@Override
|
||||
public void kill() {
|
||||
- org.bukkit.craftbukkit.event.CraftEventFactory.callEntityDeathEvent(this, drops); // CraftBukkit - call event
|
||||
+ org.bukkit.event.entity.EntityDeathEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityDeathEvent(this, drops); // CraftBukkit - call event // Paper - make cancellable
|
||||
+ if (event.isCancelled()) return; // Paper - make cancellable
|
||||
this.remove(Entity.RemovalReason.KILLED);
|
||||
this.gameEvent(GameEvent.ENTITY_DIE);
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
}
|
||||
|
||||
public void sendHealthUpdate() {
|
||||
- this.getHandle().connection.send(new ClientboundSetHealthPacket(this.getScaledHealth(), this.getHandle().getFoodData().getFoodLevel(), this.getHandle().getFoodData().getSaturationLevel()));
|
||||
+ // Paper start - cancellable death event
|
||||
+ ClientboundSetHealthPacket packet = new ClientboundSetHealthPacket(this.getScaledHealth(), this.getHandle().getFoodData().getFoodLevel(), this.getHandle().getFoodData().getSaturationLevel());
|
||||
+ if (this.getHandle().queueHealthUpdatePacket) {
|
||||
+ this.getHandle().queuedHealthUpdatePacket = packet;
|
||||
+ } else {
|
||||
+ this.getHandle().connection.send(packet);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
public void injectScaledMaxHealth(Collection<AttributeInstance> collection, boolean force) {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
@@ -0,0 +0,0 @@ public class CraftEventFactory {
|
||||
public static EntityDeathEvent callEntityDeathEvent(net.minecraft.world.entity.LivingEntity victim, List<org.bukkit.inventory.ItemStack> drops) {
|
||||
CraftLivingEntity entity = (CraftLivingEntity) victim.getBukkitEntity();
|
||||
EntityDeathEvent event = new EntityDeathEvent(entity, drops, victim.getExpReward());
|
||||
+ populateFields(victim, event); // Paper - make cancellable
|
||||
CraftWorld world = (CraftWorld) entity.getWorld();
|
||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
|
||||
+ // Paper start - make cancellable
|
||||
+ if (event.isCancelled()) {
|
||||
+ return event;
|
||||
+ }
|
||||
+ playDeathSound(victim, event);
|
||||
+ // Paper end
|
||||
victim.expToDrop = event.getDroppedExp();
|
||||
|
||||
for (org.bukkit.inventory.ItemStack stack : event.getDrops()) {
|
||||
@@ -0,0 +0,0 @@ public class CraftEventFactory {
|
||||
PlayerDeathEvent event = new PlayerDeathEvent(entity, drops, victim.getExpReward(), 0, deathMessage, stringDeathMessage); // Paper - Adventure
|
||||
event.setKeepInventory(keepInventory);
|
||||
event.setKeepLevel(victim.keepLevel); // SPIGOT-2222: pre-set keepLevel
|
||||
+ populateFields(victim, event); // Paper - make cancellable
|
||||
org.bukkit.World world = entity.getWorld();
|
||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
+ // Paper start - make cancellable
|
||||
+ if (event.isCancelled()) {
|
||||
+ return event;
|
||||
+ }
|
||||
+ playDeathSound(victim, event);
|
||||
+ // Paper end
|
||||
|
||||
victim.keepLevel = event.getKeepLevel();
|
||||
victim.newLevel = event.getNewLevel();
|
||||
@@ -0,0 +0,0 @@ public class CraftEventFactory {
|
||||
return event;
|
||||
}
|
||||
|
||||
+ // Paper start - helper methods for making death event cancellable
|
||||
+ // Add information to death event
|
||||
+ private static void populateFields(net.minecraft.world.entity.LivingEntity victim, EntityDeathEvent event) {
|
||||
+ event.setReviveHealth(event.getEntity().getAttribute(org.bukkit.attribute.Attribute.GENERIC_MAX_HEALTH).getValue());
|
||||
+ event.setShouldPlayDeathSound(!victim.silentDeath && !victim.isSilent());
|
||||
+ net.minecraft.sounds.SoundEvent soundEffect = victim.getDeathSound();
|
||||
+ event.setDeathSound(soundEffect != null ? org.bukkit.craftbukkit.CraftSound.getBukkit(soundEffect) : null);
|
||||
+ event.setDeathSoundCategory(org.bukkit.SoundCategory.valueOf(victim.getSoundSource().name()));
|
||||
+ event.setDeathSoundVolume(victim.getSoundVolume());
|
||||
+ event.setDeathSoundPitch(victim.getVoicePitch());
|
||||
+ }
|
||||
+
|
||||
+ // Play death sound manually
|
||||
+ private static void playDeathSound(net.minecraft.world.entity.LivingEntity victim, EntityDeathEvent event) {
|
||||
+ if (event.shouldPlayDeathSound() && event.getDeathSound() != null && event.getDeathSoundCategory() != null) {
|
||||
+ net.minecraft.world.entity.player.Player source = victim instanceof net.minecraft.world.entity.player.Player ? (net.minecraft.world.entity.player.Player) victim : null;
|
||||
+ double x = event.getEntity().getLocation().getX();
|
||||
+ double y = event.getEntity().getLocation().getY();
|
||||
+ double z = event.getEntity().getLocation().getZ();
|
||||
+ net.minecraft.sounds.SoundEvent soundEffect = org.bukkit.craftbukkit.CraftSound.getSoundEffect(event.getDeathSound());
|
||||
+ net.minecraft.sounds.SoundSource soundCategory = net.minecraft.sounds.SoundSource.valueOf(event.getDeathSoundCategory().name());
|
||||
+ victim.level.playSound(source, x, y, z, soundEffect, soundCategory, event.getDeathSoundVolume(), event.getDeathSoundPitch());
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
/**
|
||||
* Server methods
|
||||
*/
|
58
patches/server/Inventory-removeItemAnySlot.patch
Normal file
58
patches/server/Inventory-removeItemAnySlot.patch
Normal file
|
@ -0,0 +1,58 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <1254957+zachbr@users.noreply.github.com>
|
||||
Date: Tue, 28 Aug 2018 23:04:15 -0400
|
||||
Subject: [PATCH] Inventory#removeItemAnySlot
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java
|
||||
@@ -0,0 +0,0 @@ public class CraftInventory implements Inventory {
|
||||
}
|
||||
|
||||
private int first(ItemStack item, boolean withAmount) {
|
||||
+ // Paper start
|
||||
+ return first(item, withAmount, getStorageContents());
|
||||
+ }
|
||||
+
|
||||
+ private int first(ItemStack item, boolean withAmount, ItemStack[] inventory) {
|
||||
+ // Paper end
|
||||
if (item == null) {
|
||||
return -1;
|
||||
}
|
||||
- ItemStack[] inventory = this.getStorageContents();
|
||||
+ // ItemStack[] inventory = this.getStorageContents(); // Paper - let param deal
|
||||
for (int i = 0; i < inventory.length; i++) {
|
||||
if (inventory[i] == null) continue;
|
||||
|
||||
@@ -0,0 +0,0 @@ public class CraftInventory implements Inventory {
|
||||
|
||||
@Override
|
||||
public HashMap<Integer, ItemStack> removeItem(ItemStack... items) {
|
||||
+ // Paper start
|
||||
+ return removeItem(false, items);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public HashMap<Integer, ItemStack> removeItemAnySlot(ItemStack... items) {
|
||||
+ return removeItem(true, items);
|
||||
+ }
|
||||
+
|
||||
+ private HashMap<Integer, ItemStack> removeItem(boolean searchEntire, ItemStack... items) {
|
||||
+ // Paper end
|
||||
Validate.notNull(items, "Items cannot be null");
|
||||
HashMap<Integer, ItemStack> leftover = new HashMap<Integer, ItemStack>();
|
||||
|
||||
@@ -0,0 +0,0 @@ public class CraftInventory implements Inventory {
|
||||
int toDelete = item.getAmount();
|
||||
|
||||
while (true) {
|
||||
- int first = this.first(item, false);
|
||||
+ // Paper start - Allow searching entire contents
|
||||
+ ItemStack[] toSearch = searchEntire ? getContents() : getStorageContents();
|
||||
+ int first = this.first(item, false, toSearch);
|
||||
+ // Paper end
|
||||
|
||||
// Drat! we don't have this type in the inventory
|
||||
if (first == -1) {
|
|
@ -0,0 +1,20 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
Date: Sun, 2 Sep 2018 19:34:33 -0700
|
||||
Subject: [PATCH] Make CraftWorld#loadChunk(int, int, false) load unconverted
|
||||
chunks
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
@@ -0,0 +0,0 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
@Override
|
||||
public boolean loadChunk(int x, int z, boolean generate) {
|
||||
org.spigotmc.AsyncCatcher.catchOp("chunk load"); // Spigot
|
||||
- ChunkAccess chunk = this.world.getChunkSource().getChunk(x, z, generate ? ChunkStatus.FULL : ChunkStatus.EMPTY, true);
|
||||
+ ChunkAccess chunk = this.world.getChunkSource().getChunk(x, z, generate || isChunkGenerated(x, z) ? ChunkStatus.FULL : ChunkStatus.EMPTY, true); // Paper
|
||||
|
||||
// If generate = false, but the chunk already exists, we will get this back.
|
||||
if (chunk instanceof ImposterProtoChunk) {
|
108
patches/server/Optimize-BlockPosition-helper-methods.patch
Normal file
108
patches/server/Optimize-BlockPosition-helper-methods.patch
Normal file
|
@ -0,0 +1,108 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
Date: Wed, 15 Aug 2018 12:05:12 -0700
|
||||
Subject: [PATCH] Optimize BlockPosition helper methods
|
||||
|
||||
Resolves #1338
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/core/BlockPos.java b/src/main/java/net/minecraft/core/BlockPos.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/core/BlockPos.java
|
||||
+++ b/src/main/java/net/minecraft/core/BlockPos.java
|
||||
@@ -0,0 +0,0 @@ public class BlockPos extends Vec3i {
|
||||
|
||||
@Override
|
||||
public BlockPos above() {
|
||||
- return this.relative(Direction.UP);
|
||||
+ return new BlockPos(this.getX(), this.getY() + 1, this.getZ()); // Paper - Optimize BlockPosition
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos above(int distance) {
|
||||
- return this.relative(Direction.UP, distance);
|
||||
+ return distance == 0 ? this : new BlockPos(this.getX(), this.getY() + distance, this.getZ()); // Paper - Optimize BlockPosition
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos below() {
|
||||
- return this.relative(Direction.DOWN);
|
||||
+ return new BlockPos(this.getX(), this.getY() - 1, this.getZ()); // Paper - Optimize BlockPosition
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos below(int i) {
|
||||
- return this.relative(Direction.DOWN, i);
|
||||
+ return i == 0 ? this : new BlockPos(this.getX(), this.getY() - i, this.getZ()); // Paper - Optimize BlockPosition
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos north() {
|
||||
- return this.relative(Direction.NORTH);
|
||||
+ return new BlockPos(this.getX(), this.getY(), this.getZ() - 1); // Paper - Optimize BlockPosition
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos north(int distance) {
|
||||
- return this.relative(Direction.NORTH, distance);
|
||||
+ return distance == 0 ? this : new BlockPos(this.getX(), this.getY(), this.getZ() - distance); // Paper - Optimize BlockPosition
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos south() {
|
||||
- return this.relative(Direction.SOUTH);
|
||||
+ return new BlockPos(this.getX(), this.getY(), this.getZ() + 1); // Paper - Optimize BlockPosition
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos south(int distance) {
|
||||
- return this.relative(Direction.SOUTH, distance);
|
||||
+ return distance == 0 ? this : new BlockPos(this.getX(), this.getY(), this.getZ() + distance); // Paper - Optimize BlockPosition
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos west() {
|
||||
- return this.relative(Direction.WEST);
|
||||
+ return new BlockPos(this.getX() - 1, this.getY(), this.getZ()); // Paper - Optimize BlockPosition
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos west(int distance) {
|
||||
- return this.relative(Direction.WEST, distance);
|
||||
+ return distance == 0 ? this : new BlockPos(this.getX() - distance, this.getY(), this.getZ()); // Paper - Optimize BlockPosition
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos east() {
|
||||
- return this.relative(Direction.EAST);
|
||||
+ return new BlockPos(this.getX() + 1, this.getY(), this.getZ()); // Paper - Optimize BlockPosition
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos east(int distance) {
|
||||
- return this.relative(Direction.EAST, distance);
|
||||
+ return distance == 0 ? this : new BlockPos(this.getX() + distance, this.getY(), this.getZ()); // Paper - Optimize BlockPosition
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos relative(Direction direction) {
|
||||
+ // Paper Start - Optimize BlockPosition
|
||||
+ switch(direction) {
|
||||
+ case UP:
|
||||
+ return new BlockPos(this.getX(), this.getY() + 1, this.getZ());
|
||||
+ case DOWN:
|
||||
+ return new BlockPos(this.getX(), this.getY() - 1, this.getZ());
|
||||
+ case NORTH:
|
||||
+ return new BlockPos(this.getX(), this.getY(), this.getZ() - 1);
|
||||
+ case SOUTH:
|
||||
+ return new BlockPos(this.getX(), this.getY(), this.getZ() + 1);
|
||||
+ case WEST:
|
||||
+ return new BlockPos(this.getX() - 1, this.getY(), this.getZ());
|
||||
+ case EAST:
|
||||
+ return new BlockPos(this.getX() + 1, this.getY(), this.getZ());
|
||||
+ default:
|
||||
return new BlockPos(this.getX() + direction.getStepX(), this.getY() + direction.getStepY(), this.getZ() + direction.getStepZ());
|
||||
+ }
|
||||
+ // Paper End
|
||||
}
|
||||
|
||||
@Override
|
49
patches/server/Optimize-CraftBlockData-Creation.patch
Normal file
49
patches/server/Optimize-CraftBlockData-Creation.patch
Normal file
|
@ -0,0 +1,49 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: miclebrick <miclebrick@outlook.com>
|
||||
Date: Thu, 23 Aug 2018 11:45:32 -0400
|
||||
Subject: [PATCH] Optimize CraftBlockData Creation
|
||||
|
||||
Avoids a hashmap lookup by cacheing a reference to the CraftBlockData
|
||||
and cloning it when one is needed.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java
|
||||
@@ -0,0 +0,0 @@ public abstract class BlockBehaviour implements FeatureElement {
|
||||
this.replaceable = blockbase_info.replaceable;
|
||||
this.conditionallyFullOpaque = this.isOpaque() & this.isTransparentOnSomeFaces(); // Paper
|
||||
}
|
||||
+ // Paper start - impl cached craft block data, lazy load to fix issue with loading at the wrong time
|
||||
+ private org.bukkit.craftbukkit.block.data.CraftBlockData cachedCraftBlockData;
|
||||
+
|
||||
+ public org.bukkit.craftbukkit.block.data.CraftBlockData createCraftBlockData() {
|
||||
+ if (cachedCraftBlockData == null) cachedCraftBlockData = org.bukkit.craftbukkit.block.data.CraftBlockData.createData(asState());
|
||||
+ return (org.bukkit.craftbukkit.block.data.CraftBlockData) cachedCraftBlockData.clone();
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
private boolean calculateSolid() {
|
||||
if (((Block) this.owner).properties.forceSolidOn) {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java b/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java
|
||||
@@ -0,0 +0,0 @@ public class CraftBlockData implements BlockData {
|
||||
return craft;
|
||||
}
|
||||
|
||||
+ // Paper start - optimize creating BlockData to not need a map lookup
|
||||
+ static {
|
||||
+ // Initialize cached data for all IBlockData instances after registration
|
||||
+ Block.BLOCK_STATE_REGISTRY.iterator().forEachRemaining(BlockState::createCraftBlockData);
|
||||
+ }
|
||||
public static CraftBlockData fromData(BlockState data) {
|
||||
+ return data.createCraftBlockData();
|
||||
+ }
|
||||
+
|
||||
+ public static CraftBlockData createData(BlockState data) {
|
||||
+ // Paper end
|
||||
return CraftBlockData.MAP.getOrDefault(data.getBlock().getClass(), CraftBlockData::new).apply(data);
|
||||
}
|
||||
|
40
patches/server/Optimize-MappedRegistry.patch
Normal file
40
patches/server/Optimize-MappedRegistry.patch
Normal file
|
@ -0,0 +1,40 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sun, 26 Aug 2018 20:49:50 -0400
|
||||
Subject: [PATCH] Optimize MappedRegistry
|
||||
|
||||
Use larger initial sizes to increase bucket capacity on the BiMap
|
||||
|
||||
BiMap.get was seen to be using a good bit of CPU time.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/core/MappedRegistry.java b/src/main/java/net/minecraft/core/MappedRegistry.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/core/MappedRegistry.java
|
||||
+++ b/src/main/java/net/minecraft/core/MappedRegistry.java
|
||||
@@ -0,0 +0,0 @@ public class MappedRegistry<T> implements WritableRegistry<T> {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
final ResourceKey<? extends Registry<T>> key;
|
||||
private final ObjectList<Holder.Reference<T>> byId = new ObjectArrayList<>(256);
|
||||
- private final Object2IntMap<T> toId = Util.make(new Object2IntOpenCustomHashMap<>(Util.identityStrategy()), (map) -> {
|
||||
- map.defaultReturnValue(-1);
|
||||
- });
|
||||
- private final Map<ResourceLocation, Holder.Reference<T>> byLocation = new HashMap<>();
|
||||
- private final Map<ResourceKey<T>, Holder.Reference<T>> byKey = new HashMap<>();
|
||||
- private final Map<T, Holder.Reference<T>> byValue = new IdentityHashMap<>();
|
||||
- private final Map<T, Lifecycle> lifecycles = new IdentityHashMap<>();
|
||||
+ private final it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap<T> toId = new it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap<T>(2048);// Paper - use bigger expected size to reduce collisions and direct intent for FastUtil to be identity map
|
||||
+ private final Map<ResourceLocation, Holder.Reference<T>> byLocation = new HashMap<>(2048); // Paper - use bigger expected size to reduce collisions
|
||||
+ private final Map<ResourceKey<T>, Holder.Reference<T>> byKey = new HashMap<>(2048); // Paper - use bigger expected size to reduce collisions
|
||||
+ private final Map<T, Holder.Reference<T>> byValue = new IdentityHashMap<>(2048); // Paper - use bigger expected size to reduce collisions
|
||||
+ private final Map<T, Lifecycle> lifecycles = new IdentityHashMap<>(2048); // Paper - use bigger expected size to reduce collisions
|
||||
private Lifecycle registryLifecycle;
|
||||
private volatile Map<TagKey<T>, HolderSet.Named<T>> tags = new IdentityHashMap<>();
|
||||
private boolean frozen;
|
||||
@@ -0,0 +0,0 @@ public class MappedRegistry<T> implements WritableRegistry<T> {
|
||||
}
|
||||
|
||||
public MappedRegistry(ResourceKey<? extends Registry<T>> key, Lifecycle lifecycle, boolean intrusive) {
|
||||
+ this.toId.defaultReturnValue(-1); // Paper
|
||||
Bootstrap.checkBootstrapCalled(() -> {
|
||||
return "registry " + key;
|
||||
});
|
|
@ -0,0 +1,36 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Hugo Manrique <hugmanrique@gmail.com>
|
||||
Date: Mon, 23 Jul 2018 12:57:39 +0200
|
||||
Subject: [PATCH] Option to prevent armor stands from doing entity lookups
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
@@ -0,0 +0,0 @@ public class ArmorStand extends LivingEntity {
|
||||
|
||||
@Override
|
||||
protected void pushEntities() {
|
||||
+ if (!this.level().paperConfig().entities.armorStands.doCollisionEntityLookups) return; // Paper
|
||||
List<Entity> list = this.level().getEntities((Entity) this, this.getBoundingBox(), ArmorStand.RIDABLE_MINECARTS);
|
||||
|
||||
for (int i = 0; i < list.size(); ++i) {
|
||||
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/Level.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
// Paper end
|
||||
}
|
||||
}
|
||||
+ // Paper start - Prevent armor stands from doing entity lookups
|
||||
+ @Override
|
||||
+ public boolean noCollision(@Nullable Entity entity, AABB box) {
|
||||
+ if (entity instanceof net.minecraft.world.entity.decoration.ArmorStand && !entity.level.paperConfig().entities.armorStands.doCollisionEntityLookups) return false;
|
||||
+ return LevelAccessor.super.noCollision(entity, box);
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
public boolean shouldTickDeath(Entity entity) {
|
||||
return true;
|
33
patches/server/PlayerElytraBoostEvent.patch
Normal file
33
patches/server/PlayerElytraBoostEvent.patch
Normal file
|
@ -0,0 +1,33 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Sat, 21 Jul 2018 01:59:59 -0500
|
||||
Subject: [PATCH] PlayerElytraBoostEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/item/FireworkRocketItem.java b/src/main/java/net/minecraft/world/item/FireworkRocketItem.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/FireworkRocketItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/FireworkRocketItem.java
|
||||
@@ -0,0 +0,0 @@ public class FireworkRocketItem extends Item {
|
||||
if (!world.isClientSide) {
|
||||
FireworkRocketEntity fireworkRocketEntity = new FireworkRocketEntity(world, itemStack, user);
|
||||
fireworkRocketEntity.spawningEntity = user.getUUID(); // Paper
|
||||
- world.addFreshEntity(fireworkRocketEntity);
|
||||
- if (!user.getAbilities().instabuild) {
|
||||
+ // Paper start
|
||||
+ com.destroystokyo.paper.event.player.PlayerElytraBoostEvent event = new com.destroystokyo.paper.event.player.PlayerElytraBoostEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack), (org.bukkit.entity.Firework) fireworkRocketEntity.getBukkitEntity());
|
||||
+ if (event.callEvent() && world.addFreshEntity(fireworkRocketEntity)) {
|
||||
+ user.awardStat(Stats.ITEM_USED.get(this));
|
||||
+ if (event.shouldConsume() && !user.getAbilities().instabuild) {
|
||||
itemStack.shrink(1);
|
||||
+ } else ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
|
||||
+ } else if (user instanceof net.minecraft.server.level.ServerPlayer) {
|
||||
+ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
- user.awardStat(Stats.ITEM_USED.get(this));
|
||||
+ // user.awardStat(Stats.ITEM_USED.get(this)); // Paper - move up
|
||||
}
|
||||
|
||||
return InteractionResultHolder.sidedSuccess(user.getItemInHand(hand), world.isClientSide());
|
301
patches/server/PlayerLaunchProjectileEvent.patch
Normal file
301
patches/server/PlayerLaunchProjectileEvent.patch
Normal file
|
@ -0,0 +1,301 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Sat, 21 Jul 2018 03:11:03 -0500
|
||||
Subject: [PATCH] PlayerLaunchProjectileEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/item/EggItem.java b/src/main/java/net/minecraft/world/item/EggItem.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/EggItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/EggItem.java
|
||||
@@ -0,0 +0,0 @@ public class EggItem extends Item {
|
||||
|
||||
entityegg.setItem(itemstack);
|
||||
entityegg.shootFromRotation(user, user.getXRot(), user.getYRot(), 0.0F, 1.5F, 1.0F);
|
||||
- // CraftBukkit start
|
||||
- if (!world.addFreshEntity(entityegg)) {
|
||||
+ // Paper start
|
||||
+ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack), (org.bukkit.entity.Projectile) entityegg.getBukkitEntity());
|
||||
+ if (event.callEvent() && world.addFreshEntity(entityegg)) {
|
||||
+ if (event.shouldConsume() && !user.getAbilities().instabuild) {
|
||||
+ itemstack.shrink(1);
|
||||
+ } else if (user instanceof net.minecraft.server.level.ServerPlayer) {
|
||||
+ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
|
||||
+ }
|
||||
+
|
||||
+ world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), net.minecraft.sounds.SoundEvents.EGG_THROW, net.minecraft.sounds.SoundSource.PLAYERS, 0.5F, 0.4F / (net.minecraft.world.entity.Entity.SHARED_RANDOM.nextFloat() * 0.4F + 0.8F));
|
||||
+ user.awardStat(Stats.ITEM_USED.get(this));
|
||||
+ } else {
|
||||
if (user instanceof net.minecraft.server.level.ServerPlayer) {
|
||||
((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
|
||||
}
|
||||
return InteractionResultHolder.fail(itemstack);
|
||||
}
|
||||
- // CraftBukkit end
|
||||
+ // Paper end
|
||||
}
|
||||
world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.EGG_THROW, SoundSource.PLAYERS, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F));
|
||||
|
||||
+ /* // Paper start - moved up
|
||||
user.awardStat(Stats.ITEM_USED.get(this));
|
||||
if (!user.getAbilities().instabuild) {
|
||||
itemstack.shrink(1);
|
||||
}
|
||||
+ */ // Paper end
|
||||
|
||||
return InteractionResultHolder.sidedSuccess(itemstack, world.isClientSide());
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/item/EnderpearlItem.java b/src/main/java/net/minecraft/world/item/EnderpearlItem.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/EnderpearlItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/EnderpearlItem.java
|
||||
@@ -0,0 +0,0 @@ public class EnderpearlItem extends Item {
|
||||
|
||||
entityenderpearl.setItem(itemstack);
|
||||
entityenderpearl.shootFromRotation(user, user.getXRot(), user.getYRot(), 0.0F, 1.5F, 1.0F);
|
||||
- if (!world.addFreshEntity(entityenderpearl)) {
|
||||
+ // Paper start
|
||||
+ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack), (org.bukkit.entity.Projectile) entityenderpearl.getBukkitEntity());
|
||||
+ if (event.callEvent() && world.addFreshEntity(entityenderpearl)) {
|
||||
+ if (event.shouldConsume() && !user.getAbilities().instabuild) {
|
||||
+ itemstack.shrink(1);
|
||||
+ } else if (user instanceof net.minecraft.server.level.ServerPlayer) {
|
||||
+ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
|
||||
+ }
|
||||
+
|
||||
+ world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.ENDER_PEARL_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (net.minecraft.world.entity.Entity.SHARED_RANDOM.nextFloat() * 0.4F + 0.8F));
|
||||
+ user.awardStat(Stats.ITEM_USED.get(this));
|
||||
+ user.getCooldowns().addCooldown(this, 20);
|
||||
+ } else {
|
||||
+ // Paper end
|
||||
if (user instanceof net.minecraft.server.level.ServerPlayer) {
|
||||
((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class EnderpearlItem extends Item {
|
||||
}
|
||||
}
|
||||
|
||||
+ /* // Paper start - moved up
|
||||
world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.ENDER_PEARL_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F));
|
||||
user.getCooldowns().addCooldown(this, 20);
|
||||
// CraftBukkit end
|
||||
@@ -0,0 +0,0 @@ public class EnderpearlItem extends Item {
|
||||
if (!user.getAbilities().instabuild) {
|
||||
itemstack.shrink(1);
|
||||
}
|
||||
+ */ // Paper end - moved up
|
||||
|
||||
return InteractionResultHolder.sidedSuccess(itemstack, world.isClientSide());
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/item/ExperienceBottleItem.java b/src/main/java/net/minecraft/world/item/ExperienceBottleItem.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/ExperienceBottleItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/ExperienceBottleItem.java
|
||||
@@ -0,0 +0,0 @@ public class ExperienceBottleItem extends Item {
|
||||
@Override
|
||||
public InteractionResultHolder<ItemStack> use(Level world, Player user, InteractionHand hand) {
|
||||
ItemStack itemStack = user.getItemInHand(hand);
|
||||
- world.playSound((Player)null, user.getX(), user.getY(), user.getZ(), SoundEvents.EXPERIENCE_BOTTLE_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F));
|
||||
+ // world.playSound((Player)null, user.getX(), user.getY(), user.getZ(), SoundEvents.EXPERIENCE_BOTTLE_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F)); // Paper - moved down
|
||||
if (!world.isClientSide) {
|
||||
ThrownExperienceBottle thrownExperienceBottle = new ThrownExperienceBottle(world, user);
|
||||
thrownExperienceBottle.setItem(itemStack);
|
||||
thrownExperienceBottle.shootFromRotation(user, user.getXRot(), user.getYRot(), -20.0F, 0.7F, 1.0F);
|
||||
- world.addFreshEntity(thrownExperienceBottle);
|
||||
+ // Paper start
|
||||
+ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack), (org.bukkit.entity.Projectile) thrownExperienceBottle.getBukkitEntity());
|
||||
+ if (event.callEvent() && world.addFreshEntity(thrownExperienceBottle)) {
|
||||
+ if (event.shouldConsume() && !user.getAbilities().instabuild) {
|
||||
+ itemStack.shrink(1);
|
||||
+ } else if (user instanceof net.minecraft.server.level.ServerPlayer) {
|
||||
+ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
|
||||
+ }
|
||||
+
|
||||
+ world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.EXPERIENCE_BOTTLE_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (net.minecraft.world.entity.Entity.SHARED_RANDOM.nextFloat() * 0.4F + 0.8F));
|
||||
+ user.awardStat(Stats.ITEM_USED.get(this));
|
||||
+ } else {
|
||||
+ if (user instanceof net.minecraft.server.level.ServerPlayer) {
|
||||
+ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
|
||||
+ }
|
||||
+ return InteractionResultHolder.fail(itemStack);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
+ /* // Paper start - moved up
|
||||
user.awardStat(Stats.ITEM_USED.get(this));
|
||||
if (!user.getAbilities().instabuild) {
|
||||
itemStack.shrink(1);
|
||||
}
|
||||
+ */ // Paper end
|
||||
|
||||
return InteractionResultHolder.sidedSuccess(itemStack, world.isClientSide());
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/item/FireworkRocketItem.java b/src/main/java/net/minecraft/world/item/FireworkRocketItem.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/FireworkRocketItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/FireworkRocketItem.java
|
||||
@@ -0,0 +0,0 @@ public class FireworkRocketItem extends Item {
|
||||
Direction direction = context.getClickedFace();
|
||||
FireworkRocketEntity fireworkRocketEntity = new FireworkRocketEntity(level, context.getPlayer(), vec3.x + (double)direction.getStepX() * 0.15D, vec3.y + (double)direction.getStepY() * 0.15D, vec3.z + (double)direction.getStepZ() * 0.15D, itemStack);
|
||||
fireworkRocketEntity.spawningEntity = context.getPlayer() == null ? null : context.getPlayer().getUUID(); // Paper
|
||||
- level.addFreshEntity(fireworkRocketEntity);
|
||||
- itemStack.shrink(1);
|
||||
+ // Paper start - PlayerLaunchProjectileEvent
|
||||
+ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) context.getPlayer().getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack), (org.bukkit.entity.Firework) fireworkRocketEntity.getBukkitEntity());
|
||||
+ if (!event.callEvent() || !level.addFreshEntity(fireworkRocketEntity)) return InteractionResult.PASS;
|
||||
+ if (event.shouldConsume() && !context.getPlayer().getAbilities().instabuild) itemStack.shrink(1);
|
||||
+ else if (context.getPlayer() instanceof net.minecraft.server.level.ServerPlayer) ((net.minecraft.server.level.ServerPlayer) context.getPlayer()).getBukkitEntity().updateInventory();
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
return InteractionResult.sidedSuccess(level.isClientSide);
|
||||
diff --git a/src/main/java/net/minecraft/world/item/LingeringPotionItem.java b/src/main/java/net/minecraft/world/item/LingeringPotionItem.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/LingeringPotionItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/LingeringPotionItem.java
|
||||
@@ -0,0 +0,0 @@ public class LingeringPotionItem extends ThrowablePotionItem {
|
||||
|
||||
@Override
|
||||
public InteractionResultHolder<ItemStack> use(Level world, Player user, InteractionHand hand) {
|
||||
+ // Paper start
|
||||
+ InteractionResultHolder<ItemStack> wrapper = super.use(world, user, hand);
|
||||
+ if (wrapper.getResult() != net.minecraft.world.InteractionResult.FAIL) {
|
||||
world.playSound((Player)null, user.getX(), user.getY(), user.getZ(), SoundEvents.LINGERING_POTION_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F));
|
||||
- return super.use(world, user, hand);
|
||||
+ }
|
||||
+ return wrapper;
|
||||
+ // Paper end
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/item/SnowballItem.java b/src/main/java/net/minecraft/world/item/SnowballItem.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/SnowballItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/SnowballItem.java
|
||||
@@ -0,0 +0,0 @@ public class SnowballItem extends Item {
|
||||
|
||||
entitysnowball.setItem(itemstack);
|
||||
entitysnowball.shootFromRotation(user, user.getXRot(), user.getYRot(), 0.0F, 1.5F, 1.0F);
|
||||
- if (world.addFreshEntity(entitysnowball)) {
|
||||
- if (!user.getAbilities().instabuild) {
|
||||
+ // Paper start
|
||||
+ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack), (org.bukkit.entity.Projectile) entitysnowball.getBukkitEntity());
|
||||
+ if (event.callEvent() && world.addFreshEntity(entitysnowball)) {
|
||||
+ user.awardStat(Stats.ITEM_USED.get(this));
|
||||
+ if (event.shouldConsume() && !user.getAbilities().instabuild) {
|
||||
+ // Paper end
|
||||
itemstack.shrink(1);
|
||||
+ } else if (user instanceof net.minecraft.server.level.ServerPlayer) { // Paper
|
||||
+ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory(); // Paper
|
||||
}
|
||||
|
||||
world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.SNOWBALL_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F));
|
||||
- } else if (user instanceof net.minecraft.server.level.ServerPlayer) {
|
||||
- ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
|
||||
+ } else { // Paper
|
||||
+ if (user instanceof net.minecraft.server.level.ServerPlayer) ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory(); // Paper
|
||||
+ return InteractionResultHolder.fail(itemstack); // Paper
|
||||
}
|
||||
}
|
||||
// CraftBukkit end
|
||||
|
||||
+ /* // Paper tart - moved up
|
||||
user.awardStat(Stats.ITEM_USED.get(this));
|
||||
// CraftBukkit start - moved up
|
||||
/*
|
||||
@@ -0,0 +0,0 @@ public class SnowballItem extends Item {
|
||||
itemstack.shrink(1);
|
||||
}
|
||||
*/
|
||||
+ // Paper end
|
||||
|
||||
return InteractionResultHolder.sidedSuccess(itemstack, world.isClientSide());
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/item/SplashPotionItem.java b/src/main/java/net/minecraft/world/item/SplashPotionItem.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/SplashPotionItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/SplashPotionItem.java
|
||||
@@ -0,0 +0,0 @@ public class SplashPotionItem extends ThrowablePotionItem {
|
||||
|
||||
@Override
|
||||
public InteractionResultHolder<ItemStack> use(Level world, Player user, InteractionHand hand) {
|
||||
+ // Paper start
|
||||
+ InteractionResultHolder<ItemStack> wrapper = super.use(world, user, hand);
|
||||
+ if (wrapper.getResult() != net.minecraft.world.InteractionResult.FAIL) {
|
||||
world.playSound((Player)null, user.getX(), user.getY(), user.getZ(), SoundEvents.SPLASH_POTION_THROW, SoundSource.PLAYERS, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F));
|
||||
- return super.use(world, user, hand);
|
||||
+ }
|
||||
+ return wrapper;
|
||||
+ // Paper end
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/item/ThrowablePotionItem.java b/src/main/java/net/minecraft/world/item/ThrowablePotionItem.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/ThrowablePotionItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/ThrowablePotionItem.java
|
||||
@@ -0,0 +0,0 @@ public class ThrowablePotionItem extends PotionItem {
|
||||
ThrownPotion thrownPotion = new ThrownPotion(world, user);
|
||||
thrownPotion.setItem(itemStack);
|
||||
thrownPotion.shootFromRotation(user, user.getXRot(), user.getYRot(), -20.0F, 0.5F, 1.0F);
|
||||
- world.addFreshEntity(thrownPotion);
|
||||
+ // Paper start
|
||||
+ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack), (org.bukkit.entity.Projectile) thrownPotion.getBukkitEntity());
|
||||
+ if (event.callEvent() && world.addFreshEntity(thrownPotion)) {
|
||||
+ if (event.shouldConsume() && !user.getAbilities().instabuild) {
|
||||
+ itemStack.shrink(1);
|
||||
+ } else if (user instanceof net.minecraft.server.level.ServerPlayer) {
|
||||
+ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
|
||||
+ }
|
||||
+
|
||||
+ user.awardStat(Stats.ITEM_USED.get(this));
|
||||
+ } else {
|
||||
+ if (user instanceof net.minecraft.server.level.ServerPlayer) {
|
||||
+ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
|
||||
+ }
|
||||
+ return InteractionResultHolder.fail(itemStack);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
+ /* // Paper start - moved up
|
||||
user.awardStat(Stats.ITEM_USED.get(this));
|
||||
if (!user.getAbilities().instabuild) {
|
||||
itemStack.shrink(1);
|
||||
}
|
||||
+ */ // Paper end
|
||||
|
||||
return InteractionResultHolder.sidedSuccess(itemStack, world.isClientSide());
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/item/TridentItem.java b/src/main/java/net/minecraft/world/item/TridentItem.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/TridentItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/TridentItem.java
|
||||
@@ -0,0 +0,0 @@ public class TridentItem extends Item implements Vanishable {
|
||||
}
|
||||
|
||||
// CraftBukkit start
|
||||
- if (!world.addFreshEntity(entitythrowntrident)) {
|
||||
+ // Paper start
|
||||
+ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) entityhuman.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(stack), (org.bukkit.entity.Projectile) entitythrowntrident.getBukkitEntity());
|
||||
+ if (!event.callEvent() || !world.addFreshEntity(entitythrowntrident)) {
|
||||
+ // Paper end
|
||||
if (entityhuman instanceof net.minecraft.server.level.ServerPlayer) {
|
||||
((net.minecraft.server.level.ServerPlayer) entityhuman).getBukkitEntity().updateInventory();
|
||||
}
|
||||
return;
|
||||
}
|
||||
-
|
||||
+ if (event.shouldConsume()) { // Paper
|
||||
stack.hurtAndBreak(1, entityhuman, (entityhuman1) -> {
|
||||
entityhuman1.broadcastBreakEvent(user.getUsedItemHand());
|
||||
});
|
||||
+ } // Paper
|
||||
entitythrowntrident.tridentItem = stack.copy(); // SPIGOT-4511 update since damage call moved
|
||||
// CraftBukkit end
|
||||
|
||||
world.playSound((Player) null, (Entity) entitythrowntrident, SoundEvents.TRIDENT_THROW, SoundSource.PLAYERS, 1.0F, 1.0F);
|
||||
- if (!entityhuman.getAbilities().instabuild) {
|
||||
+ if (event.shouldConsume() && !entityhuman.getAbilities().instabuild) { // Paper
|
||||
entityhuman.getInventory().removeItem(stack);
|
||||
}
|
||||
// CraftBukkit start - SPIGOT-5458 also need in this branch :(
|
28
patches/server/Remove-unnecessary-itemmeta-handling.patch
Normal file
28
patches/server/Remove-unnecessary-itemmeta-handling.patch
Normal file
|
@ -0,0 +1,28 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 22 Nov 2016 00:40:42 -0500
|
||||
Subject: [PATCH] Remove unnecessary itemmeta handling
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/network/FriendlyByteBuf.java b/src/main/java/net/minecraft/network/FriendlyByteBuf.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/network/FriendlyByteBuf.java
|
||||
+++ b/src/main/java/net/minecraft/network/FriendlyByteBuf.java
|
||||
@@ -0,0 +0,0 @@ public class FriendlyByteBuf extends ByteBuf {
|
||||
if (item.canBeDepleted() || item.shouldOverrideMultiplayerNbt()) {
|
||||
// Spigot start - filter
|
||||
stack = stack.copy();
|
||||
- CraftItemStack.setItemMeta(stack, CraftItemStack.getItemMeta(stack));
|
||||
+ // CraftItemStack.setItemMeta(stack, CraftItemStack.getItemMeta(stack)); // Paper - This is no longer with raw NBT being handled in metadata
|
||||
// Spigot end
|
||||
nbttagcompound = stack.getTag();
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class FriendlyByteBuf extends ByteBuf {
|
||||
|
||||
itemstack.setTag(this.readNbt());
|
||||
// CraftBukkit start
|
||||
- if (itemstack.getTag() != null) {
|
||||
+ if (false && itemstack.getTag() != null) { // Paper - This is no longer needed with raw NBT being handled in metadata
|
||||
CraftItemStack.setItemMeta(itemstack, CraftItemStack.getItemMeta(itemstack));
|
||||
}
|
||||
// CraftBukkit end
|
|
@ -0,0 +1,20 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sat, 18 Aug 2018 12:43:16 -0400
|
||||
Subject: [PATCH] Restore vanilla default mob-spawn-range and water animals
|
||||
limit
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
|
||||
+++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java
|
||||
@@ -0,0 +0,0 @@ public class SpigotWorldConfig
|
||||
public byte mobSpawnRange;
|
||||
private void mobSpawnRange()
|
||||
{
|
||||
- this.mobSpawnRange = (byte) this.getInt( "mob-spawn-range", 6 );
|
||||
+ this.mobSpawnRange = (byte) getInt( "mob-spawn-range", 8 ); // Paper - Vanilla
|
||||
this.log( "Mob Spawn Range: " + this.mobSpawnRange );
|
||||
}
|
||||
|
|
@ -61,7 +61,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
}
|
||||
+ // Paper start - send SoundEffect to everyone who can see fromEntity
|
||||
+ private static void sendSoundEffect(Player fromEntity, double x, double y, double z, SoundEvent soundEffect, SoundSource soundCategory, float volume, float pitch) {
|
||||
+ fromEntity.level.playSound(fromEntity, x, y, z, soundEffect, soundCategory, volume, pitch); // This will not send the effect to the entity himself
|
||||
+ fromEntity.level().playSound(fromEntity, x, y, z, soundEffect, soundCategory, volume, pitch); // This will not send the effect to the entity himself
|
||||
+ if (fromEntity instanceof ServerPlayer) {
|
||||
+ ((ServerPlayer) fromEntity).connection.send(new net.minecraft.network.protocol.game.ClientboundSoundPacket(net.minecraft.core.registries.BuiltInRegistries.SOUND_EVENT.wrapAsHolder(soundEffect), soundCategory, x, y, z, volume, pitch, fromEntity.random.nextLong()));
|
||||
+ }
|
||||
|
|
|
@ -14,7 +14,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
|
||||
+ // Paper start
|
||||
+ public Entity releaseLeftShoulderEntity() {
|
||||
+ Entity entity = this.spawnEntityFromShoulder0(this.getShoulderEntityLeft());
|
||||
+ Entity entity = this.respawnEntityOnShoulder0(this.getShoulderEntityLeft());
|
||||
+ if (entity != null) {
|
||||
+ this.setShoulderEntityLeft(new CompoundTag());
|
||||
+ }
|
||||
|
@ -22,7 +22,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ }
|
||||
+
|
||||
+ public Entity releaseRightShoulderEntity() {
|
||||
+ Entity entity = this.spawnEntityFromShoulder0(this.getShoulderEntityRight());
|
||||
+ Entity entity = this.respawnEntityOnShoulder0(this.getShoulderEntityRight());
|
||||
+ if (entity != null) {
|
||||
+ this.setShoulderEntityRight(new CompoundTag());
|
||||
+ }
|
||||
|
@ -32,7 +32,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+
|
||||
private boolean respawnEntityOnShoulder(CompoundTag nbttagcompound) { // CraftBukkit void->boolean
|
||||
- if (!this.level().isClientSide && !nbttagcompound.isEmpty()) {
|
||||
+ return this.spawnEntityFromShoulder0(nbttagcompound) != null;
|
||||
+ return this.respawnEntityOnShoulder0(nbttagcompound) != null;
|
||||
+ }
|
||||
+
|
||||
+ // Paper - return entity
|
||||
|
|
87
patches/server/SkeletonHorse-Additions.patch
Normal file
87
patches/server/SkeletonHorse-Additions.patch
Normal file
|
@ -0,0 +1,87 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Fri, 27 Jul 2018 22:36:31 -0500
|
||||
Subject: [PATCH] SkeletonHorse Additions
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/SkeletonTrapGoal.java b/src/main/java/net/minecraft/world/entity/animal/horse/SkeletonTrapGoal.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/horse/SkeletonTrapGoal.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/horse/SkeletonTrapGoal.java
|
||||
@@ -0,0 +0,0 @@ import net.minecraft.world.item.enchantment.EnchantmentHelper;
|
||||
public class SkeletonTrapGoal extends Goal {
|
||||
|
||||
private final SkeletonHorse horse;
|
||||
+ private java.util.List<org.bukkit.entity.HumanEntity> eligiblePlayers; // Paper
|
||||
|
||||
public SkeletonTrapGoal(SkeletonHorse skeletonHorse) {
|
||||
this.horse = skeletonHorse;
|
||||
@@ -0,0 +0,0 @@ public class SkeletonTrapGoal extends Goal {
|
||||
|
||||
@Override
|
||||
public boolean canUse() {
|
||||
- return this.horse.level().hasNearbyAlivePlayerThatAffectsSpawning(this.horse.getX(), this.horse.getY(), this.horse.getZ(), 10.0D); // Paper - Affects Spawning API
|
||||
+ return !(eligiblePlayers = this.horse.level().findNearbyBukkitPlayers(this.horse.getX(), this.horse.getY(), this.horse.getZ(), 10.0D, net.minecraft.world.entity.EntitySelector.PLAYER_AFFECTS_SPAWNING)).isEmpty(); // Paper - Affects Spawning API & SkeletonHorseTrapEvent
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
ServerLevel worldserver = (ServerLevel) this.horse.level();
|
||||
+ if (!new com.destroystokyo.paper.event.entity.SkeletonHorseTrapEvent((org.bukkit.entity.SkeletonHorse) this.horse.getBukkitEntity(), eligiblePlayers).callEvent()) return; // Paper
|
||||
DifficultyInstance difficultydamagescaler = worldserver.getCurrentDifficultyAt(this.horse.blockPosition());
|
||||
|
||||
this.horse.setTrap(false);
|
||||
diff --git a/src/main/java/net/minecraft/world/level/EntityGetter.java b/src/main/java/net/minecraft/world/level/EntityGetter.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/EntityGetter.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/EntityGetter.java
|
||||
@@ -0,0 +0,0 @@ public interface EntityGetter {
|
||||
return player;
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ default List<org.bukkit.entity.HumanEntity> findNearbyBukkitPlayers(double x, double y, double z, double radius, boolean notSpectator) {
|
||||
+ return findNearbyBukkitPlayers(x, y, z, radius, notSpectator ? EntitySelector.NO_SPECTATORS : net.minecraft.world.entity.EntitySelector.NO_CREATIVE_OR_SPECTATOR);
|
||||
+ }
|
||||
+
|
||||
+ default List<org.bukkit.entity.HumanEntity> findNearbyBukkitPlayers(double x, double y, double z, double radius, @Nullable Predicate<Entity> predicate) {
|
||||
+ com.google.common.collect.ImmutableList.Builder<org.bukkit.entity.HumanEntity> builder = com.google.common.collect.ImmutableList.builder();
|
||||
+
|
||||
+ for (Player human : this.players()) {
|
||||
+ if (predicate == null || predicate.test(human)) {
|
||||
+ double distanceSquared = human.distanceToSqr(x, y, z);
|
||||
+
|
||||
+ if (radius < 0.0D || distanceSquared < radius * radius) {
|
||||
+ builder.add(human.getBukkitEntity());
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return builder.build();
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Nullable
|
||||
default Player getNearestPlayer(Entity entity, double maxDistance) {
|
||||
return this.getNearestPlayer(entity.getX(), entity.getY(), entity.getZ(), maxDistance, false);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeletonHorse.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeletonHorse.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeletonHorse.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeletonHorse.java
|
||||
@@ -0,0 +0,0 @@ public class CraftSkeletonHorse extends CraftAbstractHorse implements SkeletonHo
|
||||
public void setTrapTime(int trapTime) {
|
||||
this.getHandle().trapTime = trapTime;
|
||||
}
|
||||
+
|
||||
+ // Paper start - replaced by above methods
|
||||
+ @Override
|
||||
+ public boolean isTrap() {
|
||||
+ return getHandle().isTrap();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setTrap(boolean trap) {
|
||||
+ getHandle().setTrap(trap);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
167
patches/server/Slime-Pathfinder-Events.patch
Normal file
167
patches/server/Slime-Pathfinder-Events.patch
Normal file
|
@ -0,0 +1,167 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Fri, 24 Aug 2018 08:18:42 -0500
|
||||
Subject: [PATCH] Slime Pathfinder Events
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/Slime.java b/src/main/java/net/minecraft/world/entity/monster/Slime.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Slime.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Slime.java
|
||||
@@ -0,0 +0,0 @@ import net.minecraft.world.level.ServerLevelAccessor;
|
||||
import net.minecraft.world.level.WorldGenLevel;
|
||||
import net.minecraft.world.level.levelgen.WorldgenRandom;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
+// Paper start
|
||||
+import com.destroystokyo.paper.event.entity.SlimeChangeDirectionEvent;
|
||||
+import com.destroystokyo.paper.event.entity.SlimeSwimEvent;
|
||||
+import com.destroystokyo.paper.event.entity.SlimeTargetLivingEntityEvent;
|
||||
+import com.destroystokyo.paper.event.entity.SlimeWanderEvent;
|
||||
+// Paper end
|
||||
// CraftBukkit start
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -0,0 +0,0 @@ public class Slime extends Mob implements Enemy {
|
||||
@Override
|
||||
public void addAdditionalSaveData(CompoundTag nbt) {
|
||||
super.addAdditionalSaveData(nbt);
|
||||
+ nbt.putBoolean("Paper.canWander", this.canWander); // Paper
|
||||
nbt.putInt("Size", this.getSize() - 1);
|
||||
nbt.putBoolean("wasOnGround", this.wasOnGround);
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class Slime extends Mob implements Enemy {
|
||||
public void readAdditionalSaveData(CompoundTag nbt) {
|
||||
this.setSize(nbt.getInt("Size") + 1, false);
|
||||
super.readAdditionalSaveData(nbt);
|
||||
+ // Paper start - check exists before loading or this will be loaded as false
|
||||
+ if (nbt.contains("Paper.canWander")) {
|
||||
+ this.canWander = nbt.getBoolean("Paper.canWander");
|
||||
+ }
|
||||
+ // Paper end
|
||||
this.wasOnGround = nbt.getBoolean("wasOnGround");
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ public class Slime extends Mob implements Enemy {
|
||||
|
||||
@Override
|
||||
public boolean canUse() {
|
||||
- return (this.slime.isInWater() || this.slime.isInLava()) && this.slime.getMoveControl() instanceof Slime.SlimeMoveControl;
|
||||
+ return (this.slime.isInWater() || this.slime.isInLava()) && this.slime.getMoveControl() instanceof Slime.SlimeMoveControl && this.slime.canWander && new SlimeSwimEvent((org.bukkit.entity.Slime) this.slime.getBukkitEntity()).callEvent(); // Paper
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -0,0 +0,0 @@ public class Slime extends Mob implements Enemy {
|
||||
public boolean canUse() {
|
||||
LivingEntity entityliving = this.slime.getTarget();
|
||||
|
||||
- return entityliving == null ? false : (!this.slime.canAttack(entityliving) ? false : this.slime.getMoveControl() instanceof Slime.SlimeMoveControl);
|
||||
+ // Paper start
|
||||
+ if (entityliving == null || !entityliving.isAlive()) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ if (!this.slime.canAttack(entityliving)) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ return this.slime.getMoveControl() instanceof Slime.SlimeMoveControl && this.slime.canWander && new SlimeTargetLivingEntityEvent((org.bukkit.entity.Slime) this.slime.getBukkitEntity(), (org.bukkit.entity.LivingEntity) entityliving.getBukkitEntity()).callEvent();
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -0,0 +0,0 @@ public class Slime extends Mob implements Enemy {
|
||||
public boolean canContinueToUse() {
|
||||
LivingEntity entityliving = this.slime.getTarget();
|
||||
|
||||
- return entityliving == null ? false : (!this.slime.canAttack(entityliving) ? false : --this.growTiredTimer > 0);
|
||||
+ // Paper start
|
||||
+ if (entityliving == null || !entityliving.isAlive()) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ if (!this.slime.canAttack(entityliving)) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ return --this.growTiredTimer > 0 && this.slime.canWander && new SlimeTargetLivingEntityEvent((org.bukkit.entity.Slime) this.slime.getBukkitEntity(), (org.bukkit.entity.LivingEntity) entityliving.getBukkitEntity()).callEvent();
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -0,0 +0,0 @@ public class Slime extends Mob implements Enemy {
|
||||
}
|
||||
|
||||
}
|
||||
+
|
||||
+ // Paper start - clear timer and target when goal resets
|
||||
+ public void stop() {
|
||||
+ this.growTiredTimer = 0;
|
||||
+ this.slime.setTarget(null);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
private static class SlimeRandomDirectionGoal extends Goal {
|
||||
@@ -0,0 +0,0 @@ public class Slime extends Mob implements Enemy {
|
||||
|
||||
@Override
|
||||
public boolean canUse() {
|
||||
- return this.slime.getTarget() == null && (this.slime.onGround() || this.slime.isInWater() || this.slime.isInLava() || this.slime.hasEffect(MobEffects.LEVITATION)) && this.slime.getMoveControl() instanceof Slime.SlimeMoveControl;
|
||||
+ return this.slime.getTarget() == null && (this.slime.onGround() || this.slime.isInWater() || this.slime.isInLava() || this.slime.hasEffect(MobEffects.LEVITATION)) && this.slime.getMoveControl() instanceof Slime.SlimeMoveControl && this.slime.canWander; // Paper - add canWander
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -0,0 +0,0 @@ public class Slime extends Mob implements Enemy {
|
||||
if (--this.nextRandomizeTime <= 0) {
|
||||
this.nextRandomizeTime = this.adjustedTickDelay(40 + this.slime.getRandom().nextInt(60));
|
||||
this.chosenDegrees = (float) this.slime.getRandom().nextInt(360);
|
||||
+ // Paper start
|
||||
+ SlimeChangeDirectionEvent event = new SlimeChangeDirectionEvent((org.bukkit.entity.Slime) this.slime.getBukkitEntity(), this.chosenDegrees);
|
||||
+ if (!this.slime.canWander || !event.callEvent()) return;
|
||||
+ this.chosenDegrees = event.getNewYaw();
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
MoveControl controllermove = this.slime.getMoveControl();
|
||||
@@ -0,0 +0,0 @@ public class Slime extends Mob implements Enemy {
|
||||
|
||||
@Override
|
||||
public boolean canUse() {
|
||||
- return !this.slime.isPassenger();
|
||||
+ return !this.slime.isPassenger() && this.slime.canWander && new SlimeWanderEvent((org.bukkit.entity.Slime) this.slime.getBukkitEntity()).callEvent(); // Paper
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -0,0 +0,0 @@ public class Slime extends Mob implements Enemy {
|
||||
|
||||
}
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ private boolean canWander = true;
|
||||
+ public boolean canWander() {
|
||||
+ return canWander;
|
||||
+ }
|
||||
+
|
||||
+ public void setWander(boolean canWander) {
|
||||
+ this.canWander = canWander;
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftSlime.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftSlime.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftSlime.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftSlime.java
|
||||
@@ -0,0 +0,0 @@ public class CraftSlime extends CraftMob implements Slime, CraftEnemy {
|
||||
public EntityType getType() {
|
||||
return EntityType.SLIME;
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public boolean canWander() {
|
||||
+ return getHandle().canWander();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setWander(boolean canWander) {
|
||||
+ getHandle().setWander(canWander);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
|
@ -12,7 +12,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
|
||||
boolean flag2 = flag && this.fallDistance > 0.0F && !this.onGround() && !this.onClimbable() && !this.isInWater() && !this.hasEffect(MobEffects.BLINDNESS) && !this.isPassenger() && target instanceof LivingEntity;
|
||||
|
||||
+ flag2 = flag2 && !level.paperConfig().entities.behavior.disablePlayerCrits; // Paper
|
||||
+ flag2 = flag2 && !this.level().paperConfig().entities.behavior.disablePlayerCrits; // Paper
|
||||
flag2 = flag2 && !this.isSprinting();
|
||||
if (flag2) {
|
||||
f *= 1.5F;
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
|
||||
Date: Thu, 12 Aug 2021 04:46:41 -0700
|
||||
Subject: [PATCH] Use AsyncAppender to keep logging IO off main thread
|
||||
|
||||
|
||||
diff --git a/build.gradle.kts b/build.gradle.kts
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/build.gradle.kts
|
||||
+++ b/build.gradle.kts
|
||||
@@ -0,0 +0,0 @@ dependencies {
|
||||
implementation("commons-lang:commons-lang:2.6")
|
||||
runtimeOnly("org.xerial:sqlite-jdbc:3.42.0.0")
|
||||
runtimeOnly("com.mysql:mysql-connector-j:8.0.33")
|
||||
+ runtimeOnly("com.lmax:disruptor:3.4.4") // Paper
|
||||
|
||||
runtimeOnly("org.apache.maven:maven-resolver-provider:3.9.2")
|
||||
runtimeOnly("org.apache.maven.resolver:maven-resolver-connector-basic:1.9.10")
|
||||
diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/resources/log4j2.xml
|
||||
+++ b/src/main/resources/log4j2.xml
|
||||
@@ -0,0 +0,0 @@
|
||||
</Policies>
|
||||
<DefaultRolloverStrategy max="1000"/>
|
||||
</RollingRandomAccessFile>
|
||||
+ <Async name="Async">
|
||||
+ <AppenderRef ref="File"/>
|
||||
+ <AppenderRef ref="TerminalConsole" level="info"/>
|
||||
+ <AppenderRef ref="ServerGuiConsole" level="info"/>
|
||||
+ </Async>
|
||||
</Appenders>
|
||||
<Loggers>
|
||||
<Root level="info">
|
||||
<filters>
|
||||
<MarkerFilter marker="NETWORK_PACKETS" onMatch="DENY" onMismatch="NEUTRAL" />
|
||||
</filters>
|
||||
- <AppenderRef ref="File"/>
|
||||
- <AppenderRef ref="TerminalConsole" level="info"/>
|
||||
- <AppenderRef ref="ServerGuiConsole" level="info"/>
|
||||
+ <AppenderRef ref="Async"/>
|
||||
</Root>
|
||||
</Loggers>
|
||||
</Configuration>
|
140
patches/server/Use-ConcurrentHashMap-in-JsonList.patch
Normal file
140
patches/server/Use-ConcurrentHashMap-in-JsonList.patch
Normal file
|
@ -0,0 +1,140 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: egg82 <eggys82@gmail.com>
|
||||
Date: Tue, 7 Aug 2018 01:24:23 -0600
|
||||
Subject: [PATCH] Use ConcurrentHashMap in JsonList
|
||||
|
||||
This is specifically aimed at fixing #471
|
||||
|
||||
Using a ConcurrentHashMap because thread safety
|
||||
The performance benefit of Map over ConcurrentMap is negligabe at best in this scenaio, as most operations will be get and not add or remove
|
||||
Even without considering the use-case the benefits are still negligable
|
||||
|
||||
Original ideas for the system included an expiration policy and/or handler
|
||||
The simpler solution was to use a computeIfPresent in the get method
|
||||
This will simultaneously have an O(1) lookup time and automatically expire any values
|
||||
Since the get method (nor other similar methods) don't seem to have a critical need to flush the map to disk at any of these points further processing is simply wasteful
|
||||
Meaning the original function expired values unrelated to the current value without actually having any explicit need to
|
||||
|
||||
The h method was heavily modified to be much more efficient in its processing
|
||||
Also instead of being called on every get, it's now called just before a save
|
||||
This will eliminate stale values being flushed to disk
|
||||
|
||||
Modified isEmpty to use the isEmpty() method instead of the slightly confusing size() < 1
|
||||
The point of this is readability, but does have a side-benefit of a small microptimization
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
@@ -0,0 +0,0 @@ public abstract class PlayerList {
|
||||
} else if (!this.isWhiteListed(gameprofile, event)) { // Paper
|
||||
//ichatmutablecomponent = Component.translatable("multiplayer.disconnect.not_whitelisted"); // Paper
|
||||
//event.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(org.spigotmc.SpigotConfig.whitelistMessage)); // Spigot // Paper - Adventure - moved to isWhitelisted
|
||||
- } else if (this.getIpBans().isBanned(socketaddress) && !this.getIpBans().get(socketaddress).hasExpired()) {
|
||||
+ } else if (this.getIpBans().isBanned(socketaddress) && getIpBans().get(socketaddress) != null && !this.getIpBans().get(socketaddress).hasExpired()) { // Paper - fix NPE with temp ip bans
|
||||
IpBanListEntry ipbanentry = this.ipBans.get(socketaddress);
|
||||
|
||||
ichatmutablecomponent = Component.translatable("multiplayer.disconnect.banned_ip.reason", ipbanentry.getReason());
|
||||
diff --git a/src/main/java/net/minecraft/server/players/StoredUserList.java b/src/main/java/net/minecraft/server/players/StoredUserList.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/StoredUserList.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/StoredUserList.java
|
||||
@@ -0,0 +0,0 @@ import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
+import java.lang.reflect.ParameterizedType; // Paper
|
||||
+import java.lang.reflect.Type; // Paper
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
@@ -0,0 +0,0 @@ public abstract class StoredUserList<K, V extends StoredUserEntry<K>> {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private static final Gson GSON = (new GsonBuilder()).setPrettyPrinting().create();
|
||||
private final File file;
|
||||
- private final Map<String, V> map = Maps.newHashMap();
|
||||
+ // Paper - replace HashMap is ConcurrentHashMap
|
||||
+ private final Map<String, V> map = Maps.newConcurrentMap();
|
||||
+ private boolean e = true;
|
||||
+ private static final ParameterizedType f = new ParameterizedType() {
|
||||
+ public Type[] getActualTypeArguments() {
|
||||
+ return new Type[]{StoredUserEntry.class};
|
||||
+ }
|
||||
+
|
||||
+ public Type getRawType() {
|
||||
+ return List.class;
|
||||
+ }
|
||||
+
|
||||
+ public Type getOwnerType() {
|
||||
+ return null;
|
||||
+ }
|
||||
+ };
|
||||
|
||||
public StoredUserList(File file) {
|
||||
this.file = file;
|
||||
@@ -0,0 +0,0 @@ public abstract class StoredUserList<K, V extends StoredUserEntry<K>> {
|
||||
|
||||
@Nullable
|
||||
public V get(K key) {
|
||||
- this.removeExpired();
|
||||
- return (V) this.map.get(this.getKeyForUser(key)); // CraftBukkit - fix decompile error
|
||||
+ // Paper start
|
||||
+ // this.g();
|
||||
+ // return (V) this.d.get(this.a(k0)); // CraftBukkit - fix decompile error
|
||||
+ return (V) this.map.computeIfPresent(this.getKeyForUser(key), (k, v) -> {
|
||||
+ return v.hasExpired() ? null : v;
|
||||
+ });
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
public void remove(K key) {
|
||||
@@ -0,0 +0,0 @@ public abstract class StoredUserList<K, V extends StoredUserEntry<K>> {
|
||||
// CraftBukkit end
|
||||
|
||||
public boolean isEmpty() {
|
||||
- return this.map.size() < 1;
|
||||
+ // return this.d.size() < 1; // Paper
|
||||
+ return this.map.isEmpty(); // Paper - readability is the goal. As an aside, isEmpty() uses only sumCount() and a comparison. size() uses sumCount(), casts, and boolean logic
|
||||
}
|
||||
|
||||
protected String getKeyForUser(K profile) {
|
||||
@@ -0,0 +0,0 @@ public abstract class StoredUserList<K, V extends StoredUserEntry<K>> {
|
||||
}
|
||||
|
||||
private void removeExpired() {
|
||||
- List<K> list = Lists.newArrayList();
|
||||
- Iterator iterator = this.map.values().iterator();
|
||||
+ /*List<K> list = Lists.newArrayList();
|
||||
+ Iterator iterator = this.d.values().iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
V v0 = (V) iterator.next(); // CraftBukkit - decompile error
|
||||
|
||||
if (v0.hasExpired()) {
|
||||
- list.add(v0.getUser());
|
||||
+ list.add(v0.getKey());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ public abstract class StoredUserList<K, V extends StoredUserEntry<K>> {
|
||||
while (iterator.hasNext()) {
|
||||
K k0 = (K) iterator.next(); // CraftBukkit - decompile error
|
||||
|
||||
- this.map.remove(this.getKeyForUser(k0));
|
||||
- }
|
||||
+ this.d.remove(this.a(k0));
|
||||
+ }*/
|
||||
|
||||
+ this.map.values().removeIf(StoredUserEntry::hasExpired);
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
protected abstract StoredUserEntry<K> createEntry(JsonObject json);
|
||||
@@ -0,0 +0,0 @@ public abstract class StoredUserList<K, V extends StoredUserEntry<K>> {
|
||||
}
|
||||
|
||||
public void save() throws IOException {
|
||||
+ this.removeExpired(); // Paper - remove expired values before saving
|
||||
JsonArray jsonarray = new JsonArray();
|
||||
Stream<JsonObject> stream = this.map.values().stream().map((jsonlistentry) -> { // CraftBukkit - decompile error
|
||||
JsonObject jsonobject = new JsonObject();
|
39
patches/server/Use-a-Queue-for-Queueing-Commands.patch
Normal file
39
patches/server/Use-a-Queue-for-Queueing-Commands.patch
Normal file
|
@ -0,0 +1,39 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sun, 12 Aug 2018 02:33:39 -0400
|
||||
Subject: [PATCH] Use a Queue for Queueing Commands
|
||||
|
||||
Lists are bad as Queues mmmkay.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
@@ -0,0 +0,0 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
|
||||
static final Logger LOGGER = LogUtils.getLogger();
|
||||
private static final int CONVERSION_RETRY_DELAY_MS = 5000;
|
||||
private static final int CONVERSION_RETRIES = 2;
|
||||
- private final List<ConsoleInput> consoleInput = Collections.synchronizedList(Lists.newArrayList());
|
||||
+ private final java.util.Queue<ConsoleInput> serverCommandQueue = new java.util.concurrent.ConcurrentLinkedQueue<>(); // Paper - use a proper queuemmands
|
||||
@Nullable
|
||||
private QueryThreadGs4 queryThreadGs4;
|
||||
public final RconConsoleSource rconConsoleSource;
|
||||
@@ -0,0 +0,0 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
|
||||
}
|
||||
|
||||
public void handleConsoleInput(String command, CommandSourceStack commandSource) {
|
||||
- this.consoleInput.add(new ConsoleInput(command, commandSource));
|
||||
+ this.serverCommandQueue.add(new ConsoleInput(command, commandSource)); // Paper - use proper queue
|
||||
}
|
||||
|
||||
public void handleConsoleInputs() {
|
||||
MinecraftTimings.serverCommandTimer.startTiming(); // Spigot
|
||||
- while (!this.consoleInput.isEmpty()) {
|
||||
- ConsoleInput servercommand = (ConsoleInput) this.consoleInput.remove(0);
|
||||
+ // Paper start - use proper queue
|
||||
+ ConsoleInput servercommand;
|
||||
+ while ((servercommand = this.serverCommandQueue.poll()) != null) {
|
||||
+ // Paper end
|
||||
|
||||
// CraftBukkit start - ServerCommand for preprocessing
|
||||
ServerCommandEvent event = new ServerCommandEvent(console, servercommand.msg);
|
109
patches/server/Vanished-players-don-t-have-rights.patch
Normal file
109
patches/server/Vanished-players-don-t-have-rights.patch
Normal file
|
@ -0,0 +1,109 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Hugo Manrique <hugmanrique@gmail.com>
|
||||
Date: Mon, 23 Jul 2018 14:22:26 +0200
|
||||
Subject: [PATCH] Vanished players don't have rights
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Projectile extends Entity implements TraceableEntity {
|
||||
} else {
|
||||
Entity entity1 = this.getOwner();
|
||||
|
||||
+ // Paper start - Cancel hit for vanished players
|
||||
+ if (entity1 instanceof net.minecraft.server.level.ServerPlayer && entity instanceof net.minecraft.server.level.ServerPlayer) {
|
||||
+ org.bukkit.entity.Player collided = (org.bukkit.entity.Player) entity.getBukkitEntity();
|
||||
+ org.bukkit.entity.Player shooter = (org.bukkit.entity.Player) entity1.getBukkitEntity();
|
||||
+ if (!shooter.canSee(collided)) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
return entity1 == null || this.leftOwner || !entity1.isPassengerOfSameVehicle(entity);
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/item/BlockItem.java b/src/main/java/net/minecraft/world/item/BlockItem.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/BlockItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/BlockItem.java
|
||||
@@ -0,0 +0,0 @@ public class BlockItem extends Item {
|
||||
Player entityhuman = context.getPlayer();
|
||||
CollisionContext voxelshapecollision = entityhuman == null ? CollisionContext.empty() : CollisionContext.of(entityhuman);
|
||||
// CraftBukkit start - store default return
|
||||
- boolean defaultReturn = (!this.mustSurvive() || state.canSurvive(context.getLevel(), context.getClickedPos())) && context.getLevel().isUnobstructed(state, context.getClickedPos(), voxelshapecollision);
|
||||
+ Level world = context.getLevel(); // Paper
|
||||
+ boolean defaultReturn = (!this.mustSurvive() || state.canSurvive(context.getLevel(), context.getClickedPos())) && world.checkEntityCollision(state, entityhuman, voxelshapecollision, context.getClickedPos(), true); // Paper
|
||||
org.bukkit.entity.Player player = (context.getPlayer() instanceof ServerPlayer) ? (org.bukkit.entity.Player) context.getPlayer().getBukkitEntity() : null;
|
||||
|
||||
BlockCanBuildEvent event = new BlockCanBuildEvent(CraftBlock.at(context.getLevel(), context.getClickedPos()), player, CraftBlockData.fromData(state), defaultReturn);
|
||||
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/Level.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
this.tileLimiter = new org.spigotmc.TickLimiter(spigotConfig.tileMaxTickTime);
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ // ret true if no collision
|
||||
+ public final boolean checkEntityCollision(BlockState data, Entity source, net.minecraft.world.phys.shapes.CollisionContext voxelshapedcollision,
|
||||
+ BlockPos position, boolean checkCanSee) {
|
||||
+ // Copied from IWorldReader#a(IBlockData, BlockPosition, VoxelShapeCollision) & EntityAccess#a(Entity, VoxelShape)
|
||||
+ net.minecraft.world.phys.shapes.VoxelShape voxelshape = data.getCollisionShape(this, position, voxelshapedcollision);
|
||||
+ if (voxelshape.isEmpty()) {
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ voxelshape = voxelshape.move((double) position.getX(), (double) position.getY(), (double) position.getZ());
|
||||
+ if (voxelshape.isEmpty()) {
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ List<Entity> entities = this.getEntities(null, voxelshape.bounds());
|
||||
+ for (int i = 0, len = entities.size(); i < len; ++i) {
|
||||
+ Entity entity = entities.get(i);
|
||||
+
|
||||
+ if (checkCanSee && source instanceof net.minecraft.server.level.ServerPlayer && entity instanceof net.minecraft.server.level.ServerPlayer
|
||||
+ && !((net.minecraft.server.level.ServerPlayer) source).getBukkitEntity().canSee(((net.minecraft.server.level.ServerPlayer) entity).getBukkitEntity())) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ // !entity1.dead && entity1.i && (entity == null || !entity1.x(entity));
|
||||
+ // elide the last check since vanilla calls with entity = null
|
||||
+ // only we care about the source for the canSee check
|
||||
+ if (entity.isRemoved() || !entity.blocksBuilding) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (net.minecraft.world.phys.shapes.Shapes.joinIsNotEmpty(voxelshape, net.minecraft.world.phys.shapes.Shapes.create(entity.getBoundingBox()), net.minecraft.world.phys.shapes.BooleanOp.AND)) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return true;
|
||||
+ }
|
||||
+ // Paper end
|
||||
@Override
|
||||
public boolean isClientSide() {
|
||||
return this.isClientSide;
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
@@ -0,0 +0,0 @@ public class CraftEventFactory {
|
||||
Projectile projectile = (Projectile) entity.getBukkitEntity();
|
||||
org.bukkit.entity.Entity collided = position.getEntity().getBukkitEntity();
|
||||
com.destroystokyo.paper.event.entity.ProjectileCollideEvent event = new com.destroystokyo.paper.event.entity.ProjectileCollideEvent(projectile, collided);
|
||||
+
|
||||
+ if (projectile.getShooter() instanceof Player && collided instanceof Player) {
|
||||
+ if (!((Player) projectile.getShooter()).canSee((Player) collided)) {
|
||||
+ event.setCancelled(true);
|
||||
+ return event;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
return event;
|
||||
}
|
20
patches/server/add-more-information-to-Entity.toString.patch
Normal file
20
patches/server/add-more-information-to-Entity.toString.patch
Normal file
|
@ -0,0 +1,20 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Thu, 19 Jul 2018 01:13:28 -0400
|
||||
Subject: [PATCH] add more information to Entity.toString()
|
||||
|
||||
UUID, ticks lived, valid, dead
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
|
||||
public String toString() {
|
||||
String s = this.level() == null ? "~NULL~" : this.level().toString();
|
||||
|
||||
- return this.removalReason != null ? String.format(Locale.ROOT, "%s['%s'/%d, l='%s', x=%.2f, y=%.2f, z=%.2f, removed=%s]", this.getClass().getSimpleName(), this.getName().getString(), this.id, s, this.getX(), this.getY(), this.getZ(), this.removalReason) : String.format(Locale.ROOT, "%s['%s'/%d, l='%s', x=%.2f, y=%.2f, z=%.2f]", this.getClass().getSimpleName(), this.getName().getString(), this.id, s, this.getX(), this.getY(), this.getZ());
|
||||
+ return this.removalReason != null ? String.format(Locale.ROOT, "%s['%s'/%d, uuid='%s', l='%s', x=%.2f, y=%.2f, z=%.2f, cpos=%s, tl=%d, v=%b, removed=%s]", this.getClass().getSimpleName(), this.getName().getString(), this.id, this.uuid, s, this.getX(), this.getY(), this.getZ(), this.chunkPosition(), this.tickCount, this.valid, this.removalReason) : String.format(Locale.ROOT, "%s['%s'/%d, uuid='%s', l='%s', x=%.2f, y=%.2f, z=%.2f, cpos=%s, tl=%d, v=%b]", this.getClass().getSimpleName(), this.getName().getString(), this.id, this.uuid, s, this.getX(), this.getY(), this.getZ(), this.chunkPosition(), this.tickCount, this.valid);
|
||||
}
|
||||
|
||||
public boolean isInvulnerableTo(DamageSource damageSource) {
|
Loading…
Add table
Add a link
Reference in a new issue