mirror of
https://github.com/PaperMC/Paper.git
synced 2025-08-06 23:22:10 -07:00
279
This commit is contained in:
@@ -1,55 +0,0 @@
|
||||
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 block 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(this.x, this.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<? super 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;
|
@@ -1,75 +0,0 @@
|
||||
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
|
||||
|
||||
|
||||
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 {
|
||||
// CraftBukkit start
|
||||
private boolean addEntity(Entity entity, CreatureSpawnEvent.SpawnReason spawnReason) {
|
||||
org.spigotmc.AsyncCatcher.catchOp("entity add"); // Spigot
|
||||
+ // Paper start - extra debug info
|
||||
+ if (entity.valid) {
|
||||
+ MinecraftServer.LOGGER.error("Attempted Double World add on {}", entity, new Throwable());
|
||||
+ return true;
|
||||
+ }
|
||||
+ // Paper end - extra debug info
|
||||
if (entity.isRemoved()) {
|
||||
// WorldServer.LOGGER.warn("Tried to add entity {} but it was marked as removed already", EntityTypes.getKey(entity.getType())); // CraftBukkit
|
||||
return false;
|
||||
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 SyncedDataHolder, Nameable, EntityAccess
|
||||
|
||||
private CraftEntity bukkitEntity;
|
||||
|
||||
+ public @org.jetbrains.annotations.Nullable net.minecraft.server.level.ChunkMap.TrackedEntity tracker; // Paper
|
||||
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/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) {
|
||||
+ final T old = this.byUuid.get(entity.getUUID());
|
||||
+ if (old instanceof net.minecraft.world.entity.Entity oldCast && oldCast.getId() != entity.getId() && oldCast.valid) {
|
||||
+ LOGGER.error("Overwrote an existing entity {} with {}", oldCast, entity);
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - extra debug info
|
||||
} else {
|
||||
this.byUuid.put(uUID, entity);
|
||||
this.byId.put(entity.getId(), entity);
|
@@ -1,159 +0,0 @@
|
||||
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( this.recentTps, 20 );
|
||||
// Paper start - further improve server tick loop
|
||||
long tickSection = Util.getNanos();
|
||||
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
|
||||
this.paperConfigurations.initializeGlobalConfiguration(this.registryAccess());
|
||||
this.paperConfigurations.initializeWorldDefaultsConfiguration(this.registryAccess());
|
||||
// Paper end - initialize global and world-defaults configuration
|
||||
+ org.spigotmc.WatchdogThread.doStart(org.spigotmc.SpigotConfig.timeoutTime, org.spigotmc.SpigotConfig.restartOnCrash); // Paper - start watchdog thread
|
||||
io.papermc.paper.command.PaperCommands.registerCommands(this); // Paper - setup /paper command
|
||||
com.destroystokyo.paper.Metrics.PaperMetrics.startMetrics(); // Paper - start metrics
|
||||
com.destroystokyo.paper.VersionHistoryManager.INSTANCE.getClass(); // Paper - 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.POSTWORLD);
|
||||
if (io.papermc.paper.plugin.PluginInitializerManager.instance().pluginRemapper != null) io.papermc.paper.plugin.PluginInitializerManager.instance().pluginRemapper.pluginsEnabled(); // Paper - Remap plugins
|
||||
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( SpigotConfig.timeoutTime, SpigotConfig.restartOnCrash );
|
||||
+ // WatchdogThread.doStart( SpigotConfig.timeoutTime, SpigotConfig.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 )
|
||||
{
|
||||
this.interrupt();
|
@@ -1,108 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Sat, 22 Sep 2018 00:33:08 -0500
|
||||
Subject: [PATCH] Add LivingEntity#getTargetEntity
|
||||
|
||||
|
||||
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 @@ import net.minecraft.world.level.storage.loot.LootTable;
|
||||
import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets;
|
||||
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
+import net.minecraft.world.phys.EntityHitResult;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraft.world.scores.PlayerTeam;
|
||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
return this.level().clip(raytrace);
|
||||
}
|
||||
|
||||
+ public @Nullable EntityHitResult getTargetEntity(int maxDistance) {
|
||||
+ if (maxDistance < 1 || maxDistance > 120) {
|
||||
+ throw new IllegalArgumentException("maxDistance must be between 1-120");
|
||||
+ }
|
||||
+
|
||||
+ Vec3 start = this.getEyePosition(1.0F);
|
||||
+ Vec3 direction = this.getLookAngle();
|
||||
+ Vec3 end = start.add(direction.x * maxDistance, direction.y * maxDistance, direction.z * maxDistance);
|
||||
+
|
||||
+ List<Entity> entityList = this.level().getEntities(this, getBoundingBox().expandTowards(direction.x * maxDistance, direction.y * maxDistance, direction.z * maxDistance).inflate(1.0D, 1.0D, 1.0D), EntitySelector.NO_SPECTATORS.and(Entity::isPickable));
|
||||
+
|
||||
+ double distance = 0.0D;
|
||||
+ EntityHitResult result = null;
|
||||
+
|
||||
+ for (Entity entity : entityList) {
|
||||
+ final double inflationAmount = (double) entity.getPickRadius();
|
||||
+ AABB aabb = entity.getBoundingBox().inflate(inflationAmount, inflationAmount, inflationAmount);
|
||||
+ Optional<Vec3> rayTraceResult = aabb.clip(start, end);
|
||||
+
|
||||
+ if (rayTraceResult.isPresent()) {
|
||||
+ Vec3 rayTrace = rayTraceResult.get();
|
||||
+ double distanceTo = start.distanceToSqr(rayTrace);
|
||||
+ if (distanceTo < distance || distance == 0.0D) {
|
||||
+ result = new EntityHitResult(entity, rayTrace);
|
||||
+ distance = distanceTo;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return result;
|
||||
+ }
|
||||
+
|
||||
public int shieldBlockingDelay = this.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 @@
|
||||
package org.bukkit.craftbukkit.entity;
|
||||
|
||||
+import com.destroystokyo.paper.entity.TargetEntityInfo;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.Sets;
|
||||
import java.util.ArrayList;
|
||||
@@ -0,0 +0,0 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
+
|
||||
+ public Entity getTargetEntity(int maxDistance, boolean ignoreBlocks) {
|
||||
+ net.minecraft.world.phys.EntityHitResult rayTrace = rayTraceEntity(maxDistance, ignoreBlocks);
|
||||
+ return rayTrace == null ? null : rayTrace.getEntity().getBukkitEntity();
|
||||
+ }
|
||||
+
|
||||
+ public TargetEntityInfo getTargetEntityInfo(int maxDistance, boolean ignoreBlocks) {
|
||||
+ net.minecraft.world.phys.EntityHitResult rayTrace = rayTraceEntity(maxDistance, ignoreBlocks);
|
||||
+ return rayTrace == null ? null : new TargetEntityInfo(rayTrace.getEntity().getBukkitEntity(), new org.bukkit.util.Vector(rayTrace.getLocation().x, rayTrace.getLocation().y, rayTrace.getLocation().z));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public RayTraceResult rayTraceEntities(int maxDistance, boolean ignoreBlocks) {
|
||||
+ net.minecraft.world.phys.EntityHitResult rayTrace = this.rayTraceEntity(maxDistance, ignoreBlocks);
|
||||
+ return rayTrace == null ? null : new org.bukkit.util.RayTraceResult(org.bukkit.craftbukkit.util.CraftVector.toBukkit(rayTrace.getLocation()), rayTrace.getEntity().getBukkitEntity());
|
||||
+ }
|
||||
+
|
||||
+ public net.minecraft.world.phys.EntityHitResult rayTraceEntity(int maxDistance, boolean ignoreBlocks) {
|
||||
+ net.minecraft.world.phys.EntityHitResult rayTrace = getHandle().getTargetEntity(maxDistance);
|
||||
+ if (rayTrace == null) {
|
||||
+ return null;
|
||||
+ }
|
||||
+ if (!ignoreBlocks) {
|
||||
+ net.minecraft.world.phys.HitResult rayTraceBlocks = getHandle().getRayTrace(maxDistance, net.minecraft.world.level.ClipContext.Fluid.NONE);
|
||||
+ if (rayTraceBlocks != null) {
|
||||
+ net.minecraft.world.phys.Vec3 eye = getHandle().getEyePosition(1.0F);
|
||||
+ if (eye.distanceToSqr(rayTraceBlocks.getLocation()) <= eye.distanceToSqr(rayTrace.getLocation())) {
|
||||
+ return null;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ return rayTrace;
|
||||
+ }
|
||||
// Paper end
|
||||
|
||||
@Override
|
@@ -1,60 +0,0 @@
|
||||
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 - CreeperIgniteEvent
|
||||
+ 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 - CreeperIgniteEvent
|
||||
}
|
||||
|
||||
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 String toString() {
|
||||
return "CraftCreeper";
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public void setIgnited(boolean ignited) {
|
||||
+ getHandle().setIgnited(ignited);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isIgnited() {
|
||||
+ return getHandle().isIgnited();
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
@@ -1,92 +0,0 @@
|
||||
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 entitysize.scale(1.0F + 0.15F * (float) i);
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Nullable
|
||||
+ java.util.UUID spawningEntity;
|
||||
+
|
||||
+ @Nullable
|
||||
+ public java.util.UUID getSpawningEntity() {
|
||||
+ return this.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 @@ public class PhantomSpawner implements CustomSpawner {
|
||||
int k = 1 + randomsource.nextInt(difficultydamagescaler.getDifficulty().getId() + 1);
|
||||
|
||||
for (int l = 0; l < k; ++l) {
|
||||
+ // Paper start - PhantomPreSpawnEvent
|
||||
+ com.destroystokyo.paper.event.entity.PhantomPreSpawnEvent event = new com.destroystokyo.paper.event.entity.PhantomPreSpawnEvent(io.papermc.paper.util.MCUtil.toLocation(world, blockposition1), entityplayer.getBukkitEntity(), org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NATURAL);
|
||||
+ if (!event.callEvent()) {
|
||||
+ if (event.shouldAbortSpawn()) {
|
||||
+ break;
|
||||
+ }
|
||||
+ continue;
|
||||
+ }
|
||||
+ // Paper end - PhantomPreSpawnEvent
|
||||
Phantom entityphantom = (Phantom) EntityType.PHANTOM.create(world);
|
||||
|
||||
if (entityphantom != null) {
|
||||
+ entityphantom.setSpawningEntity(entityplayer.getUUID()); // Paper - PhantomPreSpawnEvent
|
||||
entityphantom.moveTo(blockposition1, 0.0F, 0.0F);
|
||||
groupdataentity = entityphantom.finalizeSpawn(world, difficultydamagescaler, MobSpawnType.NATURAL, groupdataentity);
|
||||
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 String toString() {
|
||||
return "CraftPhantom";
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public java.util.UUID getSpawningEntity() {
|
||||
+ return getHandle().getSpawningEntity();
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
@@ -1,83 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
Date: Sun, 7 Oct 2018 12:05:28 -0700
|
||||
Subject: [PATCH] Add PlayerConnectionCloseEvent
|
||||
|
||||
This event is invoked when a player has disconnected. It is guaranteed that,
|
||||
if the server is in online-mode, that the provided uuid and username have been
|
||||
validated.
|
||||
|
||||
The event is invoked for players who have not yet logged into the world, whereas
|
||||
PlayerQuitEvent is only invoked on players who have logged into the world.
|
||||
|
||||
The event is invoked for players who have already logged into the world,
|
||||
although whether or not the player exists in the world at the time of
|
||||
firing is undefined. (That is, whether the plugin can retrieve a Player object
|
||||
using the event parameters is undefined). However, it is guaranteed that this
|
||||
event is invoked AFTER PlayerQuitEvent, if the player has already logged into
|
||||
the world.
|
||||
|
||||
This event is guaranteed to never fire unless AsyncPlayerPreLoginEvent has
|
||||
been called beforehand, and this event may not be called in parallel with
|
||||
AsyncPlayerPreLoginEvent for the same connection.
|
||||
|
||||
Cancelling the AsyncPlayerPreLoginEvent guarantees the corresponding
|
||||
PlayerConnectionCloseEvent is never called.
|
||||
|
||||
The event may be invoked asynchronously or synchronously. As it stands,
|
||||
it is never invoked asynchronously. However, plugins should check
|
||||
Event#isAsynchronous to be future-proof.
|
||||
|
||||
On purpose, the deprecated PlayerPreLoginEvent event is left out of the
|
||||
API spec for this event. Plugins should not be using that event, and
|
||||
how PlayerPreLoginEvent interacts with PlayerConnectionCloseEvent
|
||||
is undefined.
|
||||
|
||||
== AT ==
|
||||
public net.minecraft.server.network.ServerLoginPacketListenerImpl$State
|
||||
public net.minecraft.server.network.ServerLoginPacketListenerImpl state
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/network/Connection.java b/src/main/java/net/minecraft/network/Connection.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/network/Connection.java
|
||||
+++ b/src/main/java/net/minecraft/network/Connection.java
|
||||
@@ -0,0 +0,0 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
packetlistener1.onDisconnect(ichatbasecomponent);
|
||||
}
|
||||
this.pendingActions.clear(); // Free up packet queue.
|
||||
+ // Paper start - Add PlayerConnectionCloseEvent
|
||||
+ final PacketListener packetListener = this.getPacketListener();
|
||||
+ if (packetListener instanceof net.minecraft.server.network.ServerCommonPacketListenerImpl commonPacketListener) {
|
||||
+ /* Player was logged in, either game listener or configuration listener */
|
||||
+ final com.mojang.authlib.GameProfile profile = commonPacketListener.getOwner();
|
||||
+ new com.destroystokyo.paper.event.player.PlayerConnectionCloseEvent(profile.getId(),
|
||||
+ profile.getName(), ((InetSocketAddress) this.address).getAddress(), false).callEvent();
|
||||
+ } else if (packetListener instanceof net.minecraft.server.network.ServerLoginPacketListenerImpl loginListener) {
|
||||
+ /* Player is login stage */
|
||||
+ switch (loginListener.state) {
|
||||
+ case VERIFYING:
|
||||
+ case WAITING_FOR_DUPE_DISCONNECT:
|
||||
+ case PROTOCOL_SWITCHING:
|
||||
+ case ACCEPTED:
|
||||
+ final com.mojang.authlib.GameProfile profile = loginListener.authenticatedProfile; /* Should be non-null at this stage */
|
||||
+ new com.destroystokyo.paper.event.player.PlayerConnectionCloseEvent(profile.getId(), profile.getName(),
|
||||
+ ((InetSocketAddress) this.address).getAddress(), false).callEvent();
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - Add PlayerConnectionCloseEvent
|
||||
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
@@ -0,0 +0,0 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener,
|
||||
@Nullable
|
||||
String requestedUsername;
|
||||
@Nullable
|
||||
- private GameProfile authenticatedProfile;
|
||||
+ public GameProfile authenticatedProfile; // Paper - public
|
||||
private final String serverId;
|
||||
private final boolean transferred;
|
||||
private ServerPlayer player; // CraftBukkit
|
@@ -1,117 +0,0 @@
|
||||
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 = CraftBlock.at(this.level(), blockposition);
|
||||
+ if (!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.EXPLOSION, explosionSource.getIndirectSourceEntity().getBukkitEntity()).callEvent())
|
||||
+ continue;
|
||||
+ // Paper end - TNTPrimeEvent
|
||||
nmsBlock.wasExploded(this.level(), blockposition, this.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 = org.bukkit.craftbukkit.block.CraftBlock.at(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 - TNTPrimeEvent
|
||||
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 {
|
||||
protected 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 = org.bukkit.craftbukkit.block.CraftBlock.at(world, pos);
|
||||
+ if (!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.REDSTONE, null).callEvent()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end - TNTPrimeEvent
|
||||
TntBlock.explode(world, pos);
|
||||
world.removeBlock(pos, false);
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class TntBlock extends Block {
|
||||
@Override
|
||||
protected 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 = org.bukkit.craftbukkit.block.CraftBlock.at(world, pos);
|
||||
+ if (!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.REDSTONE, null).callEvent()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end - TNTPrimeEvent
|
||||
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 = org.bukkit.craftbukkit.block.CraftBlock.at(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 - TNTPrimeEvent
|
||||
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 ItemInteractionResult.CONSUME;
|
||||
}
|
||||
// CraftBukkit end
|
||||
+ // Paper start - TNTPrimeEvent
|
||||
+ org.bukkit.block.Block tntBlock = org.bukkit.craftbukkit.block.CraftBlock.at(world, pos);
|
||||
+ if (!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.ITEM, player.getBukkitEntity()).callEvent()) {
|
||||
+ return ItemInteractionResult.FAIL;
|
||||
+ }
|
||||
+ // Paper end - TNTPrimeEvent
|
||||
TntBlock.explode(world, pos, player);
|
||||
world.setBlock(pos, Blocks.AIR.defaultBlockState(), 11);
|
||||
Item item = stack.getItem();
|
||||
@@ -0,0 +0,0 @@ public class TntBlock extends Block {
|
||||
return;
|
||||
}
|
||||
// CraftBukkit end
|
||||
+ // Paper start - TNTPrimeEvent
|
||||
+ org.bukkit.block.Block tntBlock = org.bukkit.craftbukkit.block.CraftBlock.at(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 - TNTPrimeEvent
|
||||
TntBlock.explode(world, blockposition, entity instanceof LivingEntity ? (LivingEntity) entity : null);
|
||||
world.removeBlock(blockposition, false);
|
||||
}
|
@@ -1,21 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Fri, 22 Jun 2018 10:38:31 -0500
|
||||
Subject: [PATCH] Add config to disable ender dragon legacy check
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java b/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java
|
||||
@@ -0,0 +0,0 @@ public class EndDragonFight {
|
||||
this.ticksSinceLastPlayerScan = 21;
|
||||
this.skipArenaLoadedCheck = false;
|
||||
this.needsStateScanning = true;
|
||||
+ // Paper start - Add config to disable ender dragon legacy check
|
||||
+ this.needsStateScanning = world.paperConfig().entities.spawning.scanForLegacyEnderDragon;
|
||||
+ if (!this.needsStateScanning) this.dragonKilled = true;
|
||||
+ // Paper end - Add config to disable ender dragon legacy check
|
||||
this.level = world;
|
||||
this.origin = origin;
|
||||
this.validPlayer = EntitySelector.ENTITY_STILL_ALIVE.and(EntitySelector.withinDistance((double) origin.getX(), (double) (128 + origin.getY()), (double) origin.getZ(), 192.0D));
|
@@ -1,320 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Brokkonaut <hannos17@gmx.de>
|
||||
Date: Mon, 18 Jun 2018 15:46:23 +0200
|
||||
Subject: [PATCH] Add entity knockback events
|
||||
|
||||
- EntityKnockbackEvent
|
||||
- EntityPushedByEntityAttackEvent
|
||||
- EntityKnockbackByEntityEvent
|
||||
|
||||
Co-authored-by: aerulion <aerulion@gmail.com>
|
||||
Co-authored-by: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
|
||||
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 SyncedDataHolder, Nameable, EntityAccess
|
||||
}
|
||||
}
|
||||
|
||||
- public void push(double deltaX, double deltaY, double deltaZ) {
|
||||
- this.setDeltaMovement(this.getDeltaMovement().add(deltaX, deltaY, deltaZ));
|
||||
+ public final void push(double deltaX, double deltaY, double deltaZ) { // Paper - override the added overload below
|
||||
+ // Paper start - Add EntityKnockbackByEntityEvent and EntityPushedByEntityAttackEvent
|
||||
+ this.push(deltaX, deltaY, deltaZ, null);
|
||||
+ }
|
||||
+
|
||||
+ public void push(double deltaX, double deltaY, double deltaZ, @org.jetbrains.annotations.Nullable Entity pushingEntity) {
|
||||
+ org.bukkit.util.Vector delta = new org.bukkit.util.Vector(deltaX, deltaY, deltaZ);
|
||||
+ if (pushingEntity != null) {
|
||||
+ io.papermc.paper.event.entity.EntityPushedByEntityAttackEvent event = new io.papermc.paper.event.entity.EntityPushedByEntityAttackEvent(this.getBukkitEntity(), io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.PUSH, pushingEntity.getBukkitEntity(), delta);
|
||||
+ if (!event.callEvent()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ delta = event.getKnockback();
|
||||
+ }
|
||||
+ this.setDeltaMovement(this.getDeltaMovement().add(delta.getX(), delta.getY(), delta.getZ()));
|
||||
+ // Paper end - Add EntityKnockbackByEntityEvent and EntityPushedByEntityAttackEvent
|
||||
this.hasImpulse = true;
|
||||
}
|
||||
|
||||
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 {
|
||||
d0 = (Math.random() - Math.random()) * 0.01D;
|
||||
}
|
||||
|
||||
- this.knockback(0.4000000059604645D, d0, d1, entity1, entity1 == null ? EntityKnockbackEvent.KnockbackCause.DAMAGE : EntityKnockbackEvent.KnockbackCause.ENTITY_ATTACK); // CraftBukkit
|
||||
+ this.knockback(0.4000000059604645D, d0, d1, entity1, entity1 == null ? io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.DAMAGE : io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.ENTITY_ATTACK); // CraftBukkit // Paper - knockback events
|
||||
if (!flag) {
|
||||
this.indicateDamage(d0, d1);
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
}
|
||||
|
||||
protected void blockedByShield(LivingEntity target) {
|
||||
- target.knockback(0.5D, target.getX() - this.getX(), target.getZ() - this.getZ(), null, EntityKnockbackEvent.KnockbackCause.SHIELD_BLOCK); // CraftBukkit
|
||||
+ target.knockback(0.5D, target.getX() - this.getX(), target.getZ() - this.getZ(), this, io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.SHIELD_BLOCK); // CraftBukkit // Paper - fix attacker & knockback events
|
||||
}
|
||||
|
||||
private boolean checkTotemDeathProtection(DamageSource source) {
|
||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
|
||||
public void knockback(double strength, double x, double z) {
|
||||
// CraftBukkit start - EntityKnockbackEvent
|
||||
- this.knockback(strength, x, z, null, EntityKnockbackEvent.KnockbackCause.UNKNOWN);
|
||||
+ this.knockback(strength, x, z, null, io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.UNKNOWN); // Paper - knockback events
|
||||
}
|
||||
|
||||
- public void knockback(double d0, double d1, double d2, Entity attacker, EntityKnockbackEvent.KnockbackCause cause) {
|
||||
+ public void knockback(double d0, double d1, double d2, @Nullable Entity attacker, io.papermc.paper.event.entity.EntityKnockbackEvent.Cause cause) { // Paper - knockback events
|
||||
d0 *= 1.0D - this.getAttributeValue(Attributes.KNOCKBACK_RESISTANCE);
|
||||
if (true || d0 > 0.0D) { // CraftBukkit - Call event even when force is 0
|
||||
//this.hasImpulse = true; // CraftBukkit - Move down
|
||||
Vec3 vec3d = this.getDeltaMovement();
|
||||
Vec3 vec3d1 = (new Vec3(d1, 0.0D, d2)).normalize().scale(d0);
|
||||
|
||||
- EntityKnockbackEvent event = CraftEventFactory.callEntityKnockbackEvent((org.bukkit.craftbukkit.entity.CraftLivingEntity) this.getBukkitEntity(), attacker, cause, d0, vec3d1, vec3d.x / 2.0D - vec3d1.x, this.onGround() ? Math.min(0.4D, vec3d.y / 2.0D + d0) : vec3d.y, vec3d.z / 2.0D - vec3d1.z);
|
||||
+ // Paper start - knockback events
|
||||
+ Vec3 finalVelocity = new Vec3(vec3d.x / 2.0D - vec3d1.x, this.onGround() ? Math.min(0.4D, vec3d.y / 2.0D + d0) : vec3d.y, vec3d.z / 2.0D - vec3d1.z);
|
||||
+ Vec3 diff = finalVelocity.subtract(vec3d);
|
||||
+ io.papermc.paper.event.entity.EntityKnockbackEvent event = CraftEventFactory.callEntityKnockbackEvent((org.bukkit.craftbukkit.entity.CraftLivingEntity) this.getBukkitEntity(), attacker, cause, d0, diff);
|
||||
+ // Paper end - knockback events
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.hasImpulse = true;
|
||||
- this.setDeltaMovement(event.getFinalKnockback().getX(), event.getFinalKnockback().getY(), event.getFinalKnockback().getZ());
|
||||
+ this.setDeltaMovement(vec3d.add(event.getKnockback().getX(), event.getKnockback().getY(), event.getKnockback().getZ())); // Paper - knockback events
|
||||
// CraftBukkit end
|
||||
}
|
||||
}
|
||||
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 EquipmentUser, Targeti
|
||||
|
||||
if (flag) {
|
||||
if (f1 > 0.0F && target instanceof LivingEntity) {
|
||||
- ((LivingEntity) target).knockback((double) (f1 * 0.5F), (double) Mth.sin(this.getYRot() * 0.017453292F), (double) (-Mth.cos(this.getYRot())) * 0.017453292F, this, org.bukkit.event.entity.EntityKnockbackEvent.KnockbackCause.ENTITY_ATTACK); // CraftBukkit
|
||||
+ ((LivingEntity) target).knockback((double) (f1 * 0.5F), (double) Mth.sin(this.getYRot() * 0.017453292F), (double) (-Mth.cos(this.getYRot())) * 0.017453292F, this, io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.ENTITY_ATTACK); // CraftBukkit // Paper - knockback events
|
||||
this.setDeltaMovement(this.getDeltaMovement().multiply(0.6D, 1.0D, 0.6D));
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/RamTarget.java b/src/main/java/net/minecraft/world/entity/ai/behavior/RamTarget.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ai/behavior/RamTarget.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ai/behavior/RamTarget.java
|
||||
@@ -0,0 +0,0 @@ public class RamTarget extends Behavior<Goat> {
|
||||
float f = 0.25F * (float)(i - j);
|
||||
float g = Mth.clamp(entity.getSpeed() * 1.65F, 0.2F, 3.0F) + f;
|
||||
float h = livingEntity.isDamageSourceBlocked(world.damageSources().mobAttack(entity)) ? 0.5F : 1.0F;
|
||||
- livingEntity.knockback((double)(h * g) * this.getKnockbackForce.applyAsDouble(entity), this.ramDirection.x(), this.ramDirection.z());
|
||||
+ livingEntity.knockback(h * g * this.getKnockbackForce.applyAsDouble(entity), this.ramDirection.x(), this.ramDirection.z(), entity, io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.ENTITY_ATTACK); // Paper - Add EntityKnockbackByEntityEvent and EntityPushedByEntityAttackEvent
|
||||
this.finishRam(world, entity);
|
||||
world.playSound(null, entity, this.getImpactSound.apply(entity), SoundSource.NEUTRAL, 1.0F, 1.0F);
|
||||
} else if (this.hasRammedHornBreakingBlock(world, entity)) {
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/warden/SonicBoom.java b/src/main/java/net/minecraft/world/entity/ai/behavior/warden/SonicBoom.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ai/behavior/warden/SonicBoom.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ai/behavior/warden/SonicBoom.java
|
||||
@@ -0,0 +0,0 @@ public class SonicBoom extends Behavior<Warden> {
|
||||
if (target.hurt(world.damageSources().sonicBoom(entity), 10.0F)) {
|
||||
double d = 0.5 * (1.0 - target.getAttributeValue(Attributes.KNOCKBACK_RESISTANCE));
|
||||
double e = 2.5 * (1.0 - target.getAttributeValue(Attributes.KNOCKBACK_RESISTANCE));
|
||||
- target.push(vec33.x() * e, vec33.y() * d, vec33.z() * e);
|
||||
+ target.push(vec33.x() * e, vec33.y() * d, vec33.z() * e, entity); // Paper - Add EntityKnockbackByEntityEvent and EntityPushedByEntityAttackEvent
|
||||
}
|
||||
});
|
||||
}
|
||||
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 {
|
||||
double d3 = entity.getZ() - d1;
|
||||
double d4 = Math.max(d2 * d2 + d3 * d3, 0.1D);
|
||||
|
||||
- entity.push(d2 / d4 * 4.0D, 0.20000000298023224D, d3 / d4 * 4.0D);
|
||||
+ entity.push(d2 / d4 * 4.0D, 0.20000000298023224D, d3 / d4 * 4.0D, this); // Paper - Add EntityKnockbackByEntityEvent and EntityPushedByEntityAttackEvent
|
||||
if (!this.phaseManager.getCurrentPhase().isSitting() && ((LivingEntity) entity).getLastHurtByMobTimestamp() < entity.tickCount - 2) {
|
||||
entity.hurt(this.damageSources().mobAttack(this), 5.0F);
|
||||
this.doEnchantDamageEffects(this, entity);
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/decoration/HangingEntity.java b/src/main/java/net/minecraft/world/entity/decoration/HangingEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/decoration/HangingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/decoration/HangingEntity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class HangingEntity extends Entity {
|
||||
}
|
||||
|
||||
@Override
|
||||
- public void push(double deltaX, double deltaY, double deltaZ) {
|
||||
+ public void push(double deltaX, double deltaY, double deltaZ, @org.jetbrains.annotations.Nullable Entity pushingEntity) { // Paper - add push source entity param
|
||||
if (false && !this.level().isClientSide && !this.isRemoved() && deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ > 0.0D) { // CraftBukkit - not needed
|
||||
this.kill();
|
||||
this.dropItem((Entity) null);
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java b/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/decoration/ItemFrame.java
|
||||
@@ -0,0 +0,0 @@ public class ItemFrame extends HangingEntity {
|
||||
}
|
||||
|
||||
@Override
|
||||
- public void push(double deltaX, double deltaY, double deltaZ) {
|
||||
+ public void push(double deltaX, double deltaY, double deltaZ, @org.jetbrains.annotations.Nullable Entity pushingEntity) { // Paper - add push source entity param
|
||||
if (!this.fixed) {
|
||||
- super.push(deltaX, deltaY, deltaZ);
|
||||
+ super.push(deltaX, deltaY, deltaZ, pushingEntity); // Paper - add push source entity param
|
||||
}
|
||||
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/Ravager.java b/src/main/java/net/minecraft/world/entity/monster/Ravager.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Ravager.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Ravager.java
|
||||
@@ -0,0 +0,0 @@ public class Ravager extends Raider {
|
||||
double d1 = entity.getZ() - this.getZ();
|
||||
double d2 = Math.max(d0 * d0 + d1 * d1, 0.001D);
|
||||
|
||||
- entity.push(d0 / d2 * 4.0D, 0.2D, d1 / d2 * 4.0D);
|
||||
+ entity.push(d0 / d2 * 4.0D, 0.2D, d1 / d2 * 4.0D, this); // Paper - Add EntityKnockbackByEntityEvent and EntityPushedByEntityAttackEvent
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/hoglin/HoglinBase.java b/src/main/java/net/minecraft/world/entity/monster/hoglin/HoglinBase.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/hoglin/HoglinBase.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/hoglin/HoglinBase.java
|
||||
@@ -0,0 +0,0 @@ public interface HoglinBase {
|
||||
double j = f * (double)(attacker.level().random.nextFloat() * 0.5F + 0.2F);
|
||||
Vec3 vec3 = new Vec3(g, 0.0, h).normalize().scale(j).yRot(i);
|
||||
double k = f * (double)attacker.level().random.nextFloat() * 0.5;
|
||||
- target.push(vec3.x, k, vec3.z);
|
||||
+ target.push(vec3.x, k, vec3.z, attacker); // Paper - Add EntityKnockbackByEntityEvent and EntityPushedByEntityAttackEvent
|
||||
target.hurtMarked = true;
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Player extends LivingEntity {
|
||||
if (flag5) {
|
||||
if (i > 0) {
|
||||
if (target instanceof LivingEntity) {
|
||||
- ((LivingEntity) target).knockback((double) ((float) i * 0.5F), (double) Mth.sin(this.getYRot() * 0.017453292F), (double) (-Mth.cos(this.getYRot() * 0.017453292F)), this, EntityKnockbackEvent.KnockbackCause.ENTITY_ATTACK); // CraftBukkit
|
||||
+ ((LivingEntity) target).knockback((double) ((float) i * 0.5F), (double) Mth.sin(this.getYRot() * 0.017453292F), (double) (-Mth.cos(this.getYRot() * 0.017453292F)), this, io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.ENTITY_ATTACK); // CraftBukkit // Paper - knockback events
|
||||
} else {
|
||||
- target.push((double) (-Mth.sin(this.getYRot() * 0.017453292F) * (float) i * 0.5F), 0.1D, (double) (Mth.cos(this.getYRot() * 0.017453292F) * (float) i * 0.5F));
|
||||
+ target.push((double) (-Mth.sin(this.getYRot() * 0.017453292F) * (float) i * 0.5F), 0.1D, (double) (Mth.cos(this.getYRot() * 0.017453292F) * (float) i * 0.5F), this); // Paper - Add EntityKnockbackByEntityEvent and EntityPushedByEntityAttackEvent
|
||||
}
|
||||
|
||||
this.setDeltaMovement(this.getDeltaMovement().multiply(0.6D, 1.0D, 0.6D));
|
||||
@@ -0,0 +0,0 @@ public abstract class Player extends LivingEntity {
|
||||
if (entityliving != this && entityliving != target && !this.isAlliedTo((Entity) entityliving) && (!(entityliving instanceof ArmorStand) || !((ArmorStand) entityliving).isMarker()) && this.distanceToSqr((Entity) entityliving) < 9.0D) {
|
||||
// CraftBukkit start - Only apply knockback if the damage hits
|
||||
if (entityliving.hurt(this.damageSources().playerAttack(this).sweep(), f4)) {
|
||||
- entityliving.knockback(0.4000000059604645D, (double) Mth.sin(this.getYRot() * 0.017453292F), (double) (-Mth.cos(this.getYRot() * 0.017453292F)), this, EntityKnockbackEvent.KnockbackCause.SWEEP_ATTACK); // CraftBukkit
|
||||
+ entityliving.knockback(0.4000000059604645D, (double) Mth.sin(this.getYRot() * 0.017453292F), (double) (-Mth.cos(this.getYRot() * 0.017453292F)), this, io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.SWEEP_ATTACK); // CraftBukkit // Paper - knockback events
|
||||
}
|
||||
// CraftBukkit end
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
|
||||
@@ -0,0 +0,0 @@ public abstract class AbstractArrow extends Projectile {
|
||||
Vec3 vec3d = this.getDeltaMovement().multiply(1.0D, 0.0D, 1.0D).normalize().scale((double) this.knockback * 0.6D * d0);
|
||||
|
||||
if (vec3d.lengthSqr() > 0.0D) {
|
||||
- entityliving.push(vec3d.x, 0.1D, vec3d.z);
|
||||
+ entityliving.push(vec3d.x, 0.1D, vec3d.z, this); // Paper - pass causing entity for knockback events
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/projectile/windcharge/AbstractWindCharge.java b/src/main/java/net/minecraft/world/entity/projectile/windcharge/AbstractWindCharge.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/windcharge/AbstractWindCharge.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/windcharge/AbstractWindCharge.java
|
||||
@@ -0,0 +0,0 @@ public abstract class AbstractWindCharge extends AbstractHurtingProjectile imple
|
||||
}
|
||||
|
||||
@Override
|
||||
- public void push(double deltaX, double deltaY, double deltaZ) {}
|
||||
+ public void push(double deltaX, double deltaY, double deltaZ, @org.jetbrains.annotations.Nullable Entity pushingEntity) {} // Paper - Add EntityKnockbackByEntityEvent and EntityPushedByEntityAttackEvent
|
||||
|
||||
public abstract void explode();
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/Explosion.java b/src/main/java/net/minecraft/world/level/Explosion.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/Explosion.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Explosion.java
|
||||
@@ -0,0 +0,0 @@ public class Explosion {
|
||||
|
||||
// CraftBukkit start - Call EntityKnockbackEvent
|
||||
if (entity instanceof LivingEntity) {
|
||||
- Vec3 result = entity.getDeltaMovement().add(vec3d1);
|
||||
- org.bukkit.event.entity.EntityKnockbackEvent event = CraftEventFactory.callEntityKnockbackEvent((org.bukkit.craftbukkit.entity.CraftLivingEntity) entity.getBukkitEntity(), this.source, org.bukkit.event.entity.EntityKnockbackEvent.KnockbackCause.EXPLOSION, d13, vec3d1, result.x, result.y, result.z);
|
||||
-
|
||||
- // SPIGOT-7640: Need to subtract entity movement from the event result,
|
||||
- // since the code below (the setDeltaMovement call as well as the hitPlayers map)
|
||||
- // want the vector to be the relative velocity will the event provides the absolute velocity
|
||||
- vec3d1 = (event.isCancelled()) ? Vec3.ZERO : new Vec3(event.getFinalKnockback().getX(), event.getFinalKnockback().getY(), event.getFinalKnockback().getZ()).subtract(entity.getDeltaMovement());
|
||||
+ // Paper start - knockback events
|
||||
+ io.papermc.paper.event.entity.EntityKnockbackEvent event = CraftEventFactory.callEntityKnockbackEvent((org.bukkit.craftbukkit.entity.CraftLivingEntity) entity.getBukkitEntity(), this.damageSource.getEntity() != null ? this.damageSource.getEntity() : this.source, io.papermc.paper.event.entity.EntityKnockbackEvent.Cause.EXPLOSION, d13, vec3d1);
|
||||
+ vec3d1 = event.isCancelled() ? Vec3.ZERO : org.bukkit.craftbukkit.util.CraftVector.toNMS(event.getKnockback());
|
||||
+ // Paper end - knockback events
|
||||
}
|
||||
// CraftBukkit end
|
||||
entity.setDeltaMovement(entity.getDeltaMovement().add(vec3d1));
|
||||
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 {
|
||||
return event;
|
||||
}
|
||||
|
||||
- public static EntityKnockbackEvent callEntityKnockbackEvent(CraftLivingEntity entity, Entity attacker, EntityKnockbackEvent.KnockbackCause cause, double force, Vec3 raw, double x, double y, double z) {
|
||||
- Vector bukkitRaw = new Vector(-raw.x, raw.y, -raw.z); // Due to how the knockback calculation works, we need to invert x and z.
|
||||
-
|
||||
- EntityKnockbackEvent event;
|
||||
+ // Paper start - replace knockback events
|
||||
+ public static io.papermc.paper.event.entity.EntityKnockbackEvent callEntityKnockbackEvent(CraftLivingEntity entity, Entity attacker, io.papermc.paper.event.entity.EntityKnockbackEvent.Cause cause, double force, Vec3 knockback) {
|
||||
+ Vector apiKnockback = CraftVector.toBukkit(knockback);
|
||||
+
|
||||
+ final Vector currentVelocity = entity.getVelocity();
|
||||
+ final Vector legacyFinalKnockback = currentVelocity.clone().add(apiKnockback);
|
||||
+ final org.bukkit.event.entity.EntityKnockbackEvent.KnockbackCause legacyCause = org.bukkit.event.entity.EntityKnockbackEvent.KnockbackCause.valueOf(cause.name());
|
||||
+ EntityKnockbackEvent legacyEvent;
|
||||
if (attacker != null) {
|
||||
- event = new EntityKnockbackByEntityEvent(entity, attacker.getBukkitEntity(), cause, force, new Vector(-raw.x, raw.y, -raw.z), new Vector(x, y, z));
|
||||
+ legacyEvent = new EntityKnockbackByEntityEvent(entity, attacker.getBukkitEntity(), legacyCause, force, apiKnockback, legacyFinalKnockback);
|
||||
} else {
|
||||
- event = new EntityKnockbackEvent(entity, cause, force, new Vector(-raw.x, raw.y, -raw.z), new Vector(x, y, z));
|
||||
+ legacyEvent = new EntityKnockbackEvent(entity, legacyCause, force, apiKnockback, legacyFinalKnockback);
|
||||
}
|
||||
+ legacyEvent.callEvent();
|
||||
|
||||
- Bukkit.getPluginManager().callEvent(event);
|
||||
+ final io.papermc.paper.event.entity.EntityKnockbackEvent event;
|
||||
+ apiKnockback = legacyEvent.getFinalKnockback().subtract(currentVelocity);
|
||||
+ if (attacker != null) {
|
||||
+ event = new com.destroystokyo.paper.event.entity.EntityKnockbackByEntityEvent(entity, attacker.getBukkitEntity(), cause, (float) force, apiKnockback);
|
||||
+ } else {
|
||||
+ event = new io.papermc.paper.event.entity.EntityKnockbackEvent(entity, cause, apiKnockback);
|
||||
+ }
|
||||
+ event.setCancelled(legacyEvent.isCancelled());
|
||||
+ event.callEvent();
|
||||
return event;
|
||||
}
|
||||
+ // Paper end - replace knockback events
|
||||
|
||||
public static void callEntityRemoveEvent(Entity entity, EntityRemoveEvent.Cause cause) {
|
||||
if (entity instanceof ServerPlayer) {
|
@@ -1,101 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Fri, 12 Oct 2018 14:10:46 -0500
|
||||
Subject: [PATCH] Add more Witch API
|
||||
|
||||
== AT ==
|
||||
public net.minecraft.world.entity.monster.Witch usingTime
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/Witch.java b/src/main/java/net/minecraft/world/entity/monster/Witch.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Witch.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Witch.java
|
||||
@@ -0,0 +0,0 @@ public class Witch extends Raider implements RangedAttackMob {
|
||||
}
|
||||
|
||||
if (holder != null) {
|
||||
- // Paper start
|
||||
- ItemStack potion = PotionContents.createItemStack(Items.POTION, holder);
|
||||
- potion = org.bukkit.craftbukkit.event.CraftEventFactory.handleWitchReadyPotionEvent(this, potion);
|
||||
- this.setItemSlot(EquipmentSlot.MAINHAND, potion);
|
||||
- // Paper end
|
||||
- this.usingTime = this.getMainHandItem().getUseDuration();
|
||||
- this.setUsingItem(true);
|
||||
- if (!this.isSilent()) {
|
||||
- this.level().playSound((Player) null, this.getX(), this.getY(), this.getZ(), SoundEvents.WITCH_DRINK, this.getSoundSource(), 1.0F, 0.8F + this.random.nextFloat() * 0.4F);
|
||||
- }
|
||||
-
|
||||
- AttributeInstance attributemodifiable = this.getAttribute(Attributes.MOVEMENT_SPEED);
|
||||
-
|
||||
- attributemodifiable.removeModifier(Witch.SPEED_MODIFIER_DRINKING.id());
|
||||
- attributemodifiable.addTransientModifier(Witch.SPEED_MODIFIER_DRINKING);
|
||||
+ this.setDrinkingPotion(PotionContents.createItemStack(Items.POTION, holder)); // Paper - logic moved into setDrinkingPotion, copy exact impl into the method and then comment out
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ public class Witch extends Raider implements RangedAttackMob {
|
||||
super.aiStep();
|
||||
}
|
||||
|
||||
+ // Paper start - moved to its own method
|
||||
+ public void setDrinkingPotion(ItemStack potion) {
|
||||
+ potion = org.bukkit.craftbukkit.event.CraftEventFactory.handleWitchReadyPotionEvent(this, potion);
|
||||
+ this.setItemSlot(EquipmentSlot.MAINHAND, potion);
|
||||
+ this.usingTime = this.getMainHandItem().getUseDuration();
|
||||
+ this.setUsingItem(true);
|
||||
+ if (!this.isSilent()) {
|
||||
+ this.level().playSound((Player) null, this.getX(), this.getY(), this.getZ(), SoundEvents.WITCH_DRINK, this.getSoundSource(), 1.0F, 0.8F + this.random.nextFloat() * 0.4F);
|
||||
+ }
|
||||
+
|
||||
+ AttributeInstance attributemodifiable = this.getAttribute(Attributes.MOVEMENT_SPEED);
|
||||
+
|
||||
+ attributemodifiable.removeModifier(Witch.SPEED_MODIFIER_DRINKING.id());
|
||||
+ attributemodifiable.addTransientModifier(Witch.SPEED_MODIFIER_DRINKING);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public SoundEvent getCelebrateSound() {
|
||||
return SoundEvents.WITCH_CELEBRATE;
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftWitch.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftWitch.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftWitch.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftWitch.java
|
||||
@@ -0,0 +0,0 @@ package org.bukkit.craftbukkit.entity;
|
||||
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.Witch;
|
||||
+// Paper start
|
||||
+import com.destroystokyo.paper.entity.CraftRangedEntity;
|
||||
+import com.google.common.base.Preconditions;
|
||||
+import org.bukkit.Material;
|
||||
+import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
||||
+import org.bukkit.inventory.ItemStack;
|
||||
+// Paper end
|
||||
|
||||
public class CraftWitch extends CraftRaider implements Witch, com.destroystokyo.paper.entity.CraftRangedEntity<net.minecraft.world.entity.monster.Witch> { // Paper
|
||||
public CraftWitch(CraftServer server, net.minecraft.world.entity.monster.Witch entity) {
|
||||
@@ -0,0 +0,0 @@ public class CraftWitch extends CraftRaider implements Witch, com.destroystokyo.
|
||||
public boolean isDrinkingPotion() {
|
||||
return this.getHandle().isDrinkingPotion();
|
||||
}
|
||||
+ // Paper start
|
||||
+ public int getPotionUseTimeLeft() {
|
||||
+ return getHandle().usingTime;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setPotionUseTimeLeft(int ticks) {
|
||||
+ getHandle().usingTime = ticks;
|
||||
+ }
|
||||
+
|
||||
+ public ItemStack getDrinkingPotion() {
|
||||
+ return CraftItemStack.asCraftMirror(getHandle().getMainHandItem());
|
||||
+ }
|
||||
+
|
||||
+ public void setDrinkingPotion(ItemStack potion) {
|
||||
+ Preconditions.checkArgument(potion == null || potion.getType().isEmpty() || potion.getType() == Material.POTION, "must be potion, air, or null");
|
||||
+ getHandle().setDrinkingPotion(CraftItemStack.asNMSCopy(potion));
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
@@ -1,117 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Sun, 7 Oct 2018 04:29:59 -0500
|
||||
Subject: [PATCH] Add more Zombie API
|
||||
|
||||
== AT ==
|
||||
public net.minecraft.world.entity.monster.Zombie isSunSensitive()Z
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/Zombie.java b/src/main/java/net/minecraft/world/entity/monster/Zombie.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Zombie.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Zombie.java
|
||||
@@ -0,0 +0,0 @@ public class Zombie extends Monster {
|
||||
private int inWaterTime;
|
||||
public int conversionTime;
|
||||
private int lastTick = MinecraftServer.currentTick; // CraftBukkit - add field
|
||||
+ private boolean shouldBurnInDay = true; // Paper - Add more Zombie API
|
||||
|
||||
public Zombie(EntityType<? extends Zombie> type, Level world) {
|
||||
super(type, world);
|
||||
@@ -0,0 +0,0 @@ public class Zombie extends Monster {
|
||||
super.aiStep();
|
||||
}
|
||||
|
||||
+ // Paper start - Add more Zombie API
|
||||
+ public void stopDrowning() {
|
||||
+ this.conversionTime = -1;
|
||||
+ this.getEntityData().set(Zombie.DATA_DROWNED_CONVERSION_ID, false);
|
||||
+ }
|
||||
+ // Paper end - Add more Zombie API
|
||||
public void startUnderWaterConversion(int ticksUntilWaterConversion) {
|
||||
this.lastTick = MinecraftServer.currentTick; // CraftBukkit
|
||||
this.conversionTime = ticksUntilWaterConversion;
|
||||
@@ -0,0 +0,0 @@ public class Zombie extends Monster {
|
||||
}
|
||||
|
||||
public boolean isSunSensitive() {
|
||||
- return true;
|
||||
+ return this.shouldBurnInDay; // Paper - Add more Zombie API
|
||||
}
|
||||
|
||||
+ // Paper start - Add more Zombie API
|
||||
+ public void setShouldBurnInDay(boolean shouldBurnInDay) {
|
||||
+ this.shouldBurnInDay = shouldBurnInDay;
|
||||
+ }
|
||||
+ // Paper end - Add more Zombie API
|
||||
+
|
||||
@Override
|
||||
public boolean hurt(DamageSource source, float amount) {
|
||||
if (!super.hurt(source, amount)) {
|
||||
@@ -0,0 +0,0 @@ public class Zombie extends Monster {
|
||||
nbt.putBoolean("CanBreakDoors", this.canBreakDoors());
|
||||
nbt.putInt("InWaterTime", this.isInWater() ? this.inWaterTime : -1);
|
||||
nbt.putInt("DrownedConversionTime", this.isUnderWaterConverting() ? this.conversionTime : -1);
|
||||
+ nbt.putBoolean("Paper.ShouldBurnInDay", this.shouldBurnInDay); // Paper - Add more Zombie API
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -0,0 +0,0 @@ public class Zombie extends Monster {
|
||||
if (nbt.contains("DrownedConversionTime", 99) && nbt.getInt("DrownedConversionTime") > -1) {
|
||||
this.startUnderWaterConversion(nbt.getInt("DrownedConversionTime"));
|
||||
}
|
||||
+ // Paper start - Add more Zombie API
|
||||
+ if (nbt.contains("Paper.ShouldBurnInDay")) {
|
||||
+ this.shouldBurnInDay = nbt.getBoolean("Paper.ShouldBurnInDay");
|
||||
+ }
|
||||
+ // Paper end - Add more Zombie API
|
||||
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftZombie.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftZombie.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftZombie.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftZombie.java
|
||||
@@ -0,0 +0,0 @@ public class CraftZombie extends CraftMonster implements Zombie {
|
||||
@Override
|
||||
public void setAgeLock(boolean b) {
|
||||
}
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public boolean isDrowning() {
|
||||
+ return getHandle().isUnderWaterConverting();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void startDrowning(int drownedConversionTime) {
|
||||
+ getHandle().startUnderWaterConversion(drownedConversionTime);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void stopDrowning() {
|
||||
+ getHandle().stopDrowning();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean shouldBurnInDay() {
|
||||
+ return getHandle().isSunSensitive();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isArmsRaised() {
|
||||
+ return getHandle().isAggressive();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setArmsRaised(final boolean raised) {
|
||||
+ getHandle().setAggressive(raised);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setShouldBurnInDay(boolean shouldBurnInDay) {
|
||||
+ getHandle().setShouldBurnInDay(shouldBurnInDay);
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
@Override
|
||||
public boolean getAgeLock() {
|
@@ -1,67 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Gabriele C <sgdc3.mail@gmail.com>
|
||||
Date: Mon, 22 Oct 2018 17:34:10 +0200
|
||||
Subject: [PATCH] Add option to prevent players from moving into unloaded
|
||||
chunks #1551
|
||||
|
||||
|
||||
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 extends ServerCommonPacketListenerImpl
|
||||
double d0 = entity.getX();
|
||||
double d1 = entity.getY();
|
||||
double d2 = entity.getZ();
|
||||
- double d3 = ServerGamePacketListenerImpl.clampHorizontal(packet.getX());
|
||||
- double d4 = ServerGamePacketListenerImpl.clampVertical(packet.getY());
|
||||
- double d5 = ServerGamePacketListenerImpl.clampHorizontal(packet.getZ());
|
||||
+ double d3 = ServerGamePacketListenerImpl.clampHorizontal(packet.getX()); final double toX = d3; // Paper - OBFHELPER
|
||||
+ double d4 = ServerGamePacketListenerImpl.clampVertical(packet.getY()); final double toY = d4; // Paper - OBFHELPER
|
||||
+ double d5 = ServerGamePacketListenerImpl.clampHorizontal(packet.getZ()); final double toZ = d5; // Paper - OBFHELPER
|
||||
float f = Mth.wrapDegrees(packet.getYRot());
|
||||
float f1 = Mth.wrapDegrees(packet.getXRot());
|
||||
double d6 = d3 - this.vehicleFirstGoodX;
|
||||
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
||||
}
|
||||
speed *= 2f; // TODO: Get the speed of the vehicle instead of the player
|
||||
|
||||
+ // Paper start - Prevent moving into unloaded chunks
|
||||
+ if (this.player.level().paperConfig().chunks.preventMovingIntoUnloadedChunks && (
|
||||
+ !worldserver.areChunksLoadedForMove(this.player.getBoundingBox().expandTowards(new Vec3(toX, toY, toZ).subtract(this.player.position()))) ||
|
||||
+ !worldserver.areChunksLoadedForMove(entity.getBoundingBox().expandTowards(new Vec3(toX, toY, toZ).subtract(entity.position())))
|
||||
+ )) {
|
||||
+ this.connection.send(new ClientboundMoveVehiclePacket(entity));
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end - Prevent moving into unloaded chunks
|
||||
+
|
||||
if (d10 - d9 > Math.max(100.0D, Math.pow((double) (org.spigotmc.SpigotConfig.movedTooQuicklyMultiplier * (float) i * speed), 2)) && !this.isSingleplayerOwner()) {
|
||||
// CraftBukkit end
|
||||
ServerGamePacketListenerImpl.LOGGER.warn("{} (vehicle of {}) moved too quickly! {},{},{}", new Object[]{entity.getName().getString(), this.player.getName().getString(), d6, d7, d8});
|
||||
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
||||
|
||||
} else {
|
||||
this.awaitingTeleportTime = this.tickCount;
|
||||
- double d0 = ServerGamePacketListenerImpl.clampHorizontal(packet.getX(this.player.getX()));
|
||||
- double d1 = ServerGamePacketListenerImpl.clampVertical(packet.getY(this.player.getY()));
|
||||
- double d2 = ServerGamePacketListenerImpl.clampHorizontal(packet.getZ(this.player.getZ()));
|
||||
+ double d0 = ServerGamePacketListenerImpl.clampHorizontal(packet.getX(this.player.getX())); final double toX = d0; // Paper - OBFHELPER
|
||||
+ double d1 = ServerGamePacketListenerImpl.clampVertical(packet.getY(this.player.getY())); final double toY = d1; // Paper - OBFHELPER
|
||||
+ double d2 = ServerGamePacketListenerImpl.clampHorizontal(packet.getZ(this.player.getZ())); final double toZ = d2; // Paper - OBFHELPER
|
||||
float f = Mth.wrapDegrees(packet.getYRot(this.player.getYRot()));
|
||||
float f1 = Mth.wrapDegrees(packet.getXRot(this.player.getXRot()));
|
||||
|
||||
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
||||
} else {
|
||||
speed = this.player.getAbilities().walkingSpeed * 10f;
|
||||
}
|
||||
+ // Paper start - Prevent moving into unloaded chunks
|
||||
+ if (this.player.level().paperConfig().chunks.preventMovingIntoUnloadedChunks && (this.player.getX() != toX || this.player.getZ() != toZ) && !worldserver.areChunksLoadedForMove(this.player.getBoundingBox().expandTowards(new Vec3(toX, toY, toZ).subtract(this.player.position())))) {
|
||||
+ this.internalTeleport(this.player.getX(), this.player.getY(), this.player.getZ(), this.player.getYRot(), this.player.getXRot(), Collections.emptySet());
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end - Prevent moving into unloaded chunks
|
||||
|
||||
if (!this.player.isChangingDimension() && (!this.player.level().getGameRules().getBoolean(GameRules.RULE_DISABLE_ELYTRA_MOVEMENT_CHECK) || !flag)) {
|
||||
float f2 = flag ? 300.0F : 100.0F;
|
@@ -1,68 +0,0 @@
|
||||
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 - Make shield blocking delay configurable
|
||||
+ 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 this.level().clip(raytrace);
|
||||
+ }
|
||||
+
|
||||
public int shieldBlockingDelay = this.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);
|
@@ -1,42 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Sun, 7 Oct 2018 00:54:21 -0500
|
||||
Subject: [PATCH] Add sun related API
|
||||
|
||||
== AT ==
|
||||
public net.minecraft.world.entity.Mob isSunBurnTick()Z
|
||||
|
||||
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 {
|
||||
}
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public boolean isDayTime() {
|
||||
+ return getHandle().isDay();
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public long getGameTime() {
|
||||
return this.world.levelData.getGameTime();
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java
|
||||
@@ -0,0 +0,0 @@ public abstract class CraftMob extends CraftLivingEntity implements Mob {
|
||||
public long getSeed() {
|
||||
return this.getHandle().lootTableSeed;
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public boolean isInDaylight() {
|
||||
+ return getHandle().isSunBurnTick();
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
@@ -1,31 +0,0 @@
|
||||
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 implements DataComponentHolder {
|
||||
enuminteractionresult = InteractionResult.FAIL; // cancel placement
|
||||
// PAIL: Remove this when MC-99075 fixed
|
||||
placeEvent.getPlayer().updateInventory();
|
||||
+ world.capturedTileEntities.clear(); // Paper - Allow chests to be placed with NBT data; clear out block 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 - Allow chests to be placed with NBT data
|
||||
}
|
||||
// CraftBukkit end
|
||||
}
|
@@ -1,145 +0,0 @@
|
||||
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 armor 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 - Allow ArmorStands not to tick
|
||||
|
||||
public ArmorStand(EntityType<? extends ArmorStand> type, Level world) {
|
||||
super(type, world);
|
||||
+ if (world != null) this.canTick = world.paperConfig().entities.armorStands.tick; // Paper - Allow ArmorStands not to tick
|
||||
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 ArmorStands not to tick; Still update equipment
|
||||
}
|
||||
|
||||
@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 - Allow ArmorStands not to tick
|
||||
}
|
||||
|
||||
@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 - Allow ArmorStands not to tick
|
||||
+ if (nbt.contains("Paper.CanTickOverride")) {
|
||||
+ this.canTick = nbt.getBoolean("Paper.CanTickOverride");
|
||||
+ this.canTickSetByAPI = true;
|
||||
+ }
|
||||
+ // Paper end - Allow ArmorStands not to tick
|
||||
CompoundTag nbttagcompound2 = nbt.getCompound("Pose");
|
||||
|
||||
this.readPose(nbttagcompound2);
|
||||
@@ -0,0 +0,0 @@ public class ArmorStand extends LivingEntity {
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
+ // Paper start - Allow ArmorStands not to tick
|
||||
+ if (!this.canTick) {
|
||||
+ if (this.noTickPoseDirty) {
|
||||
+ this.noTickPoseDirty = false;
|
||||
+ this.updatePose();
|
||||
+ }
|
||||
+
|
||||
+ if (this.noTickEquipmentDirty) {
|
||||
+ this.noTickEquipmentDirty = false;
|
||||
+ this.detectEquipmentUpdatesPublic();
|
||||
+ }
|
||||
+
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end - Allow ArmorStands not to tick
|
||||
+
|
||||
super.tick();
|
||||
+ // Paper start - Allow ArmorStands not to tick
|
||||
+ updatePose();
|
||||
+ }
|
||||
+
|
||||
+ public void updatePose() {
|
||||
+ // Paper end - Allow ArmorStands not to tick
|
||||
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
|
||||
}
|
@@ -1,27 +0,0 @@
|
||||
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.hasInfiniteMaterials() && iblockdata.is(BlockTags.ANVIL) && player.getRandom().nextFloat() < 0.12F) {
|
||||
BlockState iblockdata1 = AnvilBlock.damage(iblockdata);
|
||||
|
||||
+ // Paper start - AnvilDamageEvent
|
||||
+ 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 - AnvilDamageEvent
|
||||
if (iblockdata1 == null) {
|
||||
world.removeBlock(blockposition, false);
|
||||
world.levelEvent(1029, blockposition, 0);
|
@@ -1,66 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Callahan <mr.callahhh@gmail.com>
|
||||
Date: Wed, 8 Apr 2020 02:42:14 -0500
|
||||
Subject: [PATCH] Async command map building
|
||||
|
||||
This adds a custom pool inorder to make sure that they are closed
|
||||
without much though, as it doesn't matter if the client is not sent
|
||||
commands if the server is restarting. Using the default async pool caused issues to arise
|
||||
due to the shutdown logic generally being much later.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/commands/Commands.java b/src/main/java/net/minecraft/commands/Commands.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/commands/Commands.java
|
||||
+++ b/src/main/java/net/minecraft/commands/Commands.java
|
||||
@@ -0,0 +0,0 @@ public class Commands {
|
||||
if ( org.spigotmc.SpigotConfig.tabComplete < 0 ) return; // Spigot
|
||||
// CraftBukkit start
|
||||
// Register Vanilla commands into builtRoot as before
|
||||
+ // Paper start - Perf: Async command map building
|
||||
+ COMMAND_SENDING_POOL.execute(() -> {
|
||||
+ this.sendAsync(player);
|
||||
+ });
|
||||
+ }
|
||||
+
|
||||
+ public static final java.util.concurrent.ThreadPoolExecutor COMMAND_SENDING_POOL = new java.util.concurrent.ThreadPoolExecutor(
|
||||
+ 0, 2, 60L, java.util.concurrent.TimeUnit.SECONDS,
|
||||
+ new java.util.concurrent.LinkedBlockingQueue<>(),
|
||||
+ new com.google.common.util.concurrent.ThreadFactoryBuilder()
|
||||
+ .setNameFormat("Paper Async Command Builder Thread Pool - %1$d")
|
||||
+ .setUncaughtExceptionHandler(new net.minecraft.DefaultUncaughtExceptionHandlerWithName(net.minecraft.server.MinecraftServer.LOGGER))
|
||||
+ .build(),
|
||||
+ new java.util.concurrent.ThreadPoolExecutor.DiscardPolicy()
|
||||
+ );
|
||||
+
|
||||
+ private void sendAsync(ServerPlayer player) {
|
||||
+ // Paper end - Perf: Async command map building
|
||||
Map<CommandNode<CommandSourceStack>, CommandNode<SharedSuggestionProvider>> map = Maps.newIdentityHashMap(); // Use identity to prevent aliasing issues
|
||||
RootCommandNode vanillaRoot = new RootCommandNode();
|
||||
|
||||
@@ -0,0 +0,0 @@ public class Commands {
|
||||
for (CommandNode node : rootcommandnode.getChildren()) {
|
||||
bukkit.add(node.getName());
|
||||
}
|
||||
+ // Paper start - Perf: Async command map building
|
||||
+ net.minecraft.server.MinecraftServer.getServer().execute(() -> {
|
||||
+ runSync(player, bukkit, rootcommandnode);
|
||||
+ });
|
||||
+ }
|
||||
|
||||
+ private void runSync(ServerPlayer player, Collection<String> bukkit, RootCommandNode<SharedSuggestionProvider> rootcommandnode) {
|
||||
+ // Paper end - Perf: Async command map building
|
||||
PlayerCommandSendEvent event = new PlayerCommandSendEvent(player.getBukkitEntity(), new LinkedHashSet<>(bukkit));
|
||||
event.getPlayer().getServer().getPluginManager().callEvent(event);
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
MinecraftServer.LOGGER.info("Stopping server");
|
||||
+ Commands.COMMAND_SENDING_POOL.shutdownNow(); // Paper - Perf: Async command map building; Shutdown and don't bother finishing
|
||||
MinecraftTimings.stopServer(); // Paper
|
||||
// CraftBukkit start
|
||||
if (this.server != null) {
|
@@ -1,53 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Wed, 6 Feb 2019 00:20:33 -0500
|
||||
Subject: [PATCH] BlockDestroyEvent
|
||||
|
||||
Adds an event for when the server is going to destroy a current block,
|
||||
potentially causing it to drop. This event can be cancelled to avoid
|
||||
the block destruction, such as preventing signs from popping when
|
||||
floating in the air.
|
||||
|
||||
This can replace many uses of BlockPhysicsEvent
|
||||
|
||||
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 @@ import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
+import io.papermc.paper.util.MCUtil;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.FullChunkStatus;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
@@ -0,0 +0,0 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
return false;
|
||||
} else {
|
||||
FluidState fluid = this.getFluidState(pos);
|
||||
+ // Paper start - BlockDestroyEvent; while the above setAir method is named same and looks very similar
|
||||
+ // they are NOT used with same intent and the above should not fire this event. The above method is more of a BlockSetToAirEvent,
|
||||
+ // it doesn't imply destruction of a block that plays a sound effect / drops an item.
|
||||
+ boolean playEffect = true;
|
||||
+ BlockState effectType = iblockdata;
|
||||
+ int xp = iblockdata.getBlock().getExpDrop(iblockdata, (ServerLevel) this, pos, ItemStack.EMPTY, true);
|
||||
+ if (com.destroystokyo.paper.event.block.BlockDestroyEvent.getHandlerList().getRegisteredListeners().length > 0) {
|
||||
+ com.destroystokyo.paper.event.block.BlockDestroyEvent event = new com.destroystokyo.paper.event.block.BlockDestroyEvent(org.bukkit.craftbukkit.block.CraftBlock.at(this, pos), fluid.createLegacyBlock().createCraftBlockData(), effectType.createCraftBlockData(), xp, drop);
|
||||
+ if (!event.callEvent()) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ effectType = ((CraftBlockData) event.getEffectBlock()).getState();
|
||||
+ playEffect = event.playEffect();
|
||||
+ drop = event.willDrop();
|
||||
+ xp = event.getExpToDrop();
|
||||
+ }
|
||||
+ // Paper end - BlockDestroyEvent
|
||||
|
||||
- if (!(iblockdata.getBlock() instanceof BaseFireBlock)) {
|
||||
- this.levelEvent(2001, pos, Block.getId(iblockdata));
|
||||
+ if (playEffect && !(effectType.getBlock() instanceof BaseFireBlock)) { // Paper - BlockDestroyEvent
|
||||
+ this.levelEvent(2001, pos, Block.getId(effectType)); // Paper - BlockDestroyEvent
|
||||
}
|
||||
|
||||
if (drop) {
|
@@ -1,57 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Fri, 16 Nov 2018 23:08:50 -0500
|
||||
Subject: [PATCH] Book Size Limits
|
||||
|
||||
Puts some limits on the size of books.
|
||||
|
||||
diff --git a/src/main/java/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 extends ServerCommonPacketListenerImpl
|
||||
|
||||
@Override
|
||||
public void handleEditBook(ServerboundEditBookPacket packet) {
|
||||
+ // Paper start - Book size limits
|
||||
+ if (!this.cserver.isPrimaryThread()) {
|
||||
+ List<String> pageList = packet.pages();
|
||||
+ long byteTotal = 0;
|
||||
+ int maxBookPageSize = io.papermc.paper.configuration.GlobalConfiguration.get().itemValidation.bookSize.pageMax;
|
||||
+ double multiplier = Math.max(0.3D, Math.min(1D, io.papermc.paper.configuration.GlobalConfiguration.get().itemValidation.bookSize.totalMultiplier));
|
||||
+ long byteAllowed = maxBookPageSize;
|
||||
+ for (String testString : pageList) {
|
||||
+ int byteLength = testString.getBytes(java.nio.charset.StandardCharsets.UTF_8).length;
|
||||
+ if (byteLength > 256 * 4) {
|
||||
+ ServerGamePacketListenerImpl.LOGGER.warn(this.player.getScoreboardName() + " tried to send a book with with a page too large!");
|
||||
+ server.scheduleOnMain(() -> this.disconnect("Book too large!"));
|
||||
+ return;
|
||||
+ }
|
||||
+ byteTotal += byteLength;
|
||||
+ int length = testString.length();
|
||||
+ int multibytes = 0;
|
||||
+ if (byteLength != length) {
|
||||
+ for (char c : testString.toCharArray()) {
|
||||
+ if (c > 127) {
|
||||
+ multibytes++;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ byteAllowed += (maxBookPageSize * Math.min(1, Math.max(0.1D, (double) length / 255D))) * multiplier;
|
||||
+
|
||||
+ if (multibytes > 1) {
|
||||
+ // penalize MB
|
||||
+ byteAllowed -= multibytes;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (byteTotal > byteAllowed) {
|
||||
+ ServerGamePacketListenerImpl.LOGGER.warn(this.player.getScoreboardName() + " tried to send too large of a book. Book Size: " + byteTotal + " - Allowed: "+ byteAllowed + " - Pages: " + pageList.size());
|
||||
+ server.scheduleOnMain(() -> this.disconnect("Book too large!"));
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - Book size limits
|
||||
// CraftBukkit start
|
||||
if (this.lastBookTick + 20 > MinecraftServer.currentTick) {
|
||||
this.disconnect("Book edited too quickly!");
|
@@ -1,52 +0,0 @@
|
||||
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 extends ServerCommonPacketListenerImpl
|
||||
private int ackBlockChangesUpTo = -1;
|
||||
// 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 extends ServerCommonPacketListenerImpl
|
||||
this.keepConnectionAlive();
|
||||
// CraftBukkit start
|
||||
for (int spam; (spam = this.chatSpamTickCount.get()) > 0 && !this.chatSpamTickCount.compareAndSet(spam, spam - 1); ) ;
|
||||
+ if (tabSpamLimiter.get() > 0) tabSpamLimiter.getAndDecrement(); // Paper - configurable tab spam limits
|
||||
/* Use thread-safe field access instead
|
||||
if (this.chatSpamTickCount > 0) {
|
||||
--this.chatSpamTickCount;
|
||||
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
||||
public void handleCustomCommandSuggestions(ServerboundCommandSuggestionPacket packet) {
|
||||
// PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); // Paper - AsyncTabCompleteEvent; 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 - configurable tab spam limits
|
||||
this.disconnect(Component.translatable("disconnect.spam"));
|
||||
return;
|
||||
}
|
@@ -1,206 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sun, 19 Apr 2020 18:15:29 -0400
|
||||
Subject: [PATCH] Brigadier Mojang API
|
||||
|
||||
Adds AsyncPlayerSendCommandsEvent
|
||||
- Allows modifying on a per command basis what command data they see.
|
||||
|
||||
Adds CommandRegisteredEvent
|
||||
- Allows manipulating the CommandNode to add more children/metadata for the client
|
||||
|
||||
diff --git a/src/main/java/com/mojang/brigadier/exceptions/CommandSyntaxException.java b/src/main/java/com/mojang/brigadier/exceptions/CommandSyntaxException.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/com/mojang/brigadier/exceptions/CommandSyntaxException.java
|
||||
+++ b/src/main/java/com/mojang/brigadier/exceptions/CommandSyntaxException.java
|
||||
@@ -0,0 +0,0 @@ package com.mojang.brigadier.exceptions;
|
||||
|
||||
import com.mojang.brigadier.Message;
|
||||
|
||||
-public class CommandSyntaxException extends Exception {
|
||||
+public class CommandSyntaxException extends Exception implements net.kyori.adventure.util.ComponentMessageThrowable { // Paper - Brigadier API
|
||||
public static final int CONTEXT_AMOUNT = 10;
|
||||
public static boolean ENABLE_COMMAND_STACK_TRACES = true;
|
||||
public static BuiltInExceptionProvider BUILT_IN_EXCEPTIONS = new BuiltInExceptions();
|
||||
@@ -0,0 +0,0 @@ public class CommandSyntaxException extends Exception {
|
||||
public int getCursor() {
|
||||
return cursor;
|
||||
}
|
||||
+
|
||||
+ // Paper start - Brigadier API
|
||||
+ @Override
|
||||
+ public @org.jetbrains.annotations.Nullable net.kyori.adventure.text.Component componentMessage() {
|
||||
+ return io.papermc.paper.brigadier.PaperBrigadier.componentFromMessage(this.message);
|
||||
+ }
|
||||
+ // Paper end - Brigadier API
|
||||
}
|
||||
diff --git a/src/main/java/com/mojang/brigadier/tree/CommandNode.java b/src/main/java/com/mojang/brigadier/tree/CommandNode.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/com/mojang/brigadier/tree/CommandNode.java
|
||||
+++ b/src/main/java/com/mojang/brigadier/tree/CommandNode.java
|
||||
@@ -0,0 +0,0 @@ public abstract class CommandNode<S> implements Comparable<CommandNode<S>> {
|
||||
private final RedirectModifier<S> modifier;
|
||||
private final boolean forks;
|
||||
private Command<S> command;
|
||||
+ public CommandNode<CommandSourceStack> clientNode; // Paper - Brigadier API
|
||||
// CraftBukkit start
|
||||
public void removeCommand(String name) {
|
||||
this.children.remove(name);
|
||||
diff --git a/src/main/java/net/minecraft/commands/CommandSourceStack.java b/src/main/java/net/minecraft/commands/CommandSourceStack.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/commands/CommandSourceStack.java
|
||||
+++ b/src/main/java/net/minecraft/commands/CommandSourceStack.java
|
||||
@@ -0,0 +0,0 @@ import net.minecraft.world.phys.Vec2;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import com.mojang.brigadier.tree.CommandNode; // CraftBukkit
|
||||
|
||||
-public class CommandSourceStack implements ExecutionCommandSource<CommandSourceStack>, SharedSuggestionProvider {
|
||||
+public class CommandSourceStack implements ExecutionCommandSource<CommandSourceStack>, SharedSuggestionProvider, com.destroystokyo.paper.brigadier.BukkitBrigadierCommandSource { // Paper - Brigadier API
|
||||
|
||||
public static final SimpleCommandExceptionType ERROR_NOT_PLAYER = new SimpleCommandExceptionType(Component.translatable("permissions.requires.player"));
|
||||
public static final SimpleCommandExceptionType ERROR_NOT_ENTITY = new SimpleCommandExceptionType(Component.translatable("permissions.requires.entity"));
|
||||
@@ -0,0 +0,0 @@ public class CommandSourceStack implements ExecutionCommandSource<CommandSourceS
|
||||
return this.textName;
|
||||
}
|
||||
|
||||
+ // Paper start - Brigadier API
|
||||
+ @Override
|
||||
+ public org.bukkit.entity.Entity getBukkitEntity() {
|
||||
+ return getEntity() != null ? getEntity().getBukkitEntity() : null;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public org.bukkit.World getBukkitWorld() {
|
||||
+ return getLevel() != null ? getLevel().getWorld() : null;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public org.bukkit.Location getBukkitLocation() {
|
||||
+ Vec3 pos = getPosition();
|
||||
+ org.bukkit.World world = getBukkitWorld();
|
||||
+ Vec2 rot = getRotation();
|
||||
+ return world != null && pos != null ? new org.bukkit.Location(world, pos.x, pos.y, pos.z, rot != null ? rot.y : 0, rot != null ? rot.x : 0) : null;
|
||||
+ }
|
||||
+ // Paper end - Brigadier API
|
||||
+
|
||||
@Override
|
||||
public boolean hasPermission(int level) {
|
||||
// CraftBukkit start
|
||||
diff --git a/src/main/java/net/minecraft/commands/Commands.java b/src/main/java/net/minecraft/commands/Commands.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/commands/Commands.java
|
||||
+++ b/src/main/java/net/minecraft/commands/Commands.java
|
||||
@@ -0,0 +0,0 @@ public class Commands {
|
||||
bukkit.add(node.getName());
|
||||
}
|
||||
// Paper start - Perf: Async command map building
|
||||
+ new com.destroystokyo.paper.event.brigadier.AsyncPlayerSendCommandsEvent<CommandSourceStack>(player.getBukkitEntity(), (RootCommandNode) rootcommandnode, false).callEvent(); // Paper - Brigadier API
|
||||
net.minecraft.server.MinecraftServer.getServer().execute(() -> {
|
||||
runSync(player, bukkit, rootcommandnode);
|
||||
});
|
||||
@@ -0,0 +0,0 @@ public class Commands {
|
||||
|
||||
private void runSync(ServerPlayer player, Collection<String> bukkit, RootCommandNode<SharedSuggestionProvider> rootcommandnode) {
|
||||
// Paper end - Perf: Async command map building
|
||||
+ new com.destroystokyo.paper.event.brigadier.AsyncPlayerSendCommandsEvent<CommandSourceStack>(player.getBukkitEntity(), (RootCommandNode) rootcommandnode, false).callEvent(); // Paper - Brigadier API
|
||||
PlayerCommandSendEvent event = new PlayerCommandSendEvent(player.getBukkitEntity(), new LinkedHashSet<>(bukkit));
|
||||
event.getPlayer().getServer().getPluginManager().callEvent(event);
|
||||
|
||||
@@ -0,0 +0,0 @@ public class Commands {
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
CommandNode<CommandSourceStack> commandnode2 = (CommandNode) iterator.next();
|
||||
+ // Paper start - Brigadier API
|
||||
+ if (commandnode2.clientNode != null) {
|
||||
+ commandnode2 = commandnode2.clientNode;
|
||||
+ }
|
||||
+ // Paper end - Brigadier API
|
||||
if ( !org.spigotmc.SpigotConfig.sendNamespaced && commandnode2.getName().contains( ":" ) ) continue; // Spigot
|
||||
|
||||
if (commandnode2.canUse(source)) {
|
||||
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 extends ServerCommonPacketListenerImpl
|
||||
builder.suggest(completion.suggestion(), PaperAdventure.asVanilla(completion.tooltip()));
|
||||
}
|
||||
}
|
||||
- this.connection.send(new ClientboundCommandSuggestionsPacket(packet.getId(), builder.buildFuture().join()));
|
||||
+ // Paper start - Brigadier API
|
||||
+ com.mojang.brigadier.suggestion.Suggestions suggestions = builder.buildFuture().join();
|
||||
+ com.destroystokyo.paper.event.brigadier.AsyncPlayerSendSuggestionsEvent suggestEvent = new com.destroystokyo.paper.event.brigadier.AsyncPlayerSendSuggestionsEvent(this.getCraftPlayer(), suggestions, packet.getCommand());
|
||||
+ suggestEvent.setCancelled(suggestions.isEmpty());
|
||||
+ if (suggestEvent.callEvent()) {
|
||||
+ this.connection.send(new ClientboundCommandSuggestionsPacket(packet.getId(), limitTo(suggestEvent.getSuggestions(), ServerGamePacketListenerImpl.MAX_COMMAND_SUGGESTIONS)));
|
||||
+ }
|
||||
+ // Paper end - Brigadier API
|
||||
}
|
||||
}
|
||||
+ // Paper start - brig API
|
||||
+ private static Suggestions limitTo(final Suggestions suggestions, final int size) {
|
||||
+ return suggestions.getList().size() <= size ? suggestions : new Suggestions(suggestions.getRange(), suggestions.getList().subList(0, size));
|
||||
+ }
|
||||
+ // Paper end - brig API
|
||||
|
||||
private void sendServerSuggestions(final ServerboundCommandSuggestionPacket packet, final StringReader stringreader) {
|
||||
// Paper end - AsyncTabCompleteEvent
|
||||
ParseResults<CommandSourceStack> parseresults = this.server.getCommands().getDispatcher().parse(stringreader, this.player.createCommandSourceStack());
|
||||
|
||||
this.server.getCommands().getDispatcher().getCompletionSuggestions(parseresults).thenAccept((suggestions) -> {
|
||||
- if (suggestions.isEmpty()) return; // CraftBukkit - don't send through empty suggestions - prevents [<args>] from showing for plugins with nothing more to offer
|
||||
- Suggestions suggestions1 = suggestions.getList().size() <= 1000 ? suggestions : new Suggestions(suggestions.getRange(), suggestions.getList().subList(0, 1000));
|
||||
-
|
||||
- this.send(new ClientboundCommandSuggestionsPacket(packet.getId(), suggestions1));
|
||||
+ // Paper start - Brigadier API
|
||||
+ com.destroystokyo.paper.event.brigadier.AsyncPlayerSendSuggestionsEvent suggestEvent = new com.destroystokyo.paper.event.brigadier.AsyncPlayerSendSuggestionsEvent(this.getCraftPlayer(), suggestions, packet.getCommand());
|
||||
+ suggestEvent.setCancelled(suggestions.isEmpty());
|
||||
+ if (suggestEvent.callEvent()) {
|
||||
+ this.send(new ClientboundCommandSuggestionsPacket(packet.getId(), limitTo(suggestEvent.getSuggestions(), ServerGamePacketListenerImpl.MAX_COMMAND_SUGGESTIONS)));
|
||||
+ }
|
||||
+ // Paper end - Brigadier API
|
||||
});
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/command/BukkitCommandWrapper.java b/src/main/java/org/bukkit/craftbukkit/command/BukkitCommandWrapper.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/command/BukkitCommandWrapper.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/command/BukkitCommandWrapper.java
|
||||
@@ -0,0 +0,0 @@ import org.bukkit.command.CommandException;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
|
||||
-public class BukkitCommandWrapper implements com.mojang.brigadier.Command<CommandSourceStack>, Predicate<CommandSourceStack>, SuggestionProvider<CommandSourceStack> {
|
||||
+public class BukkitCommandWrapper implements com.mojang.brigadier.Command<CommandSourceStack>, Predicate<CommandSourceStack>, SuggestionProvider<CommandSourceStack>, com.destroystokyo.paper.brigadier.BukkitBrigadierCommand<CommandSourceStack> { // Paper
|
||||
|
||||
private final CraftServer server;
|
||||
private final Command command;
|
||||
@@ -0,0 +0,0 @@ public class BukkitCommandWrapper implements com.mojang.brigadier.Command<Comman
|
||||
}
|
||||
|
||||
public LiteralCommandNode<CommandSourceStack> register(CommandDispatcher<CommandSourceStack> dispatcher, String label) {
|
||||
- return dispatcher.register(
|
||||
- LiteralArgumentBuilder.<CommandSourceStack>literal(label).requires(this).executes(this)
|
||||
- .then(RequiredArgumentBuilder.<CommandSourceStack, String>argument("args", StringArgumentType.greedyString()).suggests(this).executes(this))
|
||||
- );
|
||||
+ // Paper start - Expose Brigadier to Paper-MojangAPI
|
||||
+ com.mojang.brigadier.tree.RootCommandNode<CommandSourceStack> root = dispatcher.getRoot();
|
||||
+ LiteralCommandNode<CommandSourceStack> literal = LiteralArgumentBuilder.<CommandSourceStack>literal(label).requires(this).executes(this).build();
|
||||
+ LiteralCommandNode<CommandSourceStack> defaultNode = literal;
|
||||
+ com.mojang.brigadier.tree.ArgumentCommandNode<CommandSourceStack, String> defaultArgs = RequiredArgumentBuilder.<CommandSourceStack, String>argument("args", StringArgumentType.greedyString()).suggests(this).executes(this).build();
|
||||
+ literal.addChild(defaultArgs);
|
||||
+ com.destroystokyo.paper.event.brigadier.CommandRegisteredEvent<CommandSourceStack> event = new com.destroystokyo.paper.event.brigadier.CommandRegisteredEvent<>(label, this, this.command, root, literal, defaultArgs);
|
||||
+ if (!event.callEvent()) {
|
||||
+ return null;
|
||||
+ }
|
||||
+ literal = event.getLiteral();
|
||||
+ if (event.isRawCommand()) {
|
||||
+ defaultNode.clientNode = literal;
|
||||
+ literal = defaultNode;
|
||||
+ }
|
||||
+ root.addChild(literal);
|
||||
+ return literal;
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
@Override
|
@@ -1,46 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Caleb Bassham <caleb.bassham@gmail.com>
|
||||
Date: Fri, 28 Sep 2018 02:32:19 -0500
|
||||
Subject: [PATCH] Call player spectator target events and improve
|
||||
implementation
|
||||
|
||||
Use a proper teleport for teleporting to entities in different
|
||||
worlds.
|
||||
|
||||
Implementation improvements authored by Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
Validate that the target entity is valid and deny spectate
|
||||
requests from frozen players.
|
||||
|
||||
Also, make sure the entity is spawned to the client before
|
||||
sending the camera packet. If the entity isn't spawned clientside
|
||||
when it receives the camera packet, then the client will not
|
||||
spectate the target entity.
|
||||
|
||||
Co-authored-by: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
|
||||
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 {
|
||||
|
||||
this.camera = (Entity) (entity == null ? this : entity);
|
||||
if (entity1 != this.camera) {
|
||||
+ // Paper start - Add PlayerStartSpectatingEntityEvent and PlayerStopSpectatingEntity
|
||||
+ if (this.camera == this) {
|
||||
+ com.destroystokyo.paper.event.player.PlayerStopSpectatingEntityEvent playerStopSpectatingEntityEvent = new com.destroystokyo.paper.event.player.PlayerStopSpectatingEntityEvent(this.getBukkitEntity(), entity1.getBukkitEntity());
|
||||
+ if (!playerStopSpectatingEntityEvent.callEvent()) {
|
||||
+ this.camera = entity1; // rollback camera entity again
|
||||
+ return;
|
||||
+ }
|
||||
+ } else {
|
||||
+ com.destroystokyo.paper.event.player.PlayerStartSpectatingEntityEvent playerStartSpectatingEntityEvent = new com.destroystokyo.paper.event.player.PlayerStartSpectatingEntityEvent(this.getBukkitEntity(), entity1.getBukkitEntity(), entity.getBukkitEntity());
|
||||
+ if (!playerStartSpectatingEntityEvent.callEvent()) {
|
||||
+ this.camera = entity1; // rollback camera entity again
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - Add PlayerStartSpectatingEntityEvent and PlayerStopSpectatingEntity
|
||||
Level world = this.camera.level();
|
||||
|
||||
if (world instanceof ServerLevel) {
|
@@ -1,27 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Noah van der Aa <ndvdaa@gmail.com>
|
||||
Date: Mon, 29 Apr 2024 23:12:33 +0200
|
||||
Subject: [PATCH] Catch JsonParseException in block entity names
|
||||
|
||||
As a result, data that no longer parses correctly will not crash the server
|
||||
instead just logging the exception and continuing (and in most cases should
|
||||
fix the data)
|
||||
|
||||
Player data is fixed pretty much immediately but some block data (like
|
||||
Shulkers) may need to be changed in order for it to re-save properly
|
||||
|
||||
No more crashing though.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java
|
||||
@@ -0,0 +0,0 @@ public class SkullBlockEntity extends BlockEntity {
|
||||
}
|
||||
|
||||
if (nbt.contains("custom_name", 8)) {
|
||||
- this.customName = Component.Serializer.fromJson(nbt.getString("custom_name"), registryLookup);
|
||||
+ this.customName = BlockEntity.parseCustomNameSafe(nbt.getString("custom_name"), registryLookup); // Paper
|
||||
} else {
|
||||
this.customName = null;
|
||||
}
|
@@ -1,19 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Wed, 10 Oct 2018 21:22:44 -0500
|
||||
Subject: [PATCH] Check Drowned for Villager Aggression Config
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/Drowned.java b/src/main/java/net/minecraft/world/entity/monster/Drowned.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Drowned.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Drowned.java
|
||||
@@ -0,0 +0,0 @@ public class Drowned extends Zombie implements RangedAttackMob {
|
||||
this.goalSelector.addGoal(7, new RandomStrollGoal(this, 1.0D));
|
||||
this.targetSelector.addGoal(1, (new HurtByTargetGoal(this, new Class[]{Drowned.class})).setAlertOthers(ZombifiedPiglin.class));
|
||||
this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, 10, true, false, this::okTarget));
|
||||
- this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, AbstractVillager.class, false));
|
||||
+ if (this.level().spigotConfig.zombieAggressiveTowardsVillager) this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, AbstractVillager.class, false)); // Paper - Check drowned for villager aggression config
|
||||
this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, IronGolem.class, true));
|
||||
this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, Axolotl.class, true, false));
|
||||
this.targetSelector.addGoal(5, new NearestAttackableTargetGoal<>(this, Turtle.class, 10, true, false, Turtle.BABY_ON_LAND_SELECTOR));
|
@@ -1,78 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Fri, 15 Jun 2018 00:30:32 -0400
|
||||
Subject: [PATCH] Configurable LootPool luck formula
|
||||
|
||||
Rewrites the Vanilla luck application formula so that luck can be
|
||||
applied to items that do not have any quality defined.
|
||||
|
||||
See: https://luckformula.emc.gs for data and details
|
||||
-----------
|
||||
|
||||
The rough summary is:
|
||||
My goal was that in a pool, when luck was applied, the pool
|
||||
rebalances so the percentages for bigger items is
|
||||
lowered and smaller items is boosted.
|
||||
|
||||
Do this by boosting and then reducing the weight value,
|
||||
so that larger numbers are penalized more than smaller numbers.
|
||||
resulting in a larger reduction of entries for more common
|
||||
items than the reduction on small weights,
|
||||
giving smaller weights more of a chance
|
||||
|
||||
-----------
|
||||
|
||||
This work kind of obsoletes quality, but quality would be useful
|
||||
for 2 items with same weight that you want luck to impact
|
||||
in varying directions.
|
||||
|
||||
Fishing still falls into that as the weights are closer, so luck
|
||||
will invalidate junk more.
|
||||
|
||||
This change will result in some major changes to fishing formulas.
|
||||
|
||||
-----------
|
||||
|
||||
I would love to see this change in Vanilla, so Mojang please pull :)
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/storage/loot/entries/LootPoolSingletonContainer.java b/src/main/java/net/minecraft/world/level/storage/loot/entries/LootPoolSingletonContainer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/storage/loot/entries/LootPoolSingletonContainer.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/storage/loot/entries/LootPoolSingletonContainer.java
|
||||
@@ -0,0 +0,0 @@ public abstract class LootPoolSingletonContainer extends LootPoolEntryContainer
|
||||
protected abstract class EntryBase implements LootPoolEntry {
|
||||
@Override
|
||||
public int getWeight(float luck) {
|
||||
- return Math.max(Mth.floor((float)LootPoolSingletonContainer.this.weight + (float)LootPoolSingletonContainer.this.quality * luck), 0);
|
||||
+ // Paper start - Configurable LootPool luck formula
|
||||
+ // SEE: https://luckformula.emc.gs for details and data
|
||||
+ if (LootPoolSingletonContainer.this.lastLuck != null && LootPoolSingletonContainer.this.lastLuck == luck) {
|
||||
+ return lastWeight;
|
||||
+ }
|
||||
+ // This is vanilla
|
||||
+ float qualityModifer = (float) LootPoolSingletonContainer.this.quality * luck;
|
||||
+ double baseWeight = (LootPoolSingletonContainer.this.weight + qualityModifer);
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().misc.useAlternativeLuckFormula) {
|
||||
+ // Random boost to avoid losing precision in the final int cast on return
|
||||
+ final int weightBoost = 100;
|
||||
+ baseWeight *= weightBoost;
|
||||
+ // If we have vanilla 1, bump that down to 0 so nothing is is impacted
|
||||
+ // vanilla 3 = 300, 200 basis = impact 2%
|
||||
+ // =($B2*(($B2-100)/100/100))
|
||||
+ double impacted = baseWeight * ((baseWeight - weightBoost) / weightBoost / 100);
|
||||
+ // =($B$7/100)
|
||||
+ float luckModifier = Math.min(100, luck * 10) / 100;
|
||||
+ // =B2 - (C2 *($B$7/100))
|
||||
+ baseWeight = Math.ceil(baseWeight - (impacted * luckModifier));
|
||||
+ }
|
||||
+ LootPoolSingletonContainer.this.lastLuck = luck;
|
||||
+ LootPoolSingletonContainer.this.lastWeight = (int) Math.max(Math.floor(baseWeight), 0);
|
||||
+ return lastWeight;
|
||||
}
|
||||
}
|
||||
+ private Float lastLuck = null;
|
||||
+ private int lastWeight = 0;
|
||||
+ // Paper end - Configurable LootPool luck formula
|
||||
|
||||
@FunctionalInterface
|
||||
protected interface EntryConstructor {
|
@@ -1,19 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shane Freeder <theboyetronic@gmail.com>
|
||||
Date: Tue, 2 Oct 2018 09:57:50 +0100
|
||||
Subject: [PATCH] Configurable connection throttle kick message
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java
|
||||
@@ -0,0 +0,0 @@ public class ServerHandshakePacketListenerImpl implements ServerHandshakePacketL
|
||||
synchronized (ServerHandshakePacketListenerImpl.throttleTracker) {
|
||||
if (ServerHandshakePacketListenerImpl.throttleTracker.containsKey(address) && !"127.0.0.1".equals(address.getHostAddress()) && currentTime - ServerHandshakePacketListenerImpl.throttleTracker.get(address) < connectionThrottle) {
|
||||
ServerHandshakePacketListenerImpl.throttleTracker.put(address, currentTime);
|
||||
- MutableComponent chatmessage = Component.literal("Connection throttled! Please wait before reconnecting.");
|
||||
+ Component chatmessage = io.papermc.paper.adventure.PaperAdventure.asVanilla(io.papermc.paper.configuration.GlobalConfiguration.get().messages.kick.connectionThrottle); // Paper - Configurable connection throttle kick message
|
||||
this.connection.send(new ClientboundLoginDisconnectPacket(chatmessage));
|
||||
this.connection.disconnect(chatmessage);
|
||||
return;
|
@@ -1,52 +0,0 @@
|
||||
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
|
||||
protected 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 - Configurable speed for water flowing over lava
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+ // Paper start - Configurable speed for water flowing over lava
|
||||
+ public int getFlowSpeed(Level world, BlockPos blockposition) {
|
||||
+ if (net.minecraft.core.registries.BuiltInRegistries.FLUID.wrapAsHolder(this.fluid).is(FluidTags.WATER)) {
|
||||
+ if (
|
||||
+ isLava(world, blockposition.north(1)) ||
|
||||
+ isLava(world, blockposition.south(1)) ||
|
||||
+ isLava(world, blockposition.west(1)) ||
|
||||
+ isLava(world, blockposition.east(1))
|
||||
+ ) {
|
||||
+ return world.paperConfig().environment.waterOverLavaFlowSpeed;
|
||||
+ }
|
||||
+ }
|
||||
+ return this.fluid.getTickDelay(world);
|
||||
+ }
|
||||
+ private static boolean isLava(Level world, BlockPos blockPos) {
|
||||
+ final FluidState fluidState = world.getFluidIfLoaded(blockPos);
|
||||
+ return fluidState != null && fluidState.is(FluidTags.LAVA);
|
||||
+ }
|
||||
+ // Paper end - Configurable speed for water flowing over lava
|
||||
+
|
||||
@Override
|
||||
protected 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
|
||||
protected 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 - Configurable speed for water flowing over lava
|
||||
}
|
||||
|
||||
}
|
@@ -1,77 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shane Freeder <theboyetronic@gmail.com>
|
||||
Date: Sun, 11 Nov 2018 21:01:09 +0000
|
||||
Subject: [PATCH] Don't allow digging into unloaded chunks
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
|
||||
@@ -0,0 +0,0 @@ public class ServerPlayerGameMode {
|
||||
BlockState iblockdata;
|
||||
|
||||
if (this.hasDelayedDestroy) {
|
||||
- iblockdata = this.level.getBlockState(this.delayedDestroyPos);
|
||||
- if (iblockdata.isAir()) {
|
||||
+ iblockdata = this.level.getBlockStateIfLoaded(this.delayedDestroyPos); // Paper - Don't allow digging into unloaded chunks
|
||||
+ if (iblockdata == null || iblockdata.isAir()) { // Paper - Don't allow digging into unloaded chunks
|
||||
this.hasDelayedDestroy = false;
|
||||
} else {
|
||||
float f = this.incrementDestroyProgress(iblockdata, this.delayedDestroyPos, this.delayedTickStart);
|
||||
@@ -0,0 +0,0 @@ public class ServerPlayerGameMode {
|
||||
}
|
||||
}
|
||||
} else if (this.isDestroyingBlock) {
|
||||
- iblockdata = this.level.getBlockState(this.destroyPos);
|
||||
+ // Paper start - Don't allow digging into unloaded chunks; don't want to do same logic as above, return instead
|
||||
+ iblockdata = this.level.getBlockStateIfLoaded(this.destroyPos);
|
||||
+ if (iblockdata == null) {
|
||||
+ this.isDestroyingBlock = false;
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end - Don't allow digging into unloaded chunks
|
||||
if (iblockdata.isAir()) {
|
||||
this.level.destroyBlockProgress(this.player.getId(), this.destroyPos, -1);
|
||||
this.lastSentState = -1;
|
||||
@@ -0,0 +0,0 @@ public class ServerPlayerGameMode {
|
||||
|
||||
public void handleBlockBreakAction(BlockPos pos, ServerboundPlayerActionPacket.Action action, Direction direction, int worldHeight, int sequence) {
|
||||
if (!this.player.canInteractWithBlock(pos, 1.0D)) {
|
||||
+ if (true) return; // Paper - Don't allow digging into unloaded chunks; Don't notify if unreasonably far away
|
||||
this.debugLogging(pos, false, sequence, "too far");
|
||||
} else if (pos.getY() >= worldHeight) {
|
||||
this.player.connection.send(new ClientboundBlockUpdatePacket(pos, this.level.getBlockState(pos)));
|
||||
@@ -0,0 +0,0 @@ public class ServerPlayerGameMode {
|
||||
this.debugLogging(pos, true, sequence, "stopped destroying");
|
||||
} else if (action == ServerboundPlayerActionPacket.Action.ABORT_DESTROY_BLOCK) {
|
||||
this.isDestroyingBlock = false;
|
||||
- if (!Objects.equals(this.destroyPos, pos)) {
|
||||
+ if (!Objects.equals(this.destroyPos, pos) && !BlockPos.ZERO.equals(this.destroyPos)) { // Paper
|
||||
ServerPlayerGameMode.LOGGER.debug("Mismatch in destroy block pos: {} {}", this.destroyPos, pos); // CraftBukkit - SPIGOT-5457 sent by client when interact event cancelled
|
||||
- this.level.destroyBlockProgress(this.player.getId(), this.destroyPos, -1);
|
||||
- this.debugLogging(pos, true, sequence, "aborted mismatched destroying");
|
||||
+ BlockState type = this.level.getBlockStateIfLoaded(this.destroyPos); // Paper - don't load unloaded chunks for stale records here
|
||||
+ if (type != null) this.level.destroyBlockProgress(this.player.getId(), this.destroyPos, -1);
|
||||
+ if (type != null) this.debugLogging(pos, true, sequence, "aborted mismatched destroying");
|
||||
+ this.destroyPos = BlockPos.ZERO; // Paper
|
||||
}
|
||||
|
||||
this.level.destroyBlockProgress(this.player.getId(), pos, -1);
|
||||
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 extends ServerCommonPacketListenerImpl
|
||||
case START_DESTROY_BLOCK:
|
||||
case ABORT_DESTROY_BLOCK:
|
||||
case STOP_DESTROY_BLOCK:
|
||||
+ // Paper start - Don't allow digging into unloaded chunks
|
||||
+ if (this.player.level().getChunkIfLoadedImmediately(blockposition.getX() >> 4, blockposition.getZ() >> 4) == null) {
|
||||
+ this.player.connection.ackBlockChangesUpTo(packet.getSequence());
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end - Don't allow digging into unloaded chunks
|
||||
this.player.gameMode.handleBlockBreakAction(blockposition, packetplayinblockdig_enumplayerdigtype, packet.getDirection(), this.player.level().getMaxBuildHeight(), packet.getSequence());
|
||||
this.player.connection.ackBlockChangesUpTo(packet.getSequence());
|
||||
return;
|
@@ -1,33 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 23 Oct 2018 20:25:05 -0400
|
||||
Subject: [PATCH] Don't sleep after profile lookups if not needed
|
||||
|
||||
Mojang was sleeping even if we had no more requests to go after
|
||||
the current one finished, resulting in 100ms lost per profile lookup
|
||||
|
||||
diff --git a/src/main/java/com/mojang/authlib/yggdrasil/YggdrasilGameProfileRepository.java b/src/main/java/com/mojang/authlib/yggdrasil/YggdrasilGameProfileRepository.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/com/mojang/authlib/yggdrasil/YggdrasilGameProfileRepository.java
|
||||
+++ b/src/main/java/com/mojang/authlib/yggdrasil/YggdrasilGameProfileRepository.java
|
||||
@@ -0,0 +0,0 @@ public class YggdrasilGameProfileRepository implements GameProfileRepository {
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
final int page = 0;
|
||||
+ boolean hasRequested = false; // Paper - Don't sleep after profile lookups if not needed
|
||||
|
||||
for (final List<String> request : Iterables.partition(criteria, ENTRIES_PER_PAGE)) {
|
||||
final List<String> normalizedRequest = request.stream().map(YggdrasilGameProfileRepository::normalizeName).toList();
|
||||
@@ -0,0 +0,0 @@ public class YggdrasilGameProfileRepository implements GameProfileRepository {
|
||||
LOGGER.debug("Couldn't find profile {}", name);
|
||||
callback.onProfileLookupFailed(name, new ProfileNotFoundException("Server did not find the requested profile"));
|
||||
}
|
||||
+ // Paper start - Don't sleep after profile lookups if not needed
|
||||
+ if (!hasRequested) {
|
||||
+ hasRequested = true;
|
||||
+ continue;
|
||||
+ }
|
||||
+ // Paper end - Don't sleep after profile lookups if not needed
|
||||
|
||||
try {
|
||||
Thread.sleep(DELAY_BETWEEN_PAGES);
|
@@ -1,26 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <1254957+zachbr@users.noreply.github.com>
|
||||
Date: Mon, 4 Feb 2019 23:33:24 -0500
|
||||
Subject: [PATCH] Dont block Player#remove if the handle is a custom player
|
||||
|
||||
Upstream throws UOE if you try to call remove on a Player.
|
||||
We just add a check to ensure that the CraftPlayer's handle
|
||||
is a ServerPlayer
|
||||
|
||||
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 {
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
+ if (this.getHandle().getClass().equals(ServerPlayer.class)) { // special case for NMS plugins inheriting
|
||||
// Will lead to an inconsistent player state if we remove the player as any other entity.
|
||||
throw new UnsupportedOperationException(String.format("Cannot remove player %s, use Player#kickPlayer(String) instead.", this.getName()));
|
||||
+ } else {
|
||||
+ super.remove();
|
||||
+ }
|
||||
}
|
||||
|
||||
@Override
|
@@ -1,53 +0,0 @@
|
||||
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 - EnderDragon Events
|
||||
this.dragon.level().addFreshEntity(this.flame);
|
||||
+ // Paper start - EnderDragon Events
|
||||
+ } else {
|
||||
+ this.end();
|
||||
+ }
|
||||
+ // Paper end - EnderDragon Events
|
||||
}
|
||||
|
||||
}
|
||||
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 - EnderDragon Events
|
||||
this.dragon.level().addFreshEntity(dragonFireball);
|
||||
+ else dragonFireball.discard(null); // Paper - EnderDragon Events
|
||||
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) entityareaeffectcloud.getBukkitEntity()).callEvent()) { // Paper - EnderDragon Events
|
||||
this.level().levelEvent(2006, this.blockPosition(), this.isSilent() ? -1 : 1);
|
||||
this.level().addFreshEntity(entityareaeffectcloud);
|
||||
+ } else entityareaeffectcloud.discard(null); // Paper - EnderDragon Events
|
||||
this.discard(EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause
|
||||
}
|
||||
|
@@ -1,169 +0,0 @@
|
||||
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] Expand 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.checkArgument(slot != null, "slot");
|
||||
+ com.google.common.base.Preconditions.checkArgument(slot != EquipmentSlot.BODY, "Cannot get body item");
|
||||
+ 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.checkArgument(slot != null, "slot");
|
||||
+ com.google.common.base.Preconditions.checkArgument(slot != EquipmentSlot.BODY, "Cannot set body item");
|
||||
+ 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;
|
@@ -1,24 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Wed, 20 Jun 2018 23:17:24 -0400
|
||||
Subject: [PATCH] Expand Explosions API
|
||||
|
||||
Add Entity as a Source capability, and add more API choices, and on Location.
|
||||
|
||||
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 {
|
||||
|
||||
return !this.world.explode(source == null ? null : ((CraftEntity) source).getHandle(), x, y, z, power, setFire, explosionType).wasCanceled;
|
||||
}
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public boolean createExplosion(Entity source, Location loc, float power, boolean setFire, boolean breakBlocks) {
|
||||
+ return !world.explode(source != null ? ((org.bukkit.craftbukkit.entity.CraftEntity) source).getHandle() : null, loc.getX(), loc.getY(), loc.getZ(), power, setFire, breakBlocks ? net.minecraft.world.level.Level.ExplosionInteraction.MOB : net.minecraft.world.level.Level.ExplosionInteraction.NONE).wasCanceled;
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
@Override
|
||||
public boolean createExplosion(Location loc, float power) {
|
@@ -1,32 +0,0 @@
|
||||
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()
|
@@ -1,46 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sun, 10 Jun 2018 20:20:15 -0400
|
||||
Subject: [PATCH] Fix CraftEntity hashCode
|
||||
|
||||
hashCodes are not allowed to change, however bukkit used a value
|
||||
that does change, the entityId.
|
||||
|
||||
When an entity is teleported dimensions, the entity reference is
|
||||
replaced with a new one with a new entity ID.
|
||||
|
||||
For hashCode, we can simply use the UUID's hashCode to keep
|
||||
the hashCode from changing.
|
||||
|
||||
equals() is ok to use getEntityId() because equals() should only
|
||||
be true if both the left and right are the same reference.
|
||||
|
||||
Since entity ids can not duplicate during runtime, this
|
||||
check is essentially the same as this.getHandle() == other.getHandle()
|
||||
|
||||
However, replaced it too to make it clearer of intent.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
|
||||
return false;
|
||||
}
|
||||
final CraftEntity other = (CraftEntity) obj;
|
||||
- return (this.getEntityId() == other.getEntityId());
|
||||
+ return (this.getHandle() == other.getHandle()); // Paper - while logically the same, this is clearer
|
||||
}
|
||||
|
||||
+ // Paper - Fix hashCode. entity ID's are not static.
|
||||
+ // A CraftEntity can change reference to a new entity with a new ID, and hash codes should never change
|
||||
@Override
|
||||
public int hashCode() {
|
||||
- int hash = 7;
|
||||
- hash = 29 * hash + this.getEntityId();
|
||||
- return hash;
|
||||
+ return getUniqueId().hashCode();
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
@Override
|
@@ -1,44 +0,0 @@
|
||||
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"));
|
||||
}
|
||||
|
@@ -1,23 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shane Freeder <theboyetronic@gmail.com>
|
||||
Date: Sat, 10 Nov 2018 05:15:21 +0000
|
||||
Subject: [PATCH] Fix SpongeAbsortEvent handling
|
||||
|
||||
Only process drops when the block is actually going to be removed
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/SpongeBlock.java b/src/main/java/net/minecraft/world/level/block/SpongeBlock.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/SpongeBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/SpongeBlock.java
|
||||
@@ -0,0 +0,0 @@ public class SpongeBlock extends Block {
|
||||
} else if (iblockdata.is(Blocks.KELP) || iblockdata.is(Blocks.KELP_PLANT) || iblockdata.is(Blocks.SEAGRASS) || iblockdata.is(Blocks.TALL_SEAGRASS)) {
|
||||
BlockEntity tileentity = iblockdata.hasBlockEntity() ? world.getBlockEntity(blockposition1) : null;
|
||||
|
||||
+ // Paper start - Fix SpongeAbsortEvent handling
|
||||
+ if (block.getHandle().isAir()) {
|
||||
dropResources(iblockdata, world, blockposition1, tileentity);
|
||||
+ }
|
||||
+ // Paper end - Fix SpongeAbsortEvent handling
|
||||
}
|
||||
}
|
||||
world.setBlock(blockposition1, block.getHandle(), block.getFlag());
|
@@ -1,38 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Sun, 23 Sep 2018 20:59:53 -0500
|
||||
Subject: [PATCH] Honor EntityAgeable.ageLock
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/AgeableMob.java b/src/main/java/net/minecraft/world/entity/AgeableMob.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/AgeableMob.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/AgeableMob.java
|
||||
@@ -0,0 +0,0 @@ public abstract class AgeableMob extends PathfinderMob {
|
||||
}
|
||||
|
||||
public void ageUp(int age, boolean overGrow) {
|
||||
+ if (this.ageLocked) return; // Paper - Honor ageLock
|
||||
int j = this.getAge();
|
||||
int k = j;
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java
|
||||
@@ -0,0 +0,0 @@ public class BeehiveBlockEntity extends BlockEntity {
|
||||
}
|
||||
|
||||
private static void setBeeReleaseData(int ticksInHive, Bee beeEntity) {
|
||||
+ if (!beeEntity.ageLocked) { // Paper - Honor ageLock
|
||||
int j = beeEntity.getAge();
|
||||
|
||||
if (j < 0) {
|
||||
@@ -0,0 +0,0 @@ public class BeehiveBlockEntity extends BlockEntity {
|
||||
}
|
||||
|
||||
beeEntity.setInLoveTime(Math.max(0, beeEntity.getInLoveTime() - ticksInHive));
|
||||
+ } // Paper - Honor ageLock
|
||||
}
|
||||
}
|
||||
|
@@ -1,26 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Brokkonaut <hannos17@gmx.de>
|
||||
Date: Tue, 3 Jul 2018 16:08:14 +0200
|
||||
Subject: [PATCH] Implement World.getEntity(UUID) API
|
||||
|
||||
|
||||
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 {
|
||||
return list;
|
||||
}
|
||||
|
||||
+ // Paper start - getEntity by UUID API
|
||||
+ @Override
|
||||
+ public Entity getEntity(UUID uuid) {
|
||||
+ Preconditions.checkArgument(uuid != null, "UUID cannot be null");
|
||||
+ net.minecraft.world.entity.Entity entity = world.getEntity(uuid);
|
||||
+ return entity == null ? null : entity.getBukkitEntity();
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public void save() {
|
||||
org.spigotmc.AsyncCatcher.catchOp("world save"); // Spigot
|
@@ -1,131 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Tassu <git@tassu.me>
|
||||
Date: Thu, 13 Sep 2018 08:45:21 +0300
|
||||
Subject: [PATCH] Implement furnace cook speed multiplier API
|
||||
|
||||
Fixed an issue where a furnace's cook-speed multiplier rounds down
|
||||
to the nearest Integer when updating its current cook time.
|
||||
|
||||
Co-authored-by: Eric Su <ericsu@alumni.usc.edu>
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit
|
||||
protected NonNullList<ItemStack> items;
|
||||
public int litTime;
|
||||
int litDuration;
|
||||
+ public double cookSpeedMultiplier = 1.0; // Paper - cook speed multiplier API
|
||||
public int cookingProgress;
|
||||
public int cookingTotalTime;
|
||||
@Nullable
|
||||
@@ -0,0 +0,0 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit
|
||||
protected final ContainerData dataAccess;
|
||||
public final Object2IntOpenHashMap<ResourceLocation> recipesUsed;
|
||||
private final RecipeManager.CachedCheck<Container, ? extends AbstractCookingRecipe> quickCheck;
|
||||
+ public final RecipeType<? extends AbstractCookingRecipe> recipeType; // Paper - cook speed multiplier API
|
||||
|
||||
protected AbstractFurnaceBlockEntity(BlockEntityType<?> blockEntityType, BlockPos pos, BlockState state, RecipeType<? extends AbstractCookingRecipe> recipeType) {
|
||||
super(blockEntityType, pos, state);
|
||||
@@ -0,0 +0,0 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit
|
||||
};
|
||||
this.recipesUsed = new Object2IntOpenHashMap();
|
||||
this.quickCheck = RecipeManager.createCheck((RecipeType<AbstractCookingRecipe>) recipeType); // CraftBukkit - decompile error // Eclipse fail
|
||||
+ this.recipeType = recipeType; // Paper - cook speed multiplier API
|
||||
}
|
||||
|
||||
public static void invalidateCache() {
|
||||
@@ -0,0 +0,0 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit
|
||||
this.recipesUsed.put(new ResourceLocation(s), nbttagcompound1.getInt(s));
|
||||
}
|
||||
|
||||
+ // Paper start - cook speed multiplier API
|
||||
+ if (nbt.contains("Paper.CookSpeedMultiplier")) {
|
||||
+ this.cookSpeedMultiplier = nbt.getDouble("Paper.CookSpeedMultiplier");
|
||||
+ }
|
||||
+ // Paper end - cook speed multiplier API
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -0,0 +0,0 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit
|
||||
nbt.putShort("BurnTime", (short) this.litTime);
|
||||
nbt.putShort("CookTime", (short) this.cookingProgress);
|
||||
nbt.putShort("CookTimeTotal", (short) this.cookingTotalTime);
|
||||
+ nbt.putDouble("Paper.CookSpeedMultiplier", this.cookSpeedMultiplier); // Paper - cook speed multiplier API
|
||||
ContainerHelper.saveAllItems(nbt, this.items, registryLookup);
|
||||
CompoundTag nbttagcompound1 = new CompoundTag();
|
||||
|
||||
@@ -0,0 +0,0 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit
|
||||
CraftItemStack source = CraftItemStack.asCraftMirror(blockEntity.items.get(0));
|
||||
CookingRecipe<?> recipe = (CookingRecipe<?>) recipeholder.toBukkitRecipe();
|
||||
|
||||
- FurnaceStartSmeltEvent event = new FurnaceStartSmeltEvent(CraftBlock.at(world, pos), source, recipe);
|
||||
+ FurnaceStartSmeltEvent event = new FurnaceStartSmeltEvent(CraftBlock.at(world, pos), source, recipe, AbstractFurnaceBlockEntity.getTotalCookTime(world, blockEntity.recipeType, blockEntity, blockEntity.cookSpeedMultiplier)); // Paper - cook speed multiplier API
|
||||
world.getCraftServer().getPluginManager().callEvent(event);
|
||||
|
||||
blockEntity.cookingTotalTime = event.getTotalCookTime();
|
||||
@@ -0,0 +0,0 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit
|
||||
// CraftBukkit end
|
||||
|
||||
++blockEntity.cookingProgress;
|
||||
- if (blockEntity.cookingProgress == blockEntity.cookingTotalTime) {
|
||||
+ if (blockEntity.cookingProgress >= blockEntity.cookingTotalTime) { // Paper - cook speed multiplier API
|
||||
blockEntity.cookingProgress = 0;
|
||||
- blockEntity.cookingTotalTime = AbstractFurnaceBlockEntity.getTotalCookTime(world, blockEntity);
|
||||
+ blockEntity.cookingTotalTime = AbstractFurnaceBlockEntity.getTotalCookTime(world, blockEntity.recipeType, blockEntity, blockEntity.cookSpeedMultiplier); // Paper - cook speed multiplier API
|
||||
if (AbstractFurnaceBlockEntity.burn(blockEntity.level, blockEntity.worldPosition, world.registryAccess(), recipeholder, blockEntity.items, i)) { // CraftBukkit
|
||||
blockEntity.setRecipeUsed(recipeholder);
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit
|
||||
}
|
||||
}
|
||||
|
||||
- private static int getTotalCookTime(Level world, AbstractFurnaceBlockEntity furnace) {
|
||||
- if (world == null) return 200; // CraftBukkit - SPIGOT-4302
|
||||
- return (Integer) furnace.quickCheck.getRecipeFor(furnace, world).map((recipeholder) -> {
|
||||
- return ((AbstractCookingRecipe) recipeholder.value()).getCookingTime();
|
||||
- }).orElse(200);
|
||||
+ // Paper start - cook speed multiplier API
|
||||
+ public static int getTotalCookTime(@Nullable Level world, RecipeType<? extends AbstractCookingRecipe> recipeType, AbstractFurnaceBlockEntity furnace, double cookSpeedMultiplier) {
|
||||
+ /* Scale the recipe's cooking time to the current cookSpeedMultiplier */
|
||||
+ int cookTime = world != null ? furnace.quickCheck.getRecipeFor(furnace, world).map(holder -> holder.value().getCookingTime()).orElse(200) : (net.minecraft.server.MinecraftServer.getServer().getRecipeManager().getRecipeFor(recipeType, furnace, world /* passing a null level here is safe. world is only used for map extending recipes which won't happen here */).map(holder -> holder.value().getCookingTime()).orElse(200));
|
||||
+ return (int) Math.ceil (cookTime / cookSpeedMultiplier);
|
||||
+ // Paper end - cook speed multiplier API
|
||||
}
|
||||
|
||||
public static boolean isFuel(ItemStack stack) {
|
||||
@@ -0,0 +0,0 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit
|
||||
this.items.set(slot, stack);
|
||||
stack.limitSize(this.getMaxStackSize(stack));
|
||||
if (slot == 0 && !flag) {
|
||||
- this.cookingTotalTime = AbstractFurnaceBlockEntity.getTotalCookTime(this.level, this);
|
||||
+ this.cookingTotalTime = AbstractFurnaceBlockEntity.getTotalCookTime(this.level, this.recipeType, this, this.cookSpeedMultiplier); // Paper - cook speed multiplier API
|
||||
this.cookingProgress = 0;
|
||||
this.setChanged();
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftFurnace.java b/src/main/java/org/bukkit/craftbukkit/block/CraftFurnace.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftFurnace.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftFurnace.java
|
||||
@@ -0,0 +0,0 @@ public abstract class CraftFurnace<T extends AbstractFurnaceBlockEntity> extends
|
||||
|
||||
@Override
|
||||
public abstract CraftFurnace<T> copy(Location location);
|
||||
+
|
||||
+ // Paper start - cook speed multiplier API
|
||||
+ @Override
|
||||
+ public double getCookSpeedMultiplier() {
|
||||
+ return this.getSnapshot().cookSpeedMultiplier;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setCookSpeedMultiplier(double multiplier) {
|
||||
+ com.google.common.base.Preconditions.checkArgument(multiplier >= 0, "Furnace speed multiplier cannot be negative");
|
||||
+ com.google.common.base.Preconditions.checkArgument(multiplier <= 200, "Furnace speed multiplier cannot more than 200");
|
||||
+ T snapshot = this.getSnapshot();
|
||||
+ snapshot.cookSpeedMultiplier = multiplier;
|
||||
+ snapshot.cookingTotalTime = AbstractFurnaceBlockEntity.getTotalCookTime(this.isPlaced() ? this.world.getHandle() : null, snapshot.recipeType, snapshot, snapshot.cookSpeedMultiplier); // Update the snapshot's current total cook time to scale with the newly set multiplier
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
@@ -1,60 +0,0 @@
|
||||
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 - Perf: Final for inline
|
||||
return this == object || object instanceof Vec3i vec3i && this.getX() == vec3i.getX() && this.getY() == vec3i.getY() && this.getZ() == vec3i.getZ();
|
||||
}
|
||||
|
||||
@Override
|
||||
- public int hashCode() {
|
||||
+ public final int hashCode() { // Paper - Perf: Final for inline
|
||||
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 - Perf: Final for inline
|
||||
return this.x;
|
||||
}
|
||||
|
||||
- public int getY() {
|
||||
+ public final int getY() { // Paper - Perf: Final for inline
|
||||
return this.y;
|
||||
}
|
||||
|
||||
- public int getZ() {
|
||||
+ public final int getZ() { // Paper - Perf: Final for inline
|
||||
return this.z;
|
||||
}
|
||||
|
@@ -1,47 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sat, 15 Jun 2013 19:51:17 -0400
|
||||
Subject: [PATCH] Improve EntityShootBowEvent
|
||||
|
||||
Adds missing call to Illagers and also adds Arrow ItemStack to skeletons
|
||||
|
||||
== AT ==
|
||||
public net.minecraft.world.entity.projectile.AbstractArrow getPickupItem()Lnet.minecraft.world.item.ItemStack;
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java b/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java
|
||||
@@ -0,0 +0,0 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo
|
||||
|
||||
entityarrow.shoot(d0, d1 + d3 * 0.20000000298023224D, d2, 1.6F, (float) (14 - this.level().getDifficulty().getId() * 4));
|
||||
// CraftBukkit start
|
||||
- org.bukkit.event.entity.EntityShootBowEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityShootBowEvent(this, this.getMainHandItem(), null, entityarrow, net.minecraft.world.InteractionHand.MAIN_HAND, 0.8F, true);
|
||||
+ org.bukkit.event.entity.EntityShootBowEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityShootBowEvent(this, this.getMainHandItem(), entityarrow.getPickupItem(), entityarrow, net.minecraft.world.InteractionHand.MAIN_HAND, 0.8F, true); // Paper
|
||||
if (event.isCancelled()) {
|
||||
event.getProjectile().remove();
|
||||
return;
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/Illusioner.java b/src/main/java/net/minecraft/world/entity/monster/Illusioner.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Illusioner.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Illusioner.java
|
||||
@@ -0,0 +0,0 @@ public class Illusioner extends SpellcasterIllager implements RangedAttackMob {
|
||||
double d3 = Math.sqrt(d0 * d0 + d2 * d2);
|
||||
|
||||
entityarrow.shoot(d0, d1 + d3 * 0.20000000298023224D, d2, 1.6F, (float) (14 - this.level().getDifficulty().getId() * 4));
|
||||
+ // Paper start - EntityShootBowEvent
|
||||
+ org.bukkit.event.entity.EntityShootBowEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityShootBowEvent(this, this.getMainHandItem(), entityarrow.getPickupItem(), entityarrow, target.getUsedItemHand(), 0.8F, true);
|
||||
+ if (event.isCancelled()) {
|
||||
+ event.getProjectile().remove();
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (event.getProjectile() == entityarrow.getBukkitEntity()) {
|
||||
+ this.level().addFreshEntity(entityarrow);
|
||||
+ }
|
||||
+ // Paper end - EntityShootBowEvent
|
||||
this.playSound(SoundEvents.SKELETON_SHOOT, 1.0F, 1.0F / (this.getRandom().nextFloat() * 0.4F + 0.8F));
|
||||
- this.level().addFreshEntity(entityarrow);
|
||||
}
|
||||
|
||||
@Override
|
@@ -1,105 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 23 Oct 2018 23:14:38 -0400
|
||||
Subject: [PATCH] Improve Server Thread Pool and Thread Priorities
|
||||
|
||||
Use a simple executor since Fork join is a much more complex pool
|
||||
type and we are not using its capabilities.
|
||||
|
||||
Set thread priorities so main thread has above normal priority over
|
||||
server threads
|
||||
|
||||
Allow usage of a single thread executor by not using ForkJoin so single core CPU's
|
||||
and reduce worldgen thread worker count for low core count CPUs.
|
||||
|
||||
== AT ==
|
||||
public net.minecraft.Util onThreadException(Ljava/lang/Thread;Ljava/lang/Throwable;)V
|
||||
|
||||
Co-authored-by: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
|
||||
diff --git a/src/main/java/io/papermc/paper/util/ServerWorkerThread.java b/src/main/java/io/papermc/paper/util/ServerWorkerThread.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/util/ServerWorkerThread.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package io.papermc.paper.util;
|
||||
+
|
||||
+import java.util.concurrent.atomic.AtomicInteger;
|
||||
+import net.minecraft.Util;
|
||||
+
|
||||
+public class ServerWorkerThread extends Thread {
|
||||
+ private static final AtomicInteger threadId = new AtomicInteger(1);
|
||||
+ public ServerWorkerThread(Runnable target, String poolName, int prioritityModifier) {
|
||||
+ super(target, "Worker-" + poolName + "-" + threadId.getAndIncrement());
|
||||
+ setPriority(Thread.NORM_PRIORITY+prioritityModifier); // Deprioritize over main
|
||||
+ this.setDaemon(true);
|
||||
+ this.setUncaughtExceptionHandler(Util::onThreadException);
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/net/minecraft/Util.java b/src/main/java/net/minecraft/Util.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/Util.java
|
||||
+++ b/src/main/java/net/minecraft/Util.java
|
||||
@@ -0,0 +0,0 @@ public class Util {
|
||||
private static final int DEFAULT_MAX_THREADS = 255;
|
||||
private static final int DEFAULT_SAFE_FILE_OPERATION_RETRIES = 10;
|
||||
private static final String MAX_THREADS_SYSTEM_PROPERTY = "max.bg.threads";
|
||||
- private static final ExecutorService BACKGROUND_EXECUTOR = makeExecutor("Main");
|
||||
+ private static final ExecutorService BACKGROUND_EXECUTOR = makeExecutor("Main", -1); // Paper - Perf: add priority
|
||||
private static final ExecutorService IO_POOL = makeIoExecutor("IO-Worker-", false);
|
||||
private static final ExecutorService DOWNLOAD_POOL = makeIoExecutor("Download-", true);
|
||||
// Paper start - don't submit BLOCKING PROFILE LOOKUPS to the world gen thread
|
||||
@@ -0,0 +0,0 @@ public class Util {
|
||||
return FILENAME_DATE_TIME_FORMATTER.format(ZonedDateTime.now());
|
||||
}
|
||||
|
||||
- private static ExecutorService makeExecutor(String name) {
|
||||
- int i = Mth.clamp(Runtime.getRuntime().availableProcessors() - 1, 1, getMaxThreads());
|
||||
+ private static ExecutorService makeExecutor(String s, int priorityModifier) { // Paper - Perf: add priority
|
||||
+ // Paper start - Perf: use simpler thread pool that allows 1 thread and reduce worldgen thread worker count for low core count CPUs
|
||||
+ int cpus = Runtime.getRuntime().availableProcessors() / 2;
|
||||
+ int i;
|
||||
+ if (cpus <= 4) {
|
||||
+ i = cpus <= 2 ? 1 : 2;
|
||||
+ } else if (cpus <= 8) {
|
||||
+ // [5, 8]
|
||||
+ i = Math.max(3, cpus - 2);
|
||||
+ } else {
|
||||
+ i = cpus * 2 / 3;
|
||||
+ }
|
||||
+ i = Math.min(8, i);
|
||||
+ i = Integer.getInteger("Paper.WorkerThreadCount", i);
|
||||
ExecutorService executorService;
|
||||
if (i <= 0) {
|
||||
executorService = MoreExecutors.newDirectExecutorService();
|
||||
} else {
|
||||
- AtomicInteger atomicInteger = new AtomicInteger(1);
|
||||
- executorService = new ForkJoinPool(i, pool -> {
|
||||
- ForkJoinWorkerThread forkJoinWorkerThread = new ForkJoinWorkerThread(pool) {
|
||||
+ executorService = new java.util.concurrent.ThreadPoolExecutor(i, i,0L, TimeUnit.MILLISECONDS, new java.util.concurrent.LinkedBlockingQueue<>(), target -> new io.papermc.paper.util.ServerWorkerThread(target, s, priorityModifier));
|
||||
+ }
|
||||
+ /*
|
||||
@Override
|
||||
protected void onTermination(Throwable throwable) {
|
||||
if (throwable != null) {
|
||||
@@ -0,0 +0,0 @@ public class Util {
|
||||
return forkJoinWorkerThread;
|
||||
}, Util::onThreadException, true);
|
||||
}
|
||||
+ }*/ // Paper end - Perf: use simpler thread pool
|
||||
|
||||
return executorService;
|
||||
}
|
||||
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
|
||||
thread.setUncaughtExceptionHandler((thread1, throwable) -> {
|
||||
MinecraftServer.LOGGER.error("Uncaught exception in server thread", throwable);
|
||||
});
|
||||
+ thread.setPriority(Thread.NORM_PRIORITY+2); // Paper - Perf: Boost priority
|
||||
if (Runtime.getRuntime().availableProcessors() > 4) {
|
||||
thread.setPriority(8);
|
||||
}
|
@@ -1,516 +0,0 @@
|
||||
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 {
|
||||
private int containerCounter;
|
||||
public boolean wonGame;
|
||||
private int containerUpdateDelay; // Paper - Configurable container update tick rate
|
||||
+ // Paper start - cancellable death event
|
||||
+ public boolean queueHealthUpdatePacket;
|
||||
+ public net.minecraft.network.protocol.game.ClientboundSetHealthPacket queuedHealthUpdatePacket;
|
||||
+ // Paper end - cancellable death event
|
||||
|
||||
// CraftBukkit start
|
||||
public CraftPlayer.TransferCookieConnection transferCookieConnection;
|
||||
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
|
||||
|
||||
@Override
|
||||
public void die(DamageSource damageSource) {
|
||||
- this.gameEvent(GameEvent.ENTITY_DIE);
|
||||
+ // this.gameEvent(GameEvent.ENTITY_DIE); // Paper - move below event cancellation check
|
||||
boolean flag = this.level().getGameRules().getBoolean(GameRules.RULE_SHOWDEATHMESSAGES);
|
||||
// CraftBukkit start - fire PlayerDeathEvent
|
||||
if (this.isRemoved()) {
|
||||
@@ -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, damageSource, loot, PaperAdventure.asAdventure(defaultMessage), 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;
|
||||
+ }
|
||||
+ this.gameEvent(GameEvent.ENTITY_DIE); // moved from the top of this method
|
||||
+ // 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 (this.isDeadOrDying()) {
|
||||
if (!this.checkTotemDeathProtection(source)) {
|
||||
- if (flag1) {
|
||||
- this.makeSound(this.getDeathSound());
|
||||
- }
|
||||
+ // 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 {
|
||||
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 (!this.level().isClientSide && this.hasCustomName()) {
|
||||
+ if (org.spigotmc.SpigotConfig.logNamedDeaths) LivingEntity.LOGGER.info("Named entity {} died: {}", this, this.getCombatTracker().getDeathMessage().getString()); // Spigot
|
||||
+ }
|
||||
|
||||
- if (entity == null || entity.killedEntity(worldserver, this)) {
|
||||
+ this.getCombatTracker().recheckStatus();
|
||||
+ if (entity != null) {
|
||||
+ entity.killedEntity((ServerLevel) this.level(), this);
|
||||
+ }
|
||||
this.gameEvent(GameEvent.ENTITY_DIE);
|
||||
- this.dropAllDeathLoot(damageSource);
|
||||
- this.createWitherRose(entityliving);
|
||||
+ } else {
|
||||
+ this.dead = false;
|
||||
+ this.setHealth((float) deathEvent.getReviveHealth());
|
||||
}
|
||||
|
||||
- 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, source, this.drops);
|
||||
+ org.bukkit.event.entity.EntityDeathEvent deathEvent = CraftEventFactory.callEntityDeathEvent(this, source, 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 EquipmentUser, Targeti
|
||||
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ protected boolean shouldSkipLoot(EquipmentSlot slot) { // method to avoid to fallback into the global mob loot logic (i.e fox)
|
||||
+ return false;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
protected void dropCustomDeathLoot(DamageSource source, int lootingMultiplier, boolean allowDrops) {
|
||||
super.dropCustomDeathLoot(source, lootingMultiplier, allowDrops);
|
||||
@@ -0,0 +0,0 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti
|
||||
|
||||
for (int k = 0; k < j; ++k) {
|
||||
EquipmentSlot enumitemslot = aenumitemslot[k];
|
||||
+ if (this.shouldSkipLoot(enumitemslot)) continue; // Paper
|
||||
ItemStack itemstack = this.getItemBySlot(enumitemslot);
|
||||
float f = this.getEquipmentDropChance(enumitemslot);
|
||||
boolean flag1 = f > 1.0F;
|
||||
@@ -0,0 +0,0 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Targeti
|
||||
}
|
||||
|
||||
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> {
|
||||
return this.getTrustedUUIDs().contains(uuid);
|
||||
}
|
||||
|
||||
+ // Paper start - handle the bitten item separately like vanilla
|
||||
@Override
|
||||
- protected void dropAllDeathLoot(DamageSource source) {
|
||||
+ protected boolean shouldSkipLoot(EquipmentSlot slot) {
|
||||
+ return slot == EquipmentSlot.MAINHAND;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
+ @Override
|
||||
+ // Paper start - Cancellable death event
|
||||
+ protected org.bukkit.event.entity.EntityDeathEvent dropAllDeathLoot(DamageSource source) {
|
||||
ItemStack itemstack = this.getItemBySlot(EquipmentSlot.MAINHAND);
|
||||
|
||||
- if (!itemstack.isEmpty()) {
|
||||
+ boolean releaseMouth = false;
|
||||
+ if (!itemstack.isEmpty() && this.level().getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { // Fix MC-153010
|
||||
this.spawnAtLocation(itemstack);
|
||||
+ releaseMouth = true;
|
||||
+ }
|
||||
+
|
||||
+ org.bukkit.event.entity.EntityDeathEvent deathEvent = super.dropAllDeathLoot(source);
|
||||
+
|
||||
+ // Below is code to drop
|
||||
+
|
||||
+ if (deathEvent == null || deathEvent.isCancelled()) {
|
||||
+ return deathEvent;
|
||||
+ }
|
||||
+
|
||||
+ if (releaseMouth) {
|
||||
+ // Paper end - Cancellable death event
|
||||
this.setItemSlot(EquipmentSlot.MAINHAND, ItemStack.EMPTY);
|
||||
}
|
||||
|
||||
- super.dropAllDeathLoot(source);
|
||||
+ return deathEvent; // Paper - Cancellable death event
|
||||
}
|
||||
|
||||
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); // 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) {
|
||||
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 {
|
||||
}
|
||||
// CraftBukkit end
|
||||
if (source.is(DamageTypeTags.IS_EXPLOSION)) {
|
||||
- this.brokenByAnything(source);
|
||||
- this.kill(source); // CraftBukkit
|
||||
+ // Paper start - avoid duplicate event call
|
||||
+ org.bukkit.event.entity.EntityDeathEvent event = this.brokenByAnything(source);
|
||||
+ if (!event.isCancelled()) this.kill(source, false); // CraftBukkit
|
||||
+ // Paper end
|
||||
return false;
|
||||
} else if (source.is(DamageTypeTags.IGNITES_ARMOR_STANDS)) {
|
||||
if (this.isOnFire()) {
|
||||
@@ -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();
|
||||
- this.discard(EntityRemoveEvent.Cause.DEATH); // CraftBukkit - SPIGOT-4890: remain as this.discard() since above damagesource method will call death event
|
||||
+ if (!event.isCancelled()) this.kill(source, false); // Paper - we still need to kill to follow vanilla logic (emit the game event etc...)
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -0,0 +0,0 @@ public class ArmorStand extends LivingEntity {
|
||||
|
||||
f1 -= amount;
|
||||
if (f1 <= 0.5F) {
|
||||
- this.brokenByAnything(damageSource);
|
||||
- this.kill(damageSource); // CraftBukkit
|
||||
+ // Paper start - avoid duplicate event call
|
||||
+ org.bukkit.event.entity.EntityDeathEvent event = this.brokenByAnything(damageSource);
|
||||
+ if (!event.isCancelled()) this.kill(damageSource, false); // CraftBukkit
|
||||
+ // Paper end
|
||||
} else {
|
||||
this.setHealth(f1);
|
||||
this.gameEvent(GameEvent.ENTITY_DAMAGE, damageSource.getEntity());
|
||||
@@ -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);
|
||||
|
||||
itemstack.set(DataComponents.CUSTOM_NAME, this.getCustomName());
|
||||
this.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 {
|
||||
}
|
||||
|
||||
public void kill(DamageSource damageSource) {
|
||||
- org.bukkit.craftbukkit.event.CraftEventFactory.callEntityDeathEvent(this, (damageSource == null ? this.damageSources().genericKill() : damageSource), this.drops); // CraftBukkit - call event
|
||||
+ // Paper start - make cancellable
|
||||
+ this.kill(damageSource, true);
|
||||
+ }
|
||||
+ public void kill(DamageSource damageSource, boolean callEvent) {
|
||||
+ if (callEvent) {
|
||||
+ org.bukkit.event.entity.EntityDeathEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityDeathEvent(this, (damageSource == null ? this.damageSources().genericKill() : damageSource), this.drops); // CraftBukkit - call event
|
||||
+ if (event.isCancelled()) return;
|
||||
+ }
|
||||
+ // Paper end
|
||||
this.remove(Entity.RemovalReason.KILLED, EntityRemoveEvent.Cause.DEATH); // CraftBukkit - add Bukkit remove cause
|
||||
// CraftBukkit end
|
||||
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 {
|
||||
@Override
|
||||
public void sendHealthUpdate() {
|
||||
FoodData foodData = this.getHandle().getFoodData();
|
||||
- this.sendHealthUpdate(this.getScaledHealth(), foodData.getFoodLevel(), foodData.getSaturationLevel());
|
||||
+ // Paper start - cancellable death event
|
||||
+ ClientboundSetHealthPacket packet = new ClientboundSetHealthPacket(this.getScaledHealth(), foodData.getFoodLevel(), foodData.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 {
|
||||
CraftLivingEntity entity = (CraftLivingEntity) victim.getBukkitEntity();
|
||||
CraftDamageSource bukkitDamageSource = new CraftDamageSource(damageSource);
|
||||
EntityDeathEvent event = new EntityDeathEvent(entity, bukkitDamageSource, 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, bukkitDamageSource, drops, victim.getExpReward(), 0, deathMessage);
|
||||
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.minecraftToBukkit(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.bukkitToMinecraft(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
|
||||
*/
|
@@ -1,383 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Sun, 25 Jun 2023 23:10:14 -0700
|
||||
Subject: [PATCH] Improve exact choice recipe ingredients
|
||||
|
||||
Fixes exact choices not working with recipe book clicks
|
||||
and shapeless recipes.
|
||||
|
||||
== AT ==
|
||||
public net.minecraft.world.item.ItemStackLinkedSet TYPE_AND_TAG
|
||||
public net.minecraft.world.entity.player.StackedContents put(II)V
|
||||
|
||||
diff --git a/src/main/java/io/papermc/paper/inventory/recipe/RecipeBookExactChoiceRecipe.java b/src/main/java/io/papermc/paper/inventory/recipe/RecipeBookExactChoiceRecipe.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/inventory/recipe/RecipeBookExactChoiceRecipe.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package io.papermc.paper.inventory.recipe;
|
||||
+
|
||||
+import net.minecraft.world.Container;
|
||||
+import net.minecraft.world.item.crafting.Ingredient;
|
||||
+import net.minecraft.world.item.crafting.Recipe;
|
||||
+
|
||||
+public abstract class RecipeBookExactChoiceRecipe<C extends Container> implements Recipe<C> {
|
||||
+
|
||||
+ private boolean hasExactIngredients;
|
||||
+
|
||||
+ protected final void checkExactIngredients() {
|
||||
+ // skip any special recipes
|
||||
+ if (this.isSpecial()) {
|
||||
+ this.hasExactIngredients = false;
|
||||
+ return;
|
||||
+ }
|
||||
+ for (final Ingredient ingredient : this.getIngredients()) {
|
||||
+ if (!ingredient.isEmpty() && ingredient.exact) {
|
||||
+ this.hasExactIngredients = true;
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+ this.hasExactIngredients = false;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public final boolean hasExactIngredients() {
|
||||
+ return this.hasExactIngredients;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/io/papermc/paper/inventory/recipe/StackedContentsExtraMap.java b/src/main/java/io/papermc/paper/inventory/recipe/StackedContentsExtraMap.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/inventory/recipe/StackedContentsExtraMap.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package io.papermc.paper.inventory.recipe;
|
||||
+
|
||||
+import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
+import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
+import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
+import it.unimi.dsi.fastutil.ints.IntComparators;
|
||||
+import it.unimi.dsi.fastutil.ints.IntList;
|
||||
+import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
+import it.unimi.dsi.fastutil.objects.Object2IntOpenCustomHashMap;
|
||||
+import java.util.IdentityHashMap;
|
||||
+import java.util.Map;
|
||||
+import java.util.concurrent.atomic.AtomicInteger;
|
||||
+import net.minecraft.core.registries.BuiltInRegistries;
|
||||
+import net.minecraft.world.entity.player.StackedContents;
|
||||
+import net.minecraft.world.item.ItemStack;
|
||||
+import net.minecraft.world.item.ItemStackLinkedSet;
|
||||
+import net.minecraft.world.item.crafting.Ingredient;
|
||||
+import net.minecraft.world.item.crafting.Recipe;
|
||||
+
|
||||
+public final class StackedContentsExtraMap {
|
||||
+
|
||||
+ private final AtomicInteger idCounter = new AtomicInteger(BuiltInRegistries.ITEM.size()); // start at max vanilla stacked contents idx
|
||||
+ private final Object2IntMap<ItemStack> exactChoiceIds = new Object2IntOpenCustomHashMap<>(ItemStackLinkedSet.TYPE_AND_TAG);
|
||||
+ private final Int2ObjectMap<ItemStack> idToExactChoice = new Int2ObjectOpenHashMap<>();
|
||||
+ private final StackedContents contents;
|
||||
+ public final Map<Ingredient, IntList> extraStackingIds = new IdentityHashMap<>();
|
||||
+
|
||||
+ public StackedContentsExtraMap(final StackedContents contents, final Recipe<?> recipe) {
|
||||
+ this.exactChoiceIds.defaultReturnValue(-1);
|
||||
+ this.contents = contents;
|
||||
+ this.initialize(recipe);
|
||||
+ }
|
||||
+
|
||||
+ private void initialize(final Recipe<?> recipe) {
|
||||
+ if (recipe.hasExactIngredients()) {
|
||||
+ for (final Ingredient ingredient : recipe.getIngredients()) {
|
||||
+ if (!ingredient.isEmpty() && ingredient.exact) {
|
||||
+ final net.minecraft.world.item.ItemStack[] items = ingredient.getItems();
|
||||
+ final IntList idList = new IntArrayList(items.length);
|
||||
+ for (final ItemStack item : items) {
|
||||
+ idList.add(this.registerExact(item)); // I think not copying the stack here is safe because cb copies the stack when creating the ingredient
|
||||
+ if (item.getComponentsPatch().isEmpty()) {
|
||||
+ // add regular index if it's a plain itemstack but still registered as exact
|
||||
+ idList.add(StackedContents.getStackingIndex(item));
|
||||
+ }
|
||||
+ }
|
||||
+ idList.sort(IntComparators.NATURAL_COMPARATOR);
|
||||
+ this.extraStackingIds.put(ingredient, idList);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private int registerExact(final ItemStack exactChoice) {
|
||||
+ final int existing = this.exactChoiceIds.getInt(exactChoice);
|
||||
+ if (existing > -1) {
|
||||
+ return existing;
|
||||
+ }
|
||||
+ final int id = this.idCounter.getAndIncrement();
|
||||
+ this.exactChoiceIds.put(exactChoice, id);
|
||||
+ this.idToExactChoice.put(id, exactChoice);
|
||||
+ return id;
|
||||
+ }
|
||||
+
|
||||
+ public ItemStack getById(int id) {
|
||||
+ return this.idToExactChoice.get(id);
|
||||
+ }
|
||||
+
|
||||
+ public boolean accountStack(final ItemStack stack, final int count) {
|
||||
+ if (!this.exactChoiceIds.isEmpty()) {
|
||||
+ final int id = this.exactChoiceIds.getInt(stack);
|
||||
+ if (id >= 0) {
|
||||
+ this.contents.put(id, count);
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+ return false;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/io/papermc/paper/inventory/recipe/package-info.java b/src/main/java/io/papermc/paper/inventory/recipe/package-info.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/inventory/recipe/package-info.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+@DefaultQualifier(NonNull.class)
|
||||
+package io.papermc.paper.inventory.recipe;
|
||||
+
|
||||
+import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
+import org.checkerframework.framework.qual.DefaultQualifier;
|
||||
diff --git a/src/main/java/net/minecraft/recipebook/ServerPlaceRecipe.java b/src/main/java/net/minecraft/recipebook/ServerPlaceRecipe.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/recipebook/ServerPlaceRecipe.java
|
||||
+++ b/src/main/java/net/minecraft/recipebook/ServerPlaceRecipe.java
|
||||
@@ -0,0 +0,0 @@ public class ServerPlaceRecipe<C extends Container> implements PlaceRecipe<Integ
|
||||
this.inventory = entity.getInventory();
|
||||
if (this.testClearGrid() || entity.isCreative()) {
|
||||
this.stackedContents.clear();
|
||||
+ this.stackedContents.initialize(recipe.value()); // Paper - Improve exact choice recipe ingredients
|
||||
entity.getInventory().fillStackedContents(this.stackedContents);
|
||||
this.menu.fillCraftSlotsStackedContents(this.stackedContents);
|
||||
if (this.stackedContents.canCraft((Recipe<?>)recipe.value(), null)) {
|
||||
@@ -0,0 +0,0 @@ public class ServerPlaceRecipe<C extends Container> implements PlaceRecipe<Integ
|
||||
int l = k;
|
||||
|
||||
for (int m : intList) {
|
||||
- ItemStack itemStack2 = StackedContents.fromStackingIndex(m);
|
||||
+ ItemStack itemStack2 = StackedContents.fromStackingIndexWithExtras(m, this.stackedContents); // Paper - Improve exact choice recipe ingredients
|
||||
if (!itemStack2.isEmpty()) {
|
||||
int n = itemStack2.getMaxStackSize();
|
||||
if (n < l) {
|
||||
@@ -0,0 +0,0 @@ public class ServerPlaceRecipe<C extends Container> implements PlaceRecipe<Integ
|
||||
@Override
|
||||
public void addItemToSlot(Iterator<Integer> inputs, int slot, int amount, int gridX, int gridY) {
|
||||
Slot slot2 = this.menu.getSlot(slot);
|
||||
- ItemStack itemStack = StackedContents.fromStackingIndex(inputs.next());
|
||||
+ // Paper start - Improve exact choice recipe ingredients
|
||||
+ final int itemId = inputs.next();
|
||||
+ ItemStack itemStack = null;
|
||||
+ boolean isExact = false;
|
||||
+ if (this.stackedContents.extrasMap != null && itemId >= net.minecraft.core.registries.BuiltInRegistries.ITEM.size()) {
|
||||
+ itemStack = StackedContents.fromStackingIndexExtras(itemId, this.stackedContents.extrasMap).copy();
|
||||
+ isExact = true;
|
||||
+ }
|
||||
+ if (itemStack == null) {
|
||||
+ itemStack = StackedContents.fromStackingIndex(itemId);
|
||||
+ }
|
||||
+ // Paper end - Improve exact choice recipe ingredients
|
||||
if (!itemStack.isEmpty()) {
|
||||
for (int i = 0; i < amount; i++) {
|
||||
- this.moveItemToGrid(slot2, itemStack);
|
||||
+ this.moveItemToGrid(slot2, itemStack, isExact); // Paper - Improve exact choice recipe ingredients
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class ServerPlaceRecipe<C extends Container> implements PlaceRecipe<Integ
|
||||
return i;
|
||||
}
|
||||
|
||||
+ @Deprecated @io.papermc.paper.annotation.DoNotUse // Paper - Improve exact choice recipe ingredients
|
||||
protected void moveItemToGrid(Slot slot, ItemStack stack) {
|
||||
- int i = this.inventory.findSlotMatchingUnusedItem(stack);
|
||||
+ // Paper start - Improve exact choice recipe ingredients
|
||||
+ this.moveItemToGrid(slot, stack, false);
|
||||
+ }
|
||||
+ protected void moveItemToGrid(Slot slot, ItemStack stack, final boolean isExact) {
|
||||
+ int i = isExact ? this.inventory.findSlotMatchingItem(stack) : this.inventory.findSlotMatchingUnusedItem(stack);
|
||||
+ // Paper end - Improve exact choice recipe ingredients
|
||||
if (i != -1) {
|
||||
ItemStack itemStack = this.inventory.getItem(i);
|
||||
if (!itemStack.isEmpty()) {
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/player/StackedContents.java b/src/main/java/net/minecraft/world/entity/player/StackedContents.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/player/StackedContents.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/player/StackedContents.java
|
||||
@@ -0,0 +0,0 @@ import net.minecraft.world.item.crafting.RecipeHolder;
|
||||
public class StackedContents {
|
||||
private static final int EMPTY = 0;
|
||||
public final Int2IntMap contents = new Int2IntOpenHashMap();
|
||||
+ @Nullable public io.papermc.paper.inventory.recipe.StackedContentsExtraMap extrasMap = null; // Paper - Improve exact choice recipe ingredients
|
||||
|
||||
public void accountSimpleStack(ItemStack stack) {
|
||||
+ if (this.extrasMap != null && !stack.getComponentsPatch().isEmpty() && this.extrasMap.accountStack(stack, Math.min(64, stack.getCount()))) return; // Paper - Improve exact choice recipe ingredients; max of 64 due to accountStack method below
|
||||
if (!stack.isDamaged() && !stack.isEnchanted() && !stack.has(DataComponents.CUSTOM_NAME)) {
|
||||
this.accountStack(stack);
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class StackedContents {
|
||||
if (!stack.isEmpty()) {
|
||||
int i = getStackingIndex(stack);
|
||||
int j = Math.min(maxCount, stack.getCount());
|
||||
+ if (this.extrasMap != null && !stack.getComponentsPatch().isEmpty() && this.extrasMap.accountStack(stack, j)) return; // Paper - Improve exact choice recipe ingredients; if an exact ingredient, don't include it
|
||||
this.put(i, j);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class StackedContents {
|
||||
return itemId == 0 ? ItemStack.EMPTY : new ItemStack(Item.byId(itemId));
|
||||
}
|
||||
|
||||
+ // Paper start - Improve exact choice recipe ingredients
|
||||
+ public void initialize(final Recipe<?> recipe) {
|
||||
+ this.extrasMap = new io.papermc.paper.inventory.recipe.StackedContentsExtraMap(this, recipe);
|
||||
+ }
|
||||
+
|
||||
+ public static ItemStack fromStackingIndexWithExtras(final int itemId, @Nullable final StackedContents contents) {
|
||||
+ if (contents != null && contents.extrasMap != null && itemId >= BuiltInRegistries.ITEM.size()) {
|
||||
+ return fromStackingIndexExtras(itemId, contents.extrasMap);
|
||||
+ }
|
||||
+ return fromStackingIndex(itemId);
|
||||
+ }
|
||||
+
|
||||
+ public static ItemStack fromStackingIndexExtras(final int itemId, final io.papermc.paper.inventory.recipe.StackedContentsExtraMap extrasMap) {
|
||||
+ return extrasMap.getById(itemId).copy();
|
||||
+ }
|
||||
+ // Paper end - Improve exact choice recipe ingredients
|
||||
+
|
||||
public void clear() {
|
||||
this.contents.clear();
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class StackedContents {
|
||||
this.data = new BitSet(this.ingredientCount + this.itemCount + this.ingredientCount + this.ingredientCount * this.itemCount);
|
||||
|
||||
for (int i = 0; i < this.ingredients.size(); i++) {
|
||||
- IntList intList = this.ingredients.get(i).getStackingIds();
|
||||
+ IntList intList = this.getStackingIds(this.ingredients.get(i)); // Paper - Improve exact choice recipe ingredients
|
||||
|
||||
for (int j = 0; j < this.itemCount; j++) {
|
||||
if (intList.contains(this.items[j])) {
|
||||
@@ -0,0 +0,0 @@ public class StackedContents {
|
||||
IntCollection intCollection = new IntAVLTreeSet();
|
||||
|
||||
for (Ingredient ingredient : this.ingredients) {
|
||||
- intCollection.addAll(ingredient.getStackingIds());
|
||||
+ intCollection.addAll(this.getStackingIds(ingredient)); // Paper - Improve exact choice recipe ingredients
|
||||
}
|
||||
|
||||
IntIterator intIterator = intCollection.iterator();
|
||||
@@ -0,0 +0,0 @@ public class StackedContents {
|
||||
for (Ingredient ingredient : this.ingredients) {
|
||||
int j = 0;
|
||||
|
||||
- for (int k : ingredient.getStackingIds()) {
|
||||
+ for (int k : this.getStackingIds(ingredient)) { // Paper - Improve exact choice recipe ingredients
|
||||
j = Math.max(j, StackedContents.this.contents.get(k));
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ public class StackedContents {
|
||||
|
||||
return i;
|
||||
}
|
||||
+
|
||||
+ // Paper start - Improve exact choice recipe ingredients
|
||||
+ private IntList getStackingIds(final Ingredient ingredient) {
|
||||
+ if (StackedContents.this.extrasMap != null) {
|
||||
+ final IntList ids = StackedContents.this.extrasMap.extraStackingIds.get(ingredient);
|
||||
+ if (ids != null) {
|
||||
+ return ids;
|
||||
+ }
|
||||
+ }
|
||||
+ return ingredient.getStackingIds();
|
||||
+ }
|
||||
+ // Paper end - Improve exact choice recipe ingredients
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/item/crafting/AbstractCookingRecipe.java b/src/main/java/net/minecraft/world/item/crafting/AbstractCookingRecipe.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/crafting/AbstractCookingRecipe.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/crafting/AbstractCookingRecipe.java
|
||||
@@ -0,0 +0,0 @@ import net.minecraft.world.Container;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
|
||||
-public abstract class AbstractCookingRecipe implements Recipe<Container> {
|
||||
+public abstract class AbstractCookingRecipe extends io.papermc.paper.inventory.recipe.RecipeBookExactChoiceRecipe<Container> implements Recipe<Container> { // Paper - improve exact recipe choices
|
||||
protected final RecipeType<?> type;
|
||||
protected final CookingBookCategory category;
|
||||
protected final String group;
|
||||
@@ -0,0 +0,0 @@ public abstract class AbstractCookingRecipe implements Recipe<Container> {
|
||||
this.result = result;
|
||||
this.experience = experience;
|
||||
this.cookingTime = cookingTime;
|
||||
+ this.checkExactIngredients(); // Paper - improve exact recipe choices
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/net/minecraft/world/item/crafting/Recipe.java b/src/main/java/net/minecraft/world/item/crafting/Recipe.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/crafting/Recipe.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/crafting/Recipe.java
|
||||
@@ -0,0 +0,0 @@ public interface Recipe<C extends Container> {
|
||||
}
|
||||
|
||||
org.bukkit.inventory.Recipe toBukkitRecipe(org.bukkit.NamespacedKey id); // CraftBukkit
|
||||
+
|
||||
+ // Paper start - improved exact choice recipes
|
||||
+ default boolean hasExactIngredients() {
|
||||
+ return false;
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/item/crafting/ShapedRecipe.java b/src/main/java/net/minecraft/world/item/crafting/ShapedRecipe.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/crafting/ShapedRecipe.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/crafting/ShapedRecipe.java
|
||||
@@ -0,0 +0,0 @@ import org.bukkit.craftbukkit.inventory.CraftShapedRecipe;
|
||||
import org.bukkit.inventory.RecipeChoice;
|
||||
// CraftBukkit end
|
||||
|
||||
-public class ShapedRecipe implements CraftingRecipe {
|
||||
+public class ShapedRecipe extends io.papermc.paper.inventory.recipe.RecipeBookExactChoiceRecipe<CraftingContainer> implements CraftingRecipe { // Paper - improve exact recipe choices
|
||||
|
||||
final ShapedRecipePattern pattern;
|
||||
final ItemStack result;
|
||||
@@ -0,0 +0,0 @@ public class ShapedRecipe implements CraftingRecipe {
|
||||
this.pattern = raw;
|
||||
this.result = result;
|
||||
this.showNotification = showNotification;
|
||||
+ this.checkExactIngredients(); // Paper - improve exact recipe choices
|
||||
}
|
||||
|
||||
public ShapedRecipe(String group, CraftingBookCategory category, ShapedRecipePattern raw, ItemStack result) {
|
||||
diff --git a/src/main/java/net/minecraft/world/item/crafting/ShapelessRecipe.java b/src/main/java/net/minecraft/world/item/crafting/ShapelessRecipe.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/crafting/ShapelessRecipe.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/crafting/ShapelessRecipe.java
|
||||
@@ -0,0 +0,0 @@ import org.bukkit.craftbukkit.inventory.CraftRecipe;
|
||||
import org.bukkit.craftbukkit.inventory.CraftShapelessRecipe;
|
||||
// CraftBukkit end
|
||||
|
||||
-public class ShapelessRecipe implements CraftingRecipe {
|
||||
+public class ShapelessRecipe extends io.papermc.paper.inventory.recipe.RecipeBookExactChoiceRecipe<CraftingContainer> implements CraftingRecipe { // Paper - improve exact recipe choices
|
||||
|
||||
final String group;
|
||||
final CraftingBookCategory category;
|
||||
@@ -0,0 +0,0 @@ public class ShapelessRecipe implements CraftingRecipe {
|
||||
this.category = category;
|
||||
this.result = result;
|
||||
this.ingredients = ingredients;
|
||||
+ this.checkExactIngredients(); // Paper - improve exact recipe choices
|
||||
}
|
||||
|
||||
// CraftBukkit start
|
||||
@@ -0,0 +0,0 @@ public class ShapelessRecipe implements CraftingRecipe {
|
||||
|
||||
public boolean matches(CraftingContainer inventory, Level world) {
|
||||
StackedContents autorecipestackmanager = new StackedContents();
|
||||
+ autorecipestackmanager.initialize(this); // Paper - better exact choice recipes
|
||||
int i = 0;
|
||||
|
||||
for (int j = 0; j < inventory.getContainerSize(); ++j) {
|
@@ -1,58 +0,0 @@
|
||||
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
|
||||
Preconditions.checkArgument(items != null, "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) {
|
@@ -1,212 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 3 Jul 2018 21:56:23 -0400
|
||||
Subject: [PATCH] InventoryCloseEvent Reason API
|
||||
|
||||
Allows you to determine why an inventory was closed, enabling plugin developers
|
||||
to "confirm" things based on if it was player triggered close or not.
|
||||
|
||||
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 {
|
||||
for (net.minecraft.world.level.block.entity.BlockEntity tileentity : chunk.getBlockEntities().values()) {
|
||||
if (tileentity instanceof net.minecraft.world.Container) {
|
||||
for (org.bukkit.entity.HumanEntity h : Lists.newArrayList(((net.minecraft.world.Container) tileentity).getViewers())) {
|
||||
- h.closeInventory();
|
||||
+ h.closeInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason.UNLOADED); // Paper - Inventory close reason
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
||||
// Spigot Start
|
||||
if (entity.getBukkitEntity() instanceof org.bukkit.inventory.InventoryHolder && (!(entity instanceof ServerPlayer) || entity.getRemovalReason() != Entity.RemovalReason.KILLED)) { // SPIGOT-6876: closeInventory clears death message
|
||||
for (org.bukkit.entity.HumanEntity h : Lists.newArrayList(((org.bukkit.inventory.InventoryHolder) entity.getBukkitEntity()).getInventory().getViewers())) {
|
||||
- h.closeInventory();
|
||||
+ h.closeInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason.UNLOADED); // Paper - Inventory close reason
|
||||
}
|
||||
}
|
||||
// Spigot End
|
||||
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 {
|
||||
}
|
||||
// Paper end - Configurable container update tick rate
|
||||
if (!this.level().isClientSide && !this.containerMenu.stillValid(this)) {
|
||||
- this.closeContainer();
|
||||
+ this.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.CANT_USE); // Paper - Inventory close reason
|
||||
this.containerMenu = this.inventoryMenu;
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
|
||||
|
||||
// SPIGOT-943 - only call if they have an inventory open
|
||||
if (this.containerMenu != this.inventoryMenu) {
|
||||
- this.closeContainer();
|
||||
+ this.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.DEATH); // Paper - Inventory close reason
|
||||
}
|
||||
|
||||
net.kyori.adventure.text.Component deathMessage = event.deathMessage() != null ? event.deathMessage() : net.kyori.adventure.text.Component.empty(); // Paper - Adventure
|
||||
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
|
||||
}
|
||||
// CraftBukkit end
|
||||
if (this.containerMenu != this.inventoryMenu) {
|
||||
- this.closeContainer();
|
||||
+ this.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.OPEN_NEW); // Paper - Inventory close reason
|
||||
}
|
||||
|
||||
// this.nextContainerCounter(); // CraftBukkit - moved up
|
||||
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
|
||||
|
||||
@Override
|
||||
public void closeContainer() {
|
||||
- CraftEventFactory.handleInventoryCloseEvent(this); // CraftBukkit
|
||||
+ // Paper start - Inventory close reason
|
||||
+ this.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.UNKNOWN);
|
||||
+ }
|
||||
+ @Override
|
||||
+ public void closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason reason) {
|
||||
+ CraftEventFactory.handleInventoryCloseEvent(this, reason); // CraftBukkit
|
||||
+ // Paper end - Inventory close reason
|
||||
this.connection.send(new ClientboundContainerClosePacket(this.containerMenu.containerId));
|
||||
this.doCloseContainer();
|
||||
}
|
||||
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 extends ServerCommonPacketListenerImpl
|
||||
|
||||
@Override
|
||||
public void handleContainerClose(ServerboundContainerClosePacket packet) {
|
||||
+ // Paper start - Inventory close reason
|
||||
+ this.handleContainerClose(packet, org.bukkit.event.inventory.InventoryCloseEvent.Reason.PLAYER);
|
||||
+ }
|
||||
+ public void handleContainerClose(ServerboundContainerClosePacket packet, org.bukkit.event.inventory.InventoryCloseEvent.Reason reason) {
|
||||
+ // Paper end - Inventory close reason
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
|
||||
|
||||
if (this.player.isImmobile()) return; // CraftBukkit
|
||||
- CraftEventFactory.handleInventoryCloseEvent(this.player); // CraftBukkit
|
||||
+ CraftEventFactory.handleInventoryCloseEvent(this.player, reason); // CraftBukkit // Paper
|
||||
|
||||
this.player.doCloseContainer();
|
||||
}
|
||||
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 {
|
||||
// CraftBukkit start - Quitting must be before we do final save of data, in case plugins need to modify it
|
||||
// See SPIGOT-5799, SPIGOT-6145
|
||||
if (entityplayer.containerMenu != entityplayer.inventoryMenu) {
|
||||
- entityplayer.closeContainer();
|
||||
+ entityplayer.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.DISCONNECT); // Paper - Inventory close reason
|
||||
}
|
||||
|
||||
PlayerQuitEvent playerQuitEvent = new PlayerQuitEvent(entityplayer.getBukkitEntity(), net.kyori.adventure.text.Component.translatable("multiplayer.player.left", net.kyori.adventure.text.format.NamedTextColor.YELLOW, io.papermc.paper.configuration.GlobalConfiguration.get().messages.useDisplayNameInQuitMessage ? entityplayer.getBukkitEntity().displayName() : io.papermc.paper.adventure.PaperAdventure.asAdventure(entityplayer.getDisplayName()))); // Paper - Adventure
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Player extends LivingEntity {
|
||||
this.updateIsUnderwater();
|
||||
super.tick();
|
||||
if (!this.level().isClientSide && this.containerMenu != null && !this.containerMenu.stillValid(this)) {
|
||||
- this.closeContainer();
|
||||
+ this.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.CANT_USE); // Paper - Inventory close reason
|
||||
this.containerMenu = this.inventoryMenu;
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ public abstract class Player extends LivingEntity {
|
||||
|
||||
}
|
||||
|
||||
+ // Paper start - Inventory close reason; unused code, but to keep signatures aligned
|
||||
+ public void closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason reason) {
|
||||
+ closeContainer();
|
||||
+ this.containerMenu = this.inventoryMenu;
|
||||
+ }
|
||||
+ // Paper end - Inventory close reason
|
||||
+
|
||||
public void closeContainer() {
|
||||
this.containerMenu = this.inventoryMenu;
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
|
||||
@@ -0,0 +0,0 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
|
||||
if (((ServerPlayer) this.getHandle()).connection == null) return;
|
||||
if (this.getHandle().containerMenu != this.getHandle().inventoryMenu) {
|
||||
// fire INVENTORY_CLOSE if one already open
|
||||
- ((ServerPlayer) this.getHandle()).connection.handleContainerClose(new ServerboundContainerClosePacket(this.getHandle().containerMenu.containerId));
|
||||
+ ((ServerPlayer) this.getHandle()).connection.handleContainerClose(new ServerboundContainerClosePacket(this.getHandle().containerMenu.containerId), org.bukkit.event.inventory.InventoryCloseEvent.Reason.OPEN_NEW); // Paper - Inventory close reason
|
||||
}
|
||||
ServerPlayer player = (ServerPlayer) this.getHandle();
|
||||
AbstractContainerMenu container;
|
||||
@@ -0,0 +0,0 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
|
||||
|
||||
@Override
|
||||
public void closeInventory() {
|
||||
- this.getHandle().closeContainer();
|
||||
+ // Paper start - Inventory close reason
|
||||
+ this.getHandle().closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.PLUGIN);
|
||||
}
|
||||
+ @Override
|
||||
+ public void closeInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason reason) {
|
||||
+ getHandle().closeContainer(reason);
|
||||
+ }
|
||||
+ // Paper end - Inventory close reason
|
||||
|
||||
@Override
|
||||
public boolean isBlocking() {
|
||||
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 {
|
||||
|
||||
// Close any foreign inventory
|
||||
if (this.getHandle().containerMenu != this.getHandle().inventoryMenu) {
|
||||
- this.getHandle().closeContainer();
|
||||
+ this.getHandle().closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.TELEPORT); // Paper - Inventory close reason
|
||||
}
|
||||
|
||||
// Check if the fromWorld and toWorld are the same.
|
||||
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 AbstractContainerMenu callInventoryOpenEvent(ServerPlayer player, AbstractContainerMenu container, boolean cancelled) {
|
||||
if (player.containerMenu != player.inventoryMenu) { // fire INVENTORY_CLOSE if one already open
|
||||
- player.connection.handleContainerClose(new ServerboundContainerClosePacket(player.containerMenu.containerId));
|
||||
+ player.connection.handleContainerClose(new ServerboundContainerClosePacket(player.containerMenu.containerId), InventoryCloseEvent.Reason.OPEN_NEW); // Paper - Inventory close reason
|
||||
}
|
||||
|
||||
CraftServer server = player.level().getCraftServer();
|
||||
@@ -0,0 +0,0 @@ public class CraftEventFactory {
|
||||
return event;
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Incase plugins hooked into this or Spigot adds a new inventory close event. Prefer to pass a reason
|
||||
+ * @param human
|
||||
+ */
|
||||
+ @Deprecated
|
||||
public static void handleInventoryCloseEvent(net.minecraft.world.entity.player.Player human) {
|
||||
- InventoryCloseEvent event = new InventoryCloseEvent(human.containerMenu.getBukkitView());
|
||||
+ handleInventoryCloseEvent(human, org.bukkit.event.inventory.InventoryCloseEvent.Reason.UNKNOWN);
|
||||
+ }
|
||||
+ public static void handleInventoryCloseEvent(net.minecraft.world.entity.player.Player human, org.bukkit.event.inventory.InventoryCloseEvent.Reason reason) {
|
||||
+ // Paper end
|
||||
+ InventoryCloseEvent event = new InventoryCloseEvent(human.containerMenu.getBukkitView(), reason); // Paper
|
||||
human.level().getCraftServer().getPluginManager().callEvent(event);
|
||||
human.containerMenu.transferTo(human.inventoryMenu, human.getBukkitEntity());
|
||||
}
|
@@ -1,72 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Fri, 29 Jun 2018 00:21:28 -0400
|
||||
Subject: [PATCH] LivingEntity Active Item API
|
||||
|
||||
API relating to items being actively used by a LivingEntity
|
||||
such as a bow or eating food.
|
||||
|
||||
== AT ==
|
||||
public net/minecraft/world/entity/LivingEntity completeUsingItem()V
|
||||
public net/minecraft/server/level/ServerPlayer completeUsingItem()V
|
||||
|
||||
Co-authored-by: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
|
||||
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 {
|
||||
getHandle().setShieldBlockingDelay(delay);
|
||||
}
|
||||
// Paper end
|
||||
+
|
||||
+ // Paper start - active item API
|
||||
+ @Override
|
||||
+ public void startUsingItem(org.bukkit.inventory.EquipmentSlot hand) {
|
||||
+ Preconditions.checkArgument(hand != null, "hand must not be null");
|
||||
+ switch (hand) {
|
||||
+ case HAND -> getHandle().startUsingItem(InteractionHand.MAIN_HAND);
|
||||
+ case OFF_HAND -> getHandle().startUsingItem(InteractionHand.OFF_HAND);
|
||||
+ default -> throw new IllegalArgumentException("hand may only be HAND or OFF_HAND");
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void completeUsingActiveItem() {
|
||||
+ getHandle().completeUsingItem();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public ItemStack getActiveItem() {
|
||||
+ return this.getHandle().getUseItem().asBukkitMirror();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getActiveItemRemainingTime() {
|
||||
+ return this.getHandle().getUseItemRemainingTicks();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setActiveItemRemainingTime(final int ticks) {
|
||||
+ Preconditions.checkArgument(ticks >= 0, "ticks must be >= 0");
|
||||
+ Preconditions.checkArgument(ticks <= this.getHandle().getUseItem().getUseDuration(), "ticks must be <= item use duration");
|
||||
+ this.getHandle().useItemRemaining = ticks;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getActiveItemUsedTime() {
|
||||
+ return this.getHandle().getTicksUsingItem();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean hasActiveItem() {
|
||||
+ return this.getHandle().isUsingItem();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public org.bukkit.inventory.EquipmentSlot getActiveItemHand() {
|
||||
+ return org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(this.getHandle().getUsedItemHand());
|
||||
+ }
|
||||
+ // Paper end - active item API
|
||||
}
|
@@ -1,20 +0,0 @@
|
||||
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) {
|
@@ -1,56 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Sat, 16 Jun 2018 01:18:16 -0500
|
||||
Subject: [PATCH] Make shield blocking delay configurable
|
||||
|
||||
|
||||
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 {
|
||||
if (this.isUsingItem() && !this.useItem.isEmpty()) {
|
||||
Item item = this.useItem.getItem();
|
||||
|
||||
- return item.getUseAnimation(this.useItem) != UseAnim.BLOCK ? false : item.getUseDuration(this.useItem) - this.useItemRemaining >= 5;
|
||||
+ return item.getUseAnimation(this.useItem) != UseAnim.BLOCK ? false : item.getUseDuration(this.useItem) - this.useItemRemaining >= getShieldBlockingDelay(); // Paper - Make shield blocking delay configurable
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+ // Paper start - Make shield blocking delay configurable
|
||||
+ public int shieldBlockingDelay = this.level().paperConfig().misc.shieldBlockingDelay;
|
||||
+
|
||||
+ public int getShieldBlockingDelay() {
|
||||
+ return shieldBlockingDelay;
|
||||
+ }
|
||||
+
|
||||
+ public void setShieldBlockingDelay(int shieldBlockingDelay) {
|
||||
+ this.shieldBlockingDelay = shieldBlockingDelay;
|
||||
+ }
|
||||
+ // Paper end - Make shield blocking delay configurable
|
||||
+
|
||||
public boolean isSuppressingSlidingDownLadder() {
|
||||
return this.isShiftKeyDown();
|
||||
}
|
||||
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 {
|
||||
public void setArrowsStuck(final int arrows) {
|
||||
this.getHandle().setArrowCount(arrows);
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public int getShieldBlockingDelay() {
|
||||
+ return getHandle().getShieldBlockingDelay();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setShieldBlockingDelay(int delay) {
|
||||
+ getHandle().setShieldBlockingDelay(delay);
|
||||
+ }
|
||||
// Paper end
|
||||
}
|
@@ -1,40 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shane Freeder <theboyetronic@gmail.com>
|
||||
Date: Sun, 18 Nov 2018 19:49:56 +0000
|
||||
Subject: [PATCH] Make the default permission message configurable
|
||||
|
||||
|
||||
diff --git a/src/main/java/io/papermc/paper/command/PaperCommand.java b/src/main/java/io/papermc/paper/command/PaperCommand.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/io/papermc/paper/command/PaperCommand.java
|
||||
+++ b/src/main/java/io/papermc/paper/command/PaperCommand.java
|
||||
@@ -0,0 +0,0 @@ public final class PaperCommand extends Command {
|
||||
if (sender.hasPermission(BASE_PERM + permission) || sender.hasPermission("bukkit.command.paper")) {
|
||||
return true;
|
||||
}
|
||||
- sender.sendMessage(text("I'm sorry, but you do not have permission to perform this command. Please contact the server administrators if you believe that this is in error.", RED));
|
||||
+ sender.sendMessage(Bukkit.permissionMessage());
|
||||
return false;
|
||||
}
|
||||
|
||||
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 {
|
||||
return io.papermc.paper.configuration.GlobalConfiguration.get().commands.suggestPlayerNamesWhenNullTabCompletions;
|
||||
}
|
||||
|
||||
+ @Override
|
||||
+ public String getPermissionMessage() {
|
||||
+ return net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacyAmpersand().serialize(io.papermc.paper.configuration.GlobalConfiguration.get().messages.noPermission);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public net.kyori.adventure.text.Component permissionMessage() {
|
||||
+ return io.papermc.paper.configuration.GlobalConfiguration.get().messages.noPermission;
|
||||
+ }
|
||||
+
|
||||
@Override
|
||||
public com.destroystokyo.paper.profile.PlayerProfile createProfile(@Nonnull UUID uuid) {
|
||||
return createProfile(uuid, null);
|
@@ -1,209 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sun, 9 Sep 2018 13:30:00 -0400
|
||||
Subject: [PATCH] Mob Pathfinding API
|
||||
|
||||
Implements Pathfinding API for mobs
|
||||
|
||||
== AT ==
|
||||
public net.minecraft.world.entity.ai.navigation.PathNavigation pathFinder
|
||||
public net.minecraft.world.level.pathfinder.PathFinder nodeEvaluator
|
||||
public net.minecraft.world.level.pathfinder.Path nodes
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/entity/PaperPathfinder.java b/src/main/java/com/destroystokyo/paper/entity/PaperPathfinder.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/entity/PaperPathfinder.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package com.destroystokyo.paper.entity;
|
||||
+
|
||||
+import org.apache.commons.lang.Validate;
|
||||
+import org.bukkit.Location;
|
||||
+import org.bukkit.craftbukkit.entity.CraftLivingEntity;
|
||||
+import org.bukkit.entity.LivingEntity;
|
||||
+import org.bukkit.entity.Mob;
|
||||
+import javax.annotation.Nonnull;
|
||||
+import javax.annotation.Nullable;
|
||||
+import net.minecraft.world.level.pathfinder.Node;
|
||||
+import net.minecraft.world.level.pathfinder.Path;
|
||||
+import java.util.ArrayList;
|
||||
+import java.util.List;
|
||||
+
|
||||
+public class PaperPathfinder implements com.destroystokyo.paper.entity.Pathfinder {
|
||||
+
|
||||
+ private net.minecraft.world.entity.Mob entity;
|
||||
+
|
||||
+ public PaperPathfinder(net.minecraft.world.entity.Mob entity) {
|
||||
+ this.entity = entity;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public Mob getEntity() {
|
||||
+ return entity.getBukkitMob();
|
||||
+ }
|
||||
+
|
||||
+ public void setHandle(net.minecraft.world.entity.Mob entity) {
|
||||
+ this.entity = entity;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void stopPathfinding() {
|
||||
+ entity.getNavigation().stop();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean hasPath() {
|
||||
+ return entity.getNavigation().getPath() != null && !entity.getNavigation().getPath().isDone();
|
||||
+ }
|
||||
+
|
||||
+ @Nullable
|
||||
+ @Override
|
||||
+ public PathResult getCurrentPath() {
|
||||
+ Path path = entity.getNavigation().getPath();
|
||||
+ return path != null && !path.isDone() ? new PaperPathResult(path) : null;
|
||||
+ }
|
||||
+
|
||||
+ @Nullable
|
||||
+ @Override
|
||||
+ public PathResult findPath(Location loc) {
|
||||
+ Validate.notNull(loc, "Location can not be null");
|
||||
+ Path path = entity.getNavigation().createPath(loc.getX(), loc.getY(), loc.getZ(), 0);
|
||||
+ return path != null ? new PaperPathResult(path) : null;
|
||||
+ }
|
||||
+
|
||||
+ @Nullable
|
||||
+ @Override
|
||||
+ public PathResult findPath(LivingEntity target) {
|
||||
+ Validate.notNull(target, "Target can not be null");
|
||||
+ Path path = entity.getNavigation().createPath(((CraftLivingEntity) target).getHandle(), 0);
|
||||
+ return path != null ? new PaperPathResult(path) : null;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean moveTo(@Nonnull PathResult path, double speed) {
|
||||
+ Validate.notNull(path, "PathResult can not be null");
|
||||
+ Path pathEntity = ((PaperPathResult) path).path;
|
||||
+ return entity.getNavigation().moveTo(pathEntity, speed);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean canOpenDoors() {
|
||||
+ return entity.getNavigation().pathFinder.nodeEvaluator.canOpenDoors();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setCanOpenDoors(boolean canOpenDoors) {
|
||||
+ entity.getNavigation().pathFinder.nodeEvaluator.setCanOpenDoors(canOpenDoors);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean canPassDoors() {
|
||||
+ return entity.getNavigation().pathFinder.nodeEvaluator.canPassDoors();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setCanPassDoors(boolean canPassDoors) {
|
||||
+ entity.getNavigation().pathFinder.nodeEvaluator.setCanPassDoors(canPassDoors);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean canFloat() {
|
||||
+ return entity.getNavigation().pathFinder.nodeEvaluator.canFloat();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setCanFloat(boolean canFloat) {
|
||||
+ entity.getNavigation().pathFinder.nodeEvaluator.setCanFloat(canFloat);
|
||||
+ }
|
||||
+
|
||||
+ public class PaperPathResult implements com.destroystokyo.paper.entity.PaperPathfinder.PathResult {
|
||||
+
|
||||
+ private final Path path;
|
||||
+ PaperPathResult(Path path) {
|
||||
+ this.path = path;
|
||||
+ }
|
||||
+
|
||||
+ @Nullable
|
||||
+ @Override
|
||||
+ public Location getFinalPoint() {
|
||||
+ Node point = path.getEndNode();
|
||||
+ return point != null ? toLoc(point) : null;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean canReachFinalPoint() {
|
||||
+ return path.canReach();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public List<Location> getPoints() {
|
||||
+ List<Location> points = new ArrayList<>();
|
||||
+ for (Node point : path.nodes) {
|
||||
+ points.add(toLoc(point));
|
||||
+ }
|
||||
+ return points;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getNextPointIndex() {
|
||||
+ return path.getNextNodeIndex();
|
||||
+ }
|
||||
+
|
||||
+ @Nullable
|
||||
+ @Override
|
||||
+ public Location getNextPoint() {
|
||||
+ if (!path.hasNext()) {
|
||||
+ return null;
|
||||
+ }
|
||||
+ return toLoc(path.nodes.get(path.getNextNodeIndex()));
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private Location toLoc(Node point) {
|
||||
+ return new Location(entity.level().getWorld(), point.x, point.y, point.z);
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/net/minecraft/world/level/pathfinder/Path.java b/src/main/java/net/minecraft/world/level/pathfinder/Path.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/pathfinder/Path.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/pathfinder/Path.java
|
||||
@@ -0,0 +0,0 @@ public class Path {
|
||||
private final BlockPos target;
|
||||
private final float distToTarget;
|
||||
private final boolean reached;
|
||||
+ public boolean hasNext() { return getNextNodeIndex() < this.nodes.size(); } // Paper - Mob Pathfinding API
|
||||
|
||||
public Path(List<Node> nodes, BlockPos target, boolean reachesTarget) {
|
||||
this.nodes = nodes;
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java
|
||||
@@ -0,0 +0,0 @@ import org.bukkit.loot.LootTable;
|
||||
public abstract class CraftMob extends CraftLivingEntity implements Mob {
|
||||
public CraftMob(CraftServer server, net.minecraft.world.entity.Mob entity) {
|
||||
super(server, entity);
|
||||
+ paperPathfinder = new com.destroystokyo.paper.entity.PaperPathfinder(entity); // Paper - Mob Pathfinding API
|
||||
}
|
||||
|
||||
+ private final com.destroystokyo.paper.entity.PaperPathfinder paperPathfinder; // Paper - Mob Pathfinding API
|
||||
+ @Override public com.destroystokyo.paper.entity.Pathfinder getPathfinder() { return paperPathfinder; } // Paper - Mob Pathfinding API
|
||||
@Override
|
||||
public void setTarget(LivingEntity target) {
|
||||
Preconditions.checkState(!this.getHandle().generation, "Cannot set target during world generation");
|
||||
@@ -0,0 +0,0 @@ public abstract class CraftMob extends CraftLivingEntity implements Mob {
|
||||
return (net.minecraft.world.entity.Mob) this.entity;
|
||||
}
|
||||
|
||||
+ // Paper start - Mob Pathfinding API
|
||||
+ @Override
|
||||
+ public void setHandle(net.minecraft.world.entity.Entity entity) {
|
||||
+ super.setHandle(entity);
|
||||
+ paperPathfinder.setHandle(getHandle());
|
||||
+ }
|
||||
+ // Paper end - Mob Pathfinding API
|
||||
+
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CraftMob";
|
@@ -1,107 +0,0 @@
|
||||
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
|
||||
|
||||
|
||||
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 - Perf: 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 - Perf: Optimize BlockPosition
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos below() {
|
||||
- return this.relative(Direction.DOWN);
|
||||
+ return new BlockPos(this.getX(), this.getY() - 1, this.getZ()); // Paper - Perf: 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 - Perf: Optimize BlockPosition
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos north() {
|
||||
- return this.relative(Direction.NORTH);
|
||||
+ return new BlockPos(this.getX(), this.getY(), this.getZ() - 1); // Paper - Perf: 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 - Perf: Optimize BlockPosition
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos south() {
|
||||
- return this.relative(Direction.SOUTH);
|
||||
+ return new BlockPos(this.getX(), this.getY(), this.getZ() + 1); // Paper - Perf: 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 - Perf: Optimize BlockPosition
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos west() {
|
||||
- return this.relative(Direction.WEST);
|
||||
+ return new BlockPos(this.getX() - 1, this.getY(), this.getZ()); // Paper - Perf: 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 - Perf: Optimize BlockPosition
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos east() {
|
||||
- return this.relative(Direction.EAST);
|
||||
+ return new BlockPos(this.getX() + 1, this.getY(), this.getZ()); // Paper - Perf: 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 - Perf: Optimize BlockPosition
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos relative(Direction direction) {
|
||||
+ // Paper start - Perf: 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 - Perf: Optimize BlockPosition
|
||||
}
|
||||
|
||||
@Override
|
@@ -1,49 +0,0 @@
|
||||
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.instrument = blockbase_info.instrument;
|
||||
this.replaceable = blockbase_info.replaceable;
|
||||
}
|
||||
+ // Paper start - Perf: 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 - Perf: impl cached craft block data, lazy load to fix issue with loading at the wrong time
|
||||
|
||||
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(net.minecraft.world.level.block.state.BlockState::createCraftBlockData);
|
||||
+ }
|
||||
public static CraftBlockData fromData(net.minecraft.world.level.block.state.BlockState data) {
|
||||
+ return data.createCraftBlockData();
|
||||
+ }
|
||||
+
|
||||
+ public static CraftBlockData createData(net.minecraft.world.level.block.state.BlockState data) {
|
||||
+ // Paper end
|
||||
return CraftBlockData.MAP.getOrDefault(data.getBlock().getClass(), CraftBlockData::new).apply(data);
|
||||
}
|
||||
|
@@ -1,30 +0,0 @@
|
||||
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 Reference2IntMap<T> toId = Util.make(new Reference2IntOpenHashMap<>(), 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<ResourceKey<T>, RegistrationInfo> registrationInfos = new IdentityHashMap<>();
|
||||
+ private final Reference2IntMap<T> toId = Util.make(new Reference2IntOpenHashMap<>(2048), map -> map.defaultReturnValue(-1)); // Paper - Perf: Use bigger expected size to reduce collisions
|
||||
+ private final Map<ResourceLocation, Holder.Reference<T>> byLocation = new HashMap<>(2048); // Paper - Perf: Use bigger expected size to reduce collisions
|
||||
+ private final Map<ResourceKey<T>, Holder.Reference<T>> byKey = new HashMap<>(2048); // Paper - Perf: Use bigger expected size to reduce collisions
|
||||
+ private final Map<T, Holder.Reference<T>> byValue = new IdentityHashMap<>(2048); // Paper - Perf: Use bigger expected size to reduce collisions
|
||||
+ private final Map<ResourceKey<T>, RegistrationInfo> registrationInfos = new IdentityHashMap<>(2048); // Paper - Perf: Use bigger expected size to reduce collisions
|
||||
private Lifecycle registryLifecycle;
|
||||
private volatile Map<TagKey<T>, HolderSet.Named<T>> tags = new IdentityHashMap<>();
|
||||
private boolean frozen;
|
@@ -1,42 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Fri, 2 Nov 2018 23:11:51 -0400
|
||||
Subject: [PATCH] Optimize World Time Updates
|
||||
|
||||
Splits time updates into incremental updates as well as does
|
||||
the updates per world, so that we can re-use the same packet
|
||||
object for every player unless they have per-player time enabled.
|
||||
|
||||
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
|
||||
|
||||
MinecraftTimings.timeUpdateTimer.startTiming(); // Spigot // Paper
|
||||
// Send time updates to everyone, it will get the right time from the world the player is in.
|
||||
- if (this.tickCount % 20 == 0) {
|
||||
- for (int i = 0; i < this.getPlayerList().players.size(); ++i) {
|
||||
- ServerPlayer entityplayer = (ServerPlayer) this.getPlayerList().players.get(i);
|
||||
- entityplayer.connection.send(new ClientboundSetTimePacket(entityplayer.level().getGameTime(), entityplayer.getPlayerTime(), entityplayer.level().getGameRules().getBoolean(GameRules.RULE_DAYLIGHT))); // Add support for per player time
|
||||
+ // Paper start - Perf: Optimize time updates
|
||||
+ for (final ServerLevel level : this.getAllLevels()) {
|
||||
+ final boolean doDaylight = level.getGameRules().getBoolean(GameRules.RULE_DAYLIGHT);
|
||||
+ final long dayTime = level.getDayTime();
|
||||
+ long worldTime = level.getGameTime();
|
||||
+ final ClientboundSetTimePacket worldPacket = new ClientboundSetTimePacket(worldTime, dayTime, doDaylight);
|
||||
+ for (Player entityhuman : level.players()) {
|
||||
+ if (!(entityhuman instanceof ServerPlayer) || (tickCount + entityhuman.getId()) % 20 != 0) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ ServerPlayer entityplayer = (ServerPlayer) entityhuman;
|
||||
+ long playerTime = entityplayer.getPlayerTime();
|
||||
+ ClientboundSetTimePacket packet = (playerTime == dayTime) ? worldPacket :
|
||||
+ new ClientboundSetTimePacket(worldTime, playerTime, doDaylight);
|
||||
+ entityplayer.connection.send(packet); // Add support for per player time
|
||||
}
|
||||
}
|
||||
+ // Paper end - Perf: Optimize time updates
|
||||
MinecraftTimings.timeUpdateTimer.stopTiming(); // Spigot // Paper
|
||||
|
||||
while (iterator.hasNext()) {
|
@@ -1,36 +0,0 @@
|
||||
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 - Option to prevent armor stands from doing entity lookups
|
||||
List<Entity> list = this.level().getEntities((Entity) this, this.getBoundingBox(), ArmorStand.RIDABLE_MINECARTS);
|
||||
Iterator iterator = list.iterator();
|
||||
|
||||
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 - Prevent block entity and entity crashes
|
||||
}
|
||||
}
|
||||
+ // Paper start - Option to 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 - Option to prevent armor stands from doing entity lookups
|
||||
|
||||
public boolean shouldTickDeath(Entity entity) {
|
||||
return true;
|
@@ -1,33 +0,0 @@
|
||||
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 implements ProjectileItem {
|
||||
if (!world.isClientSide) {
|
||||
FireworkRocketEntity fireworkRocketEntity = new FireworkRocketEntity(world, itemStack, user);
|
||||
fireworkRocketEntity.spawningEntity = user.getUUID(); // Paper
|
||||
- world.addFreshEntity(fireworkRocketEntity);
|
||||
- itemStack.consume(1, user);
|
||||
- user.awardStat(Stats.ITEM_USED.get(this));
|
||||
+ // Paper start - PlayerElytraBoostEvent
|
||||
+ 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(), org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(hand));
|
||||
+ if (event.callEvent() && world.addFreshEntity(fireworkRocketEntity)) {
|
||||
+ user.awardStat(Stats.ITEM_USED.get(this));
|
||||
+ if (event.shouldConsume() && !user.hasInfiniteMaterials()) {
|
||||
+ 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 - PlayerElytraBoostEvent
|
||||
+ }
|
||||
+
|
||||
+ // user.awardStat(Stats.ITEM_USED.get(this)); // Paper - PlayerElytraBoostEvent; move up
|
||||
}
|
||||
|
||||
return InteractionResultHolder.sidedSuccess(user.getItemInHand(hand), world.isClientSide());
|
@@ -1,319 +0,0 @@
|
||||
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 implements ProjectileItem {
|
||||
|
||||
entityegg.setItem(itemstack);
|
||||
entityegg.shootFromRotation(user, user.getXRot(), user.getYRot(), 0.0F, 1.5F, 1.0F);
|
||||
- // CraftBukkit start
|
||||
- if (!world.addFreshEntity(entityegg)) {
|
||||
+ // Paper start - PlayerLaunchProjectileEvent
|
||||
+ 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()) {
|
||||
+ itemstack.consume(1, user);
|
||||
+ } 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 - PlayerLaunchProjectileEvent
|
||||
}
|
||||
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 - PlayerLaunchProjectileEvent; moved up
|
||||
user.awardStat(Stats.ITEM_USED.get(this));
|
||||
itemstack.consume(1, user);
|
||||
+ */ // Paper end - PlayerLaunchProjectileEvent
|
||||
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 - PlayerLaunchProjectileEvent
|
||||
+ 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()) {
|
||||
+ itemstack.consume(1, user);
|
||||
+ } 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 - PlayerLaunchProjectileEvent
|
||||
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 - PlayerLaunchProjectileEvent; 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
|
||||
|
||||
user.awardStat(Stats.ITEM_USED.get(this));
|
||||
itemstack.consume(1, user);
|
||||
+ */ // Paper end - PlayerLaunchProjectileEvent; 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 implements ProjectileItem {
|
||||
@Override
|
||||
public InteractionResultHolder<ItemStack> use(Level world, Player user, InteractionHand hand) {
|
||||
ItemStack itemStack = user.getItemInHand(hand);
|
||||
- world.playSound(
|
||||
- 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 - PlayerLaunchProjectileEvent; 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 - PlayerLaunchProjectileEvent
|
||||
+ 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()) {
|
||||
+ itemStack.consume(1, user);
|
||||
+ } else if (user instanceof net.minecraft.server.level.ServerPlayer) {
|
||||
+ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
|
||||
+ }
|
||||
+
|
||||
+ world.playSound(
|
||||
+ null,
|
||||
+ user.getX(),
|
||||
+ user.getY(),
|
||||
+ user.getZ(),
|
||||
+ SoundEvents.EXPERIENCE_BOTTLE_THROW,
|
||||
+ SoundSource.NEUTRAL,
|
||||
+ 0.5F,
|
||||
+ 0.4F / (world.getRandom().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 - PlayerLaunchProjectileEvent
|
||||
}
|
||||
|
||||
+ /* // Paper start - PlayerLaunchProjectileEvent; moved up
|
||||
user.awardStat(Stats.ITEM_USED.get(this));
|
||||
itemStack.consume(1, user);
|
||||
+ */ // Paper end - PlayerLaunchProjectileEvent
|
||||
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 implements ProjectileItem {
|
||||
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 - PlayerLaunchProjectileEvent
|
||||
}
|
||||
|
||||
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 - PlayerLaunchProjectileEvent
|
||||
+ InteractionResultHolder<ItemStack> wrapper = super.use(world, user, hand);
|
||||
+ if (wrapper.getResult() != net.minecraft.world.InteractionResult.FAIL) {
|
||||
+ // Paper end - PlayerLaunchProjectileEvent
|
||||
world.playSound(
|
||||
null,
|
||||
user.getX(),
|
||||
@@ -0,0 +0,0 @@ public class LingeringPotionItem extends ThrowablePotionItem {
|
||||
0.5F,
|
||||
0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F)
|
||||
);
|
||||
- return super.use(world, user, hand);
|
||||
+ // Paper start - PlayerLaunchProjectileEvent
|
||||
+ }
|
||||
+ return wrapper;
|
||||
+ // Paper end - PlayerLaunchProjectileEvent
|
||||
}
|
||||
}
|
||||
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 implements ProjectileItem {
|
||||
|
||||
entitysnowball.setItem(itemstack);
|
||||
entitysnowball.shootFromRotation(user, user.getXRot(), user.getYRot(), 0.0F, 1.5F, 1.0F);
|
||||
- if (world.addFreshEntity(entitysnowball)) {
|
||||
- itemstack.consume(1, user);
|
||||
+ // Paper start - PlayerLaunchProjectileEvent
|
||||
+ 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()) {
|
||||
+ // Paper end - PlayerLaunchProjectileEvent
|
||||
+ itemstack.consume(1, user);
|
||||
+ } else if (user instanceof net.minecraft.server.level.ServerPlayer) { // Paper - PlayerLaunchProjectileEvent
|
||||
+ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory(); // Paper - PlayerLaunchProjectileEvent
|
||||
+ }
|
||||
|
||||
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 - PlayerLaunchProjectileEvent
|
||||
+ if (user instanceof net.minecraft.server.level.ServerPlayer) ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory(); // Paper - PlayerLaunchProjectileEvent
|
||||
+ return InteractionResultHolder.fail(itemstack); // Paper - PlayerLaunchProjectileEvent
|
||||
}
|
||||
}
|
||||
// CraftBukkit end
|
||||
|
||||
- user.awardStat(Stats.ITEM_USED.get(this));
|
||||
+ // user.awardStat(Stats.ITEM_USED.get(this)); // Paper - PlayerLaunchProjectileEvent; moved up
|
||||
// itemstack.consume(1, entityhuman); // CraftBukkit - moved up
|
||||
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 - PlayerLaunchProjectileEvent
|
||||
+ InteractionResultHolder<ItemStack> wrapper = super.use(world, user, hand);
|
||||
+ if (wrapper.getResult() != net.minecraft.world.InteractionResult.FAIL) {
|
||||
+ // Paper end - PlayerLaunchProjectileEvent
|
||||
world.playSound(
|
||||
null,
|
||||
user.getX(),
|
||||
@@ -0,0 +0,0 @@ public class SplashPotionItem extends ThrowablePotionItem {
|
||||
0.5F,
|
||||
0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F)
|
||||
);
|
||||
- return super.use(world, user, hand);
|
||||
+ // Paper start - PlayerLaunchProjectileEvent
|
||||
+ }
|
||||
+ return wrapper;
|
||||
+ // Paper end - PlayerLaunchProjectileEvent
|
||||
}
|
||||
}
|
||||
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 implements ProjectileItem {
|
||||
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 - PlayerLaunchProjectileEvent
|
||||
+ 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()) {
|
||||
+ itemStack.consume(1, user);
|
||||
+ } 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 - PlayerLaunchProjectileEvent
|
||||
}
|
||||
|
||||
+ /* // Paper start - PlayerLaunchProjectileEvent; moved up
|
||||
user.awardStat(Stats.ITEM_USED.get(this));
|
||||
itemStack.consume(1, user);
|
||||
+ */ // 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 ProjectileItem {
|
||||
}
|
||||
|
||||
// CraftBukkit start
|
||||
- if (!world.addFreshEntity(entitythrowntrident)) {
|
||||
+ // Paper start - PlayerLaunchProjectileEvent
|
||||
+ 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 - PlayerLaunchProjectileEvent
|
||||
if (entityhuman instanceof net.minecraft.server.level.ServerPlayer) {
|
||||
((net.minecraft.server.level.ServerPlayer) entityhuman).getBukkitEntity().updateInventory();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
+ if (event.shouldConsume()) { // Paper - PlayerLaunchProjectileEvent
|
||||
stack.hurtAndBreak(1, entityhuman, LivingEntity.getSlotForHand(user.getUsedItemHand()));
|
||||
+ } // Paper - PlayerLaunchProjectileEvent
|
||||
entitythrowntrident.pickupItemStack = 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.hasInfiniteMaterials()) {
|
||||
+ if (event.shouldConsume() && !entityhuman.hasInfiniteMaterials()) {
|
||||
entityhuman.getInventory().removeItem(stack);
|
||||
}
|
||||
// CraftBukkit start - SPIGOT-5458 also need in this branch :(
|
@@ -1,44 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 18 Jun 2018 01:12:53 -0400
|
||||
Subject: [PATCH] PlayerReadyArrowEvent
|
||||
|
||||
Called when a player is firing a bow and the server is choosing an arrow to use.
|
||||
Plugins can skip selection of certain arrows and control which is used.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Player extends LivingEntity {
|
||||
return ImmutableList.of(Pose.STANDING, Pose.CROUCHING, Pose.SWIMMING);
|
||||
}
|
||||
|
||||
+ // Paper start - PlayerReadyArrowEvent
|
||||
+ protected boolean tryReadyArrow(ItemStack bow, ItemStack itemstack) {
|
||||
+ return !(this instanceof ServerPlayer) ||
|
||||
+ new com.destroystokyo.paper.event.player.PlayerReadyArrowEvent(
|
||||
+ ((ServerPlayer) this).getBukkitEntity(),
|
||||
+ org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(bow),
|
||||
+ org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack)
|
||||
+ ).callEvent();
|
||||
+ }
|
||||
+ // Paper end - PlayerReadyArrowEvent
|
||||
+
|
||||
@Override
|
||||
public ItemStack getProjectile(ItemStack stack) {
|
||||
if (!(stack.getItem() instanceof ProjectileWeaponItem)) {
|
||||
return ItemStack.EMPTY;
|
||||
} else {
|
||||
- Predicate<ItemStack> predicate = ((ProjectileWeaponItem) stack.getItem()).getSupportedHeldProjectiles();
|
||||
+ Predicate<ItemStack> predicate = ((ProjectileWeaponItem) stack.getItem()).getSupportedHeldProjectiles().and(item -> tryReadyArrow(stack, item)); // Paper - PlayerReadyArrowEvent
|
||||
ItemStack itemstack1 = ProjectileWeaponItem.getHeldProjectile(this, predicate);
|
||||
|
||||
if (!itemstack1.isEmpty()) {
|
||||
return itemstack1;
|
||||
} else {
|
||||
- predicate = ((ProjectileWeaponItem) stack.getItem()).getAllSupportedProjectiles();
|
||||
+ predicate = ((ProjectileWeaponItem) stack.getItem()).getAllSupportedProjectiles().and(item -> tryReadyArrow(stack, item)); // Paper - PlayerReadyArrowEvent
|
||||
|
||||
for (int i = 0; i < this.inventory.getContainerSize(); ++i) {
|
||||
ItemStack itemstack2 = this.inventory.getItem(i);
|
@@ -1,27 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Phoenix616 <mail@moep.tv>
|
||||
Date: Tue, 18 Sep 2018 23:53:23 +0100
|
||||
Subject: [PATCH] PreSpawnerSpawnEvent
|
||||
|
||||
This adds a separate event before an entity is spawned by a spawner
|
||||
which contains the location of the spawner too similarly to how the
|
||||
SpawnerSpawnEvent gets called instead of the CreatureSpawnEvent for
|
||||
spawners.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/BaseSpawner.java b/src/main/java/net/minecraft/world/level/BaseSpawner.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/BaseSpawner.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/BaseSpawner.java
|
||||
@@ -0,0 +0,0 @@ public abstract class BaseSpawner {
|
||||
continue;
|
||||
}
|
||||
// Paper start - PreCreatureSpawnEvent
|
||||
- com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent event = new com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent(
|
||||
+ com.destroystokyo.paper.event.entity.PreSpawnerSpawnEvent event = new com.destroystokyo.paper.event.entity.PreSpawnerSpawnEvent(
|
||||
io.papermc.paper.util.MCUtil.toLocation(world, d0, d1, d2),
|
||||
org.bukkit.craftbukkit.entity.CraftEntityType.minecraftToBukkit(optional.get()),
|
||||
- org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER
|
||||
+ io.papermc.paper.util.MCUtil.toLocation(world, pos)
|
||||
);
|
||||
if (!event.callEvent()) {
|
||||
flag = true;
|
@@ -1,75 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 10 Sep 2018 23:36:16 -0400
|
||||
Subject: [PATCH] Prevent chunk loading from Fluid Flowing
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java
|
||||
@@ -0,0 +0,0 @@ public abstract class FlowingFluid extends Fluid {
|
||||
Direction enumdirection = (Direction) entry.getKey();
|
||||
FluidState fluid1 = (FluidState) entry.getValue();
|
||||
BlockPos blockposition1 = pos.relative(enumdirection);
|
||||
- BlockState iblockdata1 = world.getBlockState(blockposition1);
|
||||
+ BlockState iblockdata1 = world.getBlockStateIfLoaded(blockposition1); // Paper - Prevent chunk loading from fluid flowing
|
||||
+ if (iblockdata1 == null) continue; // Paper - Prevent chunk loading from fluid flowing
|
||||
|
||||
if (this.canSpreadTo(world, pos, blockState, enumdirection, blockposition1, iblockdata1, world.getFluidState(blockposition1), fluid1.getType())) {
|
||||
// CraftBukkit start
|
||||
@@ -0,0 +0,0 @@ public abstract class FlowingFluid extends Fluid {
|
||||
while (iterator.hasNext()) {
|
||||
Direction enumdirection = (Direction) iterator.next();
|
||||
BlockPos blockposition1 = pos.relative(enumdirection);
|
||||
- BlockState iblockdata1 = world.getBlockState(blockposition1);
|
||||
+ BlockState iblockdata1 = world.getBlockStateIfLoaded(blockposition1); // Paper - Prevent chunk loading from fluid flowing
|
||||
+ if (iblockdata1 == null) continue; // Paper - Prevent chunk loading from fluid flowing
|
||||
FluidState fluid = iblockdata1.getFluidState();
|
||||
|
||||
if (fluid.getType().isSame(this) && this.canPassThroughWall(enumdirection, world, pos, state, blockposition1, iblockdata1)) {
|
||||
@@ -0,0 +0,0 @@ public abstract class FlowingFluid extends Fluid {
|
||||
if (enumdirection1 != direction) {
|
||||
BlockPos blockposition2 = pos.relative(enumdirection1);
|
||||
short short0 = FlowingFluid.getCacheKey(fromPos, blockposition2);
|
||||
- Pair<BlockState, FluidState> pair = (Pair) stateCache.computeIfAbsent(short0, (short1) -> {
|
||||
- BlockState iblockdata1 = world.getBlockState(blockposition2);
|
||||
+ // Paper start - Prevent chunk loading from fluid flowing
|
||||
+ Pair<BlockState, FluidState> pair = stateCache.get(short0);
|
||||
+ if (pair == null) {
|
||||
+ BlockState iblockdatax = world.getBlockStateIfLoaded(blockposition2);
|
||||
+ if (iblockdatax == null) {
|
||||
+ continue;
|
||||
+ }
|
||||
|
||||
- return Pair.of(iblockdata1, iblockdata1.getFluidState());
|
||||
- });
|
||||
+ pair = Pair.of(iblockdatax, iblockdatax.getFluidState());
|
||||
+ stateCache.put(short0, pair);
|
||||
+ }
|
||||
+ // Paper end - Prevent chunk loading from fluid flowing
|
||||
BlockState iblockdata1 = (BlockState) pair.getFirst();
|
||||
FluidState fluid = (FluidState) pair.getSecond();
|
||||
|
||||
@@ -0,0 +0,0 @@ public abstract class FlowingFluid extends Fluid {
|
||||
Direction enumdirection = (Direction) iterator.next();
|
||||
BlockPos blockposition1 = pos.relative(enumdirection);
|
||||
short short0 = FlowingFluid.getCacheKey(pos, blockposition1);
|
||||
- Pair<BlockState, FluidState> pair = (Pair) short2objectmap.computeIfAbsent(short0, (short1) -> {
|
||||
- BlockState iblockdata1 = world.getBlockState(blockposition1);
|
||||
-
|
||||
- return Pair.of(iblockdata1, iblockdata1.getFluidState());
|
||||
- });
|
||||
+ // Paper start - Prevent chunk loading from fluid flowing
|
||||
+ Pair pair = (Pair) short2objectmap.get(short0);
|
||||
+ if (pair == null) {
|
||||
+ BlockState iblockdatax = world.getBlockStateIfLoaded(blockposition1);
|
||||
+ if (iblockdatax == null) continue;
|
||||
+
|
||||
+ pair = Pair.of(iblockdatax, iblockdatax.getFluidState());
|
||||
+ short2objectmap.put(short0, pair);
|
||||
+ }
|
||||
+ // Paper end - Prevent chunk loading from fluid flowing
|
||||
BlockState iblockdata1 = (BlockState) pair.getFirst();
|
||||
FluidState fluid = (FluidState) pair.getSecond();
|
||||
FluidState fluid1 = this.getNewLiquid(world, blockposition1, iblockdata1);
|
@@ -1,32 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Wed, 12 Sep 2018 21:12:57 -0400
|
||||
Subject: [PATCH] Prevent mob spawning from loading/generating chunks
|
||||
|
||||
also prevents if out of world border bounds
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java
|
||||
@@ -0,0 +0,0 @@ public final class NaturalSpawner {
|
||||
StructureManager structuremanager = world.structureManager();
|
||||
ChunkGenerator chunkgenerator = world.getChunkSource().getGenerator();
|
||||
int i = pos.getY();
|
||||
- BlockState iblockdata = chunk.getBlockState(pos);
|
||||
+ BlockState iblockdata = world.getBlockStateIfLoadedAndInBounds(pos); // Paper - don't load chunks for mob spawn
|
||||
|
||||
- if (!iblockdata.isRedstoneConductor(chunk, pos)) {
|
||||
+ if (iblockdata != null && !iblockdata.isRedstoneConductor(chunk, pos)) { // Paper - don't load chunks for mob spawn
|
||||
BlockPos.MutableBlockPos blockposition_mutableblockposition = new BlockPos.MutableBlockPos();
|
||||
int j = 0;
|
||||
int k = 0;
|
||||
@@ -0,0 +0,0 @@ public final class NaturalSpawner {
|
||||
if (entityhuman != null) {
|
||||
double d2 = entityhuman.distanceToSqr(d0, (double) i, d1);
|
||||
|
||||
- if (NaturalSpawner.isRightDistanceToPlayerAndSpawnPoint(world, chunk, blockposition_mutableblockposition, d2)) {
|
||||
+ if (world.isLoadedAndInBounds(blockposition_mutableblockposition) && NaturalSpawner.isRightDistanceToPlayerAndSpawnPoint(world, chunk, blockposition_mutableblockposition, d2)) { // Paper - don't load chunks for mob spawn
|
||||
if (biomesettingsmobs_c == null) {
|
||||
Optional<MobSpawnSettings.SpawnerData> optional = NaturalSpawner.getRandomSpawnMobAt(world, structuremanager, chunkgenerator, group, world.random, blockposition_mutableblockposition);
|
||||
|
@@ -1,99 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 10 Sep 2018 23:56:36 -0400
|
||||
Subject: [PATCH] Prevent various interactions from causing chunk loads
|
||||
|
||||
Co-authored-by: Shane Freeder <theboyetronic@gmail.com>
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/RemoveBlockGoal.java b/src/main/java/net/minecraft/world/entity/ai/goal/RemoveBlockGoal.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ai/goal/RemoveBlockGoal.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ai/goal/RemoveBlockGoal.java
|
||||
@@ -0,0 +0,0 @@ public class RemoveBlockGoal extends MoveToBlockGoal {
|
||||
|
||||
@Nullable
|
||||
private BlockPos getPosWithBlock(BlockPos pos, BlockGetter world) {
|
||||
- if (world.getBlockState(pos).is(this.blockToRemove)) {
|
||||
+ net.minecraft.world.level.block.state.BlockState block = world.getBlockStateIfLoaded(pos); // Paper - Prevent AI rules from loading chunks
|
||||
+ if (block == null) return null; // Paper - Prevent AI rules from loading chunks
|
||||
+ if (block.is(this.blockToRemove)) { // Paper - Prevent AI rules from loading chunks
|
||||
return pos;
|
||||
} else {
|
||||
BlockPos[] ablockposition = new BlockPos[]{pos.below(), pos.west(), pos.east(), pos.north(), pos.south(), pos.below().below()};
|
||||
@@ -0,0 +0,0 @@ public class RemoveBlockGoal extends MoveToBlockGoal {
|
||||
for (int j = 0; j < i; ++j) {
|
||||
BlockPos blockposition1 = ablockposition1[j];
|
||||
|
||||
- if (world.getBlockState(blockposition1).is(this.blockToRemove)) {
|
||||
+ net.minecraft.world.level.block.state.BlockState block2 = world.getBlockStateIfLoaded(blockposition1); // Paper - Prevent AI rules from loading chunks
|
||||
+ if (block2 != null && block2.is(this.blockToRemove)) { // Paper - Prevent AI rules from loading chunks
|
||||
return blockposition1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class RemoveBlockGoal extends MoveToBlockGoal {
|
||||
|
||||
@Override
|
||||
protected boolean isValidTarget(LevelReader world, BlockPos pos) {
|
||||
- ChunkAccess ichunkaccess = world.getChunk(SectionPos.blockToSectionCoord(pos.getX()), SectionPos.blockToSectionCoord(pos.getZ()), ChunkStatus.FULL, false);
|
||||
+ ChunkAccess ichunkaccess = world.getChunkIfLoadedImmediately(pos.getX() >> 4, pos.getZ() >> 4); // Paper - Prevent AI rules from loading chunks
|
||||
|
||||
return ichunkaccess == null ? false : ichunkaccess.getBlockState(pos).is(this.blockToRemove) && ichunkaccess.getBlockState(pos.above()).isAir() && ichunkaccess.getBlockState(pos.above(2)).isAir();
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
|
||||
@@ -0,0 +0,0 @@ public class EnderMan extends Monster implements NeutralMob {
|
||||
int j = Mth.floor(this.enderman.getY() + randomsource.nextDouble() * 2.0D);
|
||||
int k = Mth.floor(this.enderman.getZ() - 1.0D + randomsource.nextDouble() * 2.0D);
|
||||
BlockPos blockposition = new BlockPos(i, j, k);
|
||||
- BlockState iblockdata = world.getBlockState(blockposition);
|
||||
+ BlockState iblockdata = world.getBlockStateIfLoaded(blockposition); // Paper - Prevent endermen from loading chunks
|
||||
+ if (iblockdata == null) return; // Paper - Prevent endermen from loading chunks
|
||||
BlockPos blockposition1 = blockposition.below();
|
||||
BlockState iblockdata1 = world.getBlockState(blockposition1);
|
||||
BlockState iblockdata2 = this.enderman.getCarriedBlock();
|
||||
@@ -0,0 +0,0 @@ public class EnderMan extends Monster implements NeutralMob {
|
||||
int j = Mth.floor(this.enderman.getY() + randomsource.nextDouble() * 3.0D);
|
||||
int k = Mth.floor(this.enderman.getZ() - 2.0D + randomsource.nextDouble() * 4.0D);
|
||||
BlockPos blockposition = new BlockPos(i, j, k);
|
||||
- BlockState iblockdata = world.getBlockState(blockposition);
|
||||
+ BlockState iblockdata = world.getBlockStateIfLoaded(blockposition); // Paper - Prevent endermen from loading chunks
|
||||
+ if (iblockdata == null) return; // Paper - Prevent endermen from loading chunks
|
||||
Vec3 vec3d = new Vec3((double) this.enderman.getBlockX() + 0.5D, (double) j + 0.5D, (double) this.enderman.getBlockZ() + 0.5D);
|
||||
Vec3 vec3d1 = new Vec3((double) i + 0.5D, (double) j + 0.5D, (double) k + 0.5D);
|
||||
BlockHitResult movingobjectpositionblock = world.clip(new ClipContext(vec3d, vec3d1, ClipContext.Block.OUTLINE, ClipContext.Fluid.NONE, this.enderman));
|
||||
diff --git a/src/main/java/net/minecraft/world/item/component/LodestoneTracker.java b/src/main/java/net/minecraft/world/item/component/LodestoneTracker.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/component/LodestoneTracker.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/component/LodestoneTracker.java
|
||||
@@ -0,0 +0,0 @@ public record LodestoneTracker(Optional<GlobalPos> target, boolean tracked) {
|
||||
return this;
|
||||
} else {
|
||||
BlockPos blockPos = this.target.get().pos();
|
||||
- return world.isInWorldBounds(blockPos) && world.getPoiManager().existsAtPosition(PoiTypes.LODESTONE, blockPos)
|
||||
+ return world.isInWorldBounds(blockPos) && (!world.hasChunkAt(blockPos) || world.getPoiManager().existsAtPosition(PoiTypes.LODESTONE, blockPos)) // Paper - Prevent compass from loading chunks
|
||||
? this
|
||||
: new LodestoneTracker(Optional.empty(), true);
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/level/BlockGetter.java b/src/main/java/net/minecraft/world/level/BlockGetter.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/BlockGetter.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/BlockGetter.java
|
||||
@@ -0,0 +0,0 @@ public interface BlockGetter extends LevelHeightAccessor {
|
||||
|
||||
// CraftBukkit start - moved block handling into separate method for use by Block#rayTrace
|
||||
default BlockHitResult clip(ClipContext raytrace1, BlockPos blockposition) {
|
||||
- BlockState iblockdata = this.getBlockState(blockposition);
|
||||
+ // Paper start - Prevent raytrace from loading chunks
|
||||
+ BlockState iblockdata = this.getBlockStateIfLoaded(blockposition);
|
||||
+ if (iblockdata == null) {
|
||||
+ // copied the last function parameter (listed below)
|
||||
+ Vec3 vec3d = raytrace1.getFrom().subtract(raytrace1.getTo());
|
||||
+
|
||||
+ return BlockHitResult.miss(raytrace1.getTo(), Direction.getNearest(vec3d.x, vec3d.y, vec3d.z), BlockPos.containing(raytrace1.getTo()));
|
||||
+ }
|
||||
+ // Paper end - Prevent raytrace from loading chunks
|
||||
FluidState fluid = this.getFluidState(blockposition);
|
||||
Vec3 vec3d = raytrace1.getFrom();
|
||||
Vec3 vec3d1 = raytrace1.getTo();
|
@@ -1,19 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Fri, 15 Jun 2018 20:37:03 -0400
|
||||
Subject: [PATCH] Print Error details when failing to save player data
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/storage/PlayerDataStorage.java b/src/main/java/net/minecraft/world/level/storage/PlayerDataStorage.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/storage/PlayerDataStorage.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/storage/PlayerDataStorage.java
|
||||
@@ -0,0 +0,0 @@ public class PlayerDataStorage {
|
||||
|
||||
Util.safeReplaceFile(path2, path1, path3);
|
||||
} catch (Exception exception) {
|
||||
- PlayerDataStorage.LOGGER.warn("Failed to save player data for {}", player.getName().getString());
|
||||
+ PlayerDataStorage.LOGGER.warn("Failed to save player data for {}", player.getScoreboardName(), exception); // Paper - Print exception
|
||||
}
|
||||
|
||||
}
|
@@ -1,162 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 26 Jun 2018 22:00:49 -0400
|
||||
Subject: [PATCH] RangedEntity API
|
||||
|
||||
Allows you to determine if an entity is capable of ranged attacks,
|
||||
and to perform an attack.
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/entity/CraftRangedEntity.java b/src/main/java/com/destroystokyo/paper/entity/CraftRangedEntity.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/entity/CraftRangedEntity.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package com.destroystokyo.paper.entity;
|
||||
+
|
||||
+import net.minecraft.world.entity.Mob;
|
||||
+import net.minecraft.world.entity.monster.RangedAttackMob;
|
||||
+import org.bukkit.craftbukkit.entity.CraftLivingEntity;
|
||||
+import org.bukkit.entity.LivingEntity;
|
||||
+
|
||||
+public interface CraftRangedEntity<T extends Mob & RangedAttackMob> extends RangedEntity {
|
||||
+ T getHandle();
|
||||
+
|
||||
+ @Override
|
||||
+ default void rangedAttack(LivingEntity target, float charge) {
|
||||
+ getHandle().performRangedAttack(((CraftLivingEntity) target).getHandle(), charge);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ default void setChargingAttack(boolean raiseHands) {
|
||||
+ getHandle().setAggressive(raiseHands);
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractSkeleton.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractSkeleton.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractSkeleton.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractSkeleton.java
|
||||
@@ -0,0 +0,0 @@ import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.AbstractSkeleton;
|
||||
import org.bukkit.entity.Skeleton;
|
||||
|
||||
-public abstract class CraftAbstractSkeleton extends CraftMonster implements AbstractSkeleton {
|
||||
+public abstract class CraftAbstractSkeleton extends CraftMonster implements AbstractSkeleton, com.destroystokyo.paper.entity.CraftRangedEntity<net.minecraft.world.entity.monster.AbstractSkeleton> { // Paper
|
||||
|
||||
public CraftAbstractSkeleton(CraftServer server, net.minecraft.world.entity.monster.AbstractSkeleton entity) {
|
||||
super(server, entity);
|
||||
@@ -0,0 +0,0 @@ public abstract class CraftAbstractSkeleton extends CraftMonster implements Abst
|
||||
public void setSkeletonType(Skeleton.SkeletonType type) {
|
||||
throw new UnsupportedOperationException("Not supported.");
|
||||
}
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public net.minecraft.world.entity.monster.AbstractSkeleton getHandle() {
|
||||
+ return (net.minecraft.world.entity.monster.AbstractSkeleton) super.getHandle();
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftDrowned.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftDrowned.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftDrowned.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftDrowned.java
|
||||
@@ -0,0 +0,0 @@ package org.bukkit.craftbukkit.entity;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.Drowned;
|
||||
|
||||
-public class CraftDrowned extends CraftZombie implements Drowned {
|
||||
+public class CraftDrowned extends CraftZombie implements Drowned, com.destroystokyo.paper.entity.CraftRangedEntity<net.minecraft.world.entity.monster.Drowned> { // Paper
|
||||
|
||||
public CraftDrowned(CraftServer server, net.minecraft.world.entity.monster.Drowned entity) {
|
||||
super(server, entity);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftIllusioner.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftIllusioner.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftIllusioner.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftIllusioner.java
|
||||
@@ -0,0 +0,0 @@ package org.bukkit.craftbukkit.entity;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.Illusioner;
|
||||
|
||||
-public class CraftIllusioner extends CraftSpellcaster implements Illusioner {
|
||||
+public class CraftIllusioner extends CraftSpellcaster implements Illusioner, com.destroystokyo.paper.entity.CraftRangedEntity<net.minecraft.world.entity.monster.Illusioner> { // Paper
|
||||
|
||||
public CraftIllusioner(CraftServer server, net.minecraft.world.entity.monster.Illusioner entity) {
|
||||
super(server, entity);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLlama.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLlama.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLlama.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLlama.java
|
||||
@@ -0,0 +0,0 @@ import org.bukkit.entity.Llama;
|
||||
import org.bukkit.entity.Llama.Color;
|
||||
import org.bukkit.inventory.LlamaInventory;
|
||||
|
||||
-public class CraftLlama extends CraftChestedHorse implements Llama {
|
||||
+public class CraftLlama extends CraftChestedHorse implements Llama, com.destroystokyo.paper.entity.CraftRangedEntity<net.minecraft.world.entity.animal.horse.Llama> { // Paper
|
||||
|
||||
public CraftLlama(CraftServer server, net.minecraft.world.entity.animal.horse.Llama entity) {
|
||||
super(server, entity);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPiglin.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPiglin.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPiglin.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPiglin.java
|
||||
@@ -0,0 +0,0 @@ import org.bukkit.craftbukkit.inventory.CraftItemType;
|
||||
import org.bukkit.entity.Piglin;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
|
||||
-public class CraftPiglin extends CraftPiglinAbstract implements Piglin {
|
||||
+public class CraftPiglin extends CraftPiglinAbstract implements Piglin, com.destroystokyo.paper.entity.CraftRangedEntity<net.minecraft.world.entity.monster.piglin.Piglin> { // Paper
|
||||
|
||||
public CraftPiglin(CraftServer server, net.minecraft.world.entity.monster.piglin.Piglin entity) {
|
||||
super(server, entity);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPillager.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPillager.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPillager.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPillager.java
|
||||
@@ -0,0 +0,0 @@ import org.bukkit.craftbukkit.inventory.CraftInventory;
|
||||
import org.bukkit.entity.Pillager;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
|
||||
-public class CraftPillager extends CraftIllager implements Pillager {
|
||||
+public class CraftPillager extends CraftIllager implements Pillager, com.destroystokyo.paper.entity.CraftRangedEntity<net.minecraft.world.entity.monster.Pillager> { // Paper
|
||||
|
||||
public CraftPillager(CraftServer server, net.minecraft.world.entity.monster.Pillager entity) {
|
||||
super(server, entity);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java
|
||||
@@ -0,0 +0,0 @@ import net.minecraft.world.entity.animal.SnowGolem;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.Snowman;
|
||||
|
||||
-public class CraftSnowman extends CraftGolem implements Snowman {
|
||||
+public class CraftSnowman extends CraftGolem implements Snowman, com.destroystokyo.paper.entity.CraftRangedEntity<SnowGolem> { // Paper
|
||||
public CraftSnowman(CraftServer server, SnowGolem entity) {
|
||||
super(server, entity);
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftWitch.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftWitch.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftWitch.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftWitch.java
|
||||
@@ -0,0 +0,0 @@ package org.bukkit.craftbukkit.entity;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.Witch;
|
||||
|
||||
-public class CraftWitch extends CraftRaider implements Witch {
|
||||
+public class CraftWitch extends CraftRaider implements Witch, com.destroystokyo.paper.entity.CraftRangedEntity<net.minecraft.world.entity.monster.Witch> { // Paper
|
||||
public CraftWitch(CraftServer server, net.minecraft.world.entity.monster.Witch entity) {
|
||||
super(server, entity);
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftWither.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftWither.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftWither.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftWither.java
|
||||
@@ -0,0 +0,0 @@ import org.bukkit.craftbukkit.boss.CraftBossBar;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Wither;
|
||||
|
||||
-public class CraftWither extends CraftMonster implements Wither {
|
||||
+public class CraftWither extends CraftMonster implements Wither, com.destroystokyo.paper.entity.CraftRangedEntity<WitherBoss> { // Paper
|
||||
|
||||
private BossBar bossBar;
|
||||
|
@@ -1,29 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Minecrell <minecrell@minecrell.net>
|
||||
Date: Fri, 13 Jul 2018 14:54:43 +0200
|
||||
Subject: [PATCH] Refresh player inventory when cancelling
|
||||
PlayerInteractEntityEvent
|
||||
|
||||
When interacting with entities with an item, the client will assume
|
||||
the interaction is successful, and update the held item on the
|
||||
client. However, if the interaction is cancelled on the server side,
|
||||
the client will still mistakenly remove/replace the item in hand.
|
||||
|
||||
Examples for this are milking cows with a bucket or dyeing sheep.
|
||||
The bucket is replaced with milk and the dye removed from inventory.
|
||||
|
||||
Refresh the player inventory when PlayerInteractEntityEvent is
|
||||
cancelled to avoid this problem.
|
||||
|
||||
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 extends ServerCommonPacketListenerImpl
|
||||
}
|
||||
|
||||
if (event.isCancelled()) {
|
||||
+ ServerGamePacketListenerImpl.this.player.containerMenu.sendAllDataToRemote(); // Paper - Refresh player inventory
|
||||
return;
|
||||
}
|
||||
// CraftBukkit end
|
@@ -1,30 +0,0 @@
|
||||
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/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 implements DataComponentHolder {
|
||||
|
||||
// CraftBukkit start
|
||||
ItemStack itemstack = new ItemStack(holder, i, datacomponentpatch);
|
||||
- if (!datacomponentpatch.isEmpty()) {
|
||||
+ if (false && !datacomponentpatch.isEmpty()) { // Paper - This is no longer needed with raw NBT being handled in metadata
|
||||
CraftItemStack.setItemMeta(itemstack, CraftItemStack.getItemMeta(itemstack));
|
||||
}
|
||||
return itemstack;
|
||||
@@ -0,0 +0,0 @@ public final class ItemStack implements DataComponentHolder {
|
||||
} else {
|
||||
registryfriendlybytebuf.writeVarInt(itemstack.getCount());
|
||||
// Spigot start - filter
|
||||
- itemstack = itemstack.copy();
|
||||
- CraftItemStack.setItemMeta(itemstack, CraftItemStack.getItemMeta(itemstack));
|
||||
+ // itemstack = itemstack.copy();
|
||||
+ // CraftItemStack.setItemMeta(itemstack, CraftItemStack.getItemMeta(itemstack)); // Paper - This is no longer with raw NBT being handled in metadata
|
||||
// Spigot end
|
||||
ITEM_STREAM_CODEC.encode(registryfriendlybytebuf, itemstack.getItemHolder()); // CraftBukkit - decompile error
|
||||
// Paper start - adventure; conditionally render translatable components
|
@@ -1,164 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <1254957+zachbr@users.noreply.github.com>
|
||||
Date: Wed, 2 Jan 2019 00:35:43 -0600
|
||||
Subject: [PATCH] Replace OfflinePlayer#getLastPlayed
|
||||
|
||||
Currently OfflinePlayer#getLastPlayed could more accurately be described
|
||||
as "OfflinePlayer#getLastTimeTheirDataWasSaved".
|
||||
|
||||
The API doc says it should return the last time the server "witnessed"
|
||||
the player, whilst also saying it should return the last time they
|
||||
logged in. The current implementation does neither.
|
||||
|
||||
Given this interesting contradiction in the API documentation and the
|
||||
current defacto implementation, I've elected to deprecate (with no
|
||||
intent to remove) and replace it with two new methods, clearly named and
|
||||
documented as to their purpose.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
index 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 {
|
||||
private int containerCounter;
|
||||
public boolean wonGame;
|
||||
private int containerUpdateDelay; // Paper - Configurable container update tick rate
|
||||
+ public long loginTime; // Paper - Replace OfflinePlayer#getLastPlayed
|
||||
// Paper start - cancellable death event
|
||||
public boolean queueHealthUpdatePacket;
|
||||
public net.minecraft.network.protocol.game.ClientboundSetHealthPacket queuedHealthUpdatePacket;
|
||||
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
index 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 {
|
||||
|
||||
public void placeNewPlayer(Connection connection, ServerPlayer player, CommonListenerCookie clientData) {
|
||||
player.isRealPlayer = true; // Paper
|
||||
+ player.loginTime = System.currentTimeMillis(); // Paper - Replace OfflinePlayer#getLastPlayed
|
||||
GameProfile gameprofile = player.getGameProfile();
|
||||
GameProfileCache usercache = this.server.getProfileCache();
|
||||
// Optional optional; // CraftBukkit - decompile error
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java b/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java
|
||||
@@ -0,0 +0,0 @@ public class CraftOfflinePlayer implements OfflinePlayer, ConfigurationSerializa
|
||||
return this.getData() != null;
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public long getLastLogin() {
|
||||
+ Player player = getPlayer();
|
||||
+ if (player != null) return player.getLastLogin();
|
||||
+
|
||||
+ CompoundTag data = getPaperData();
|
||||
+
|
||||
+ if (data != null) {
|
||||
+ if (data.contains("LastLogin")) {
|
||||
+ return data.getLong("LastLogin");
|
||||
+ } else {
|
||||
+ // if the player file cannot provide accurate data, this is probably the closest we can approximate
|
||||
+ File file = getDataFile();
|
||||
+ return file.lastModified();
|
||||
+ }
|
||||
+ } else {
|
||||
+ return 0;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public long getLastSeen() {
|
||||
+ Player player = getPlayer();
|
||||
+ if (player != null) return player.getLastSeen();
|
||||
+
|
||||
+ CompoundTag data = getPaperData();
|
||||
+
|
||||
+ if (data != null) {
|
||||
+ if (data.contains("LastSeen")) {
|
||||
+ return data.getLong("LastSeen");
|
||||
+ } else {
|
||||
+ // if the player file cannot provide accurate data, this is probably the closest we can approximate
|
||||
+ File file = getDataFile();
|
||||
+ return file.lastModified();
|
||||
+ }
|
||||
+ } else {
|
||||
+ return 0;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private CompoundTag getPaperData() {
|
||||
+ CompoundTag result = getData();
|
||||
+
|
||||
+ if (result != null) {
|
||||
+ if (!result.contains("Paper")) {
|
||||
+ result.put("Paper", new CompoundTag());
|
||||
+ }
|
||||
+ result = result.getCompound("Paper");
|
||||
+ }
|
||||
+
|
||||
+ return result;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public Location getLastDeathLocation() {
|
||||
if (this.getData().contains("LastDeathLocation", 10)) {
|
||||
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 {
|
||||
private BorderChangeListener clientWorldBorderListener = this.createWorldBorderListener();
|
||||
public org.bukkit.event.player.PlayerResourcePackStatusEvent.Status resourcePackStatus; // Paper - more resource pack API
|
||||
private static final boolean DISABLE_CHANNEL_LIMIT = System.getProperty("paper.disableChannelLimit") != null; // Paper - add a flag to disable the channel limit
|
||||
+ private long lastSaveTime; // Paper - getLastPlayed replacement API
|
||||
|
||||
public CraftPlayer(CraftServer server, ServerPlayer entity) {
|
||||
super(server, entity);
|
||||
@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
this.firstPlayed = firstPlayed;
|
||||
}
|
||||
|
||||
+ // Paper start - getLastPlayed replacement API
|
||||
+ @Override
|
||||
+ public long getLastLogin() {
|
||||
+ return this.getHandle().loginTime;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public long getLastSeen() {
|
||||
+ return this.isOnline() ? System.currentTimeMillis() : this.lastSaveTime;
|
||||
+ }
|
||||
+ // Paper end - getLastPlayed replacement API
|
||||
+
|
||||
public void readExtraData(CompoundTag nbttagcompound) {
|
||||
this.hasPlayedBefore = true;
|
||||
if (nbttagcompound.contains("bukkit")) {
|
||||
@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
}
|
||||
|
||||
public void setExtraData(CompoundTag nbttagcompound) {
|
||||
+ this.lastSaveTime = System.currentTimeMillis(); // Paper
|
||||
+
|
||||
if (!nbttagcompound.contains("bukkit")) {
|
||||
nbttagcompound.put("bukkit", new CompoundTag());
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
data.putLong("firstPlayed", this.getFirstPlayed());
|
||||
data.putLong("lastPlayed", System.currentTimeMillis());
|
||||
data.putString("lastKnownName", handle.getScoreboardName());
|
||||
+
|
||||
+ // Paper start - persist for use in offline save data
|
||||
+ if (!nbttagcompound.contains("Paper")) {
|
||||
+ nbttagcompound.put("Paper", new CompoundTag());
|
||||
+ }
|
||||
+
|
||||
+ CompoundTag paper = nbttagcompound.getCompound("Paper");
|
||||
+ paper.putLong("LastLogin", handle.loginTime);
|
||||
+ paper.putLong("LastSeen", System.currentTimeMillis());
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
@Override
|
@@ -1,18 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: GreenMeanie <GreenMeanieMC@gmail.com>
|
||||
Date: Sat, 20 Oct 2018 22:34:02 -0400
|
||||
Subject: [PATCH] Reset players airTicks on respawn
|
||||
|
||||
|
||||
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 {
|
||||
|
||||
this.setHealth(this.getMaxHealth());
|
||||
this.stopUsingItem(); // CraftBukkit - SPIGOT-6682: Clear active item on reset
|
||||
+ this.setAirSupply(this.getMaxAirSupply()); // Paper - Reset players airTicks on respawn
|
||||
this.setRemainingFireTicks(0);
|
||||
this.fallDistance = 0;
|
||||
this.foodData = new FoodData(this);
|
@@ -1,358 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Mon, 5 Nov 2018 04:23:51 +0000
|
||||
Subject: [PATCH] Restore custom InventoryHolder support
|
||||
|
||||
Upstream removed the ability to consistently use a custom InventoryHolder,
|
||||
However, the implementation does not use an InventoryHolder in any form
|
||||
outside of custom inventories.
|
||||
|
||||
== AT ==
|
||||
public-f net.minecraft.world.inventory.AbstractContainerMenu dataSlots
|
||||
public-f net.minecraft.world.inventory.AbstractContainerMenu remoteDataSlots
|
||||
|
||||
Co-authored-by: Shane Freeder <theboyetronic@gmail.com>
|
||||
|
||||
diff --git a/src/main/java/io/papermc/paper/inventory/PaperInventoryCustomHolderContainer.java b/src/main/java/io/papermc/paper/inventory/PaperInventoryCustomHolderContainer.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/inventory/PaperInventoryCustomHolderContainer.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package io.papermc.paper.inventory;
|
||||
+
|
||||
+import io.papermc.paper.adventure.PaperAdventure;
|
||||
+import net.kyori.adventure.text.Component;
|
||||
+import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||
+import net.minecraft.world.Container;
|
||||
+import net.minecraft.world.entity.player.Player;
|
||||
+import net.minecraft.world.item.ItemStack;
|
||||
+import net.minecraft.world.level.block.entity.BaseContainerBlockEntity;
|
||||
+import org.bukkit.Location;
|
||||
+import org.bukkit.craftbukkit.entity.CraftHumanEntity;
|
||||
+import org.bukkit.entity.HumanEntity;
|
||||
+import org.bukkit.event.inventory.InventoryType;
|
||||
+import org.bukkit.inventory.InventoryHolder;
|
||||
+import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
+import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
+import org.checkerframework.framework.qual.DefaultQualifier;
|
||||
+
|
||||
+import java.util.List;
|
||||
+
|
||||
+@DefaultQualifier(NonNull.class)
|
||||
+public final class PaperInventoryCustomHolderContainer implements Container {
|
||||
+
|
||||
+ private final InventoryHolder owner;
|
||||
+ private final Container delegate;
|
||||
+ private final InventoryType type;
|
||||
+ private final String title;
|
||||
+ private final Component adventure$title;
|
||||
+
|
||||
+ public PaperInventoryCustomHolderContainer(InventoryHolder owner, Container delegate, InventoryType type) {
|
||||
+ this.owner = owner;
|
||||
+ this.delegate = delegate;
|
||||
+ this.type = type;
|
||||
+ @Nullable Component adventure$title = null;
|
||||
+ if (delegate instanceof BaseContainerBlockEntity blockEntity) {
|
||||
+ adventure$title = blockEntity.getCustomName() != null ? PaperAdventure.asAdventure(blockEntity.getCustomName()) : null;
|
||||
+ }
|
||||
+ if (adventure$title == null) {
|
||||
+ adventure$title = type.defaultTitle();
|
||||
+ }
|
||||
+ this.adventure$title = adventure$title;
|
||||
+ this.title = LegacyComponentSerializer.legacySection().serialize(this.adventure$title);
|
||||
+ }
|
||||
+
|
||||
+ public Component title() {
|
||||
+ return this.adventure$title;
|
||||
+ }
|
||||
+
|
||||
+ public String getTitle() {
|
||||
+ return this.title;
|
||||
+ }
|
||||
+
|
||||
+ public InventoryType getType() {
|
||||
+ return this.type;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getContainerSize() {
|
||||
+ return this.delegate.getContainerSize();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isEmpty() {
|
||||
+ return this.delegate.isEmpty();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public ItemStack getItem(int slot) {
|
||||
+ return this.delegate.getItem(slot);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public ItemStack removeItem(int slot, int amount) {
|
||||
+ return this.delegate.removeItem(slot, amount);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public ItemStack removeItemNoUpdate(int slot) {
|
||||
+ return this.delegate.removeItemNoUpdate(slot);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setItem(int slot, ItemStack stack) {
|
||||
+ this.delegate.setItem(slot, stack);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getMaxStackSize() {
|
||||
+ return this.delegate.getMaxStackSize();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setChanged() {
|
||||
+ this.delegate.setChanged();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean stillValid(Player player) {
|
||||
+ return this.delegate.stillValid(player);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public List<ItemStack> getContents() {
|
||||
+ return this.delegate.getContents();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void onOpen(CraftHumanEntity who) {
|
||||
+ this.delegate.onOpen(who);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void onClose(CraftHumanEntity who) {
|
||||
+ this.delegate.onClose(who);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public List<HumanEntity> getViewers() {
|
||||
+ return this.delegate.getViewers();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public InventoryHolder getOwner() {
|
||||
+ return this.owner;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setMaxStackSize(int size) {
|
||||
+ this.delegate.setMaxStackSize(size);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public Location getLocation() {
|
||||
+ return this.delegate.getLocation();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void clearContent() {
|
||||
+ this.delegate.clearContent();
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java
|
||||
@@ -0,0 +0,0 @@ public class CraftContainer extends AbstractContainerMenu {
|
||||
public CraftContainer(final Inventory inventory, final Player player, int id) {
|
||||
this(new InventoryView() {
|
||||
|
||||
- private final String originalTitle = (inventory instanceof CraftInventoryCustom) ? ((CraftInventoryCustom.MinecraftInventory) ((CraftInventory) inventory).getInventory()).getTitle() : inventory.getType().getDefaultTitle();
|
||||
+ private final String originalTitle = inventory instanceof CraftInventoryCustom ? ((CraftInventoryCustom) inventory).getTitle() : inventory.getType().getDefaultTitle(); // Paper
|
||||
private String title = this.originalTitle;
|
||||
|
||||
@Override
|
||||
@@ -0,0 +0,0 @@ public class CraftContainer extends AbstractContainerMenu {
|
||||
// Paper start
|
||||
@Override
|
||||
public net.kyori.adventure.text.Component title() {
|
||||
- return inventory instanceof CraftInventoryCustom ? ((CraftInventoryCustom.MinecraftInventory) ((CraftInventory) inventory).getInventory()).title() : net.kyori.adventure.text.Component.text(inventory.getType().getDefaultTitle());
|
||||
+ return inventory instanceof CraftInventoryCustom custom ? custom.title() : inventory.getType().defaultTitle(); // Paper
|
||||
}
|
||||
// Paper end
|
||||
|
||||
@@ -0,0 +0,0 @@ public class CraftContainer extends AbstractContainerMenu {
|
||||
this.lastSlots = this.delegate.lastSlots;
|
||||
this.slots = this.delegate.slots;
|
||||
this.remoteSlots = this.delegate.remoteSlots;
|
||||
+ // Paper start - copy data slots for InventoryView#set/getProperty
|
||||
+ this.dataSlots = this.delegate.dataSlots;
|
||||
+ this.remoteDataSlots = this.delegate.remoteDataSlots;
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
// SPIGOT-4598 - we should still delegate the shift click handler
|
||||
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 {
|
||||
return InventoryType.BREWING;
|
||||
} else if (this.inventory instanceof CraftInventoryCustom.MinecraftInventory) {
|
||||
return ((CraftInventoryCustom.MinecraftInventory) this.inventory).getType();
|
||||
+ // Paper start
|
||||
+ } else if (this.inventory instanceof io.papermc.paper.inventory.PaperInventoryCustomHolderContainer holderContainer) {
|
||||
+ return holderContainer.getType();
|
||||
+ // Paper end
|
||||
} else if (this.inventory instanceof PlayerEnderChestContainer) {
|
||||
return InventoryType.ENDER_CHEST;
|
||||
} else if (this.inventory instanceof MerchantContainer) {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryCustom.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryCustom.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryCustom.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryCustom.java
|
||||
@@ -0,0 +0,0 @@ import org.bukkit.event.inventory.InventoryType;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
|
||||
public class CraftInventoryCustom extends CraftInventory {
|
||||
+ // Paper start
|
||||
+ public CraftInventoryCustom(InventoryHolder owner, InventoryType type, Container delegate) {
|
||||
+ super(new io.papermc.paper.inventory.PaperInventoryCustomHolderContainer(owner, delegate, type));
|
||||
+ }
|
||||
+ // Paper end
|
||||
public CraftInventoryCustom(InventoryHolder owner, InventoryType type) {
|
||||
super(new MinecraftInventory(owner, type));
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class CraftInventoryCustom extends CraftInventory {
|
||||
public CraftInventoryCustom(InventoryHolder owner, int size, String title) {
|
||||
super(new MinecraftInventory(owner, size, title));
|
||||
}
|
||||
+ // Paper start
|
||||
+ public String getTitle() {
|
||||
+ if (this.inventory instanceof MinecraftInventory minecraftInventory) {
|
||||
+ return minecraftInventory.getTitle();
|
||||
+ } else if (this.inventory instanceof io.papermc.paper.inventory.PaperInventoryCustomHolderContainer customHolderContainer) {
|
||||
+ return customHolderContainer.getTitle();
|
||||
+ } else {
|
||||
+ throw new UnsupportedOperationException(this.inventory.getClass() + " isn't a recognized Container type here");
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public net.kyori.adventure.text.Component title() {
|
||||
+ if (this.inventory instanceof MinecraftInventory minecraftInventory) {
|
||||
+ return minecraftInventory.title();
|
||||
+ } else if (this.inventory instanceof io.papermc.paper.inventory.PaperInventoryCustomHolderContainer customHolderContainer) {
|
||||
+ return customHolderContainer.title();
|
||||
+ } else {
|
||||
+ throw new UnsupportedOperationException(this.inventory.getClass() + " isn't a recognized Container type here");
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
static class MinecraftInventory implements Container {
|
||||
private final NonNullList<ItemStack> items;
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/util/CraftTileInventoryConverter.java b/src/main/java/org/bukkit/craftbukkit/inventory/util/CraftTileInventoryConverter.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/util/CraftTileInventoryConverter.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/util/CraftTileInventoryConverter.java
|
||||
@@ -0,0 +0,0 @@ public abstract class CraftTileInventoryConverter implements CraftInventoryCreat
|
||||
|
||||
@Override
|
||||
public Inventory createInventory(InventoryHolder holder, InventoryType type) {
|
||||
- return this.getInventory(this.getTileEntity());
|
||||
+ return this.getInventory(holder, type, this.getTileEntity()); // Paper
|
||||
}
|
||||
|
||||
// Paper start
|
||||
@@ -0,0 +0,0 @@ public abstract class CraftTileInventoryConverter implements CraftInventoryCreat
|
||||
((RandomizableContainerBlockEntity) te).name = io.papermc.paper.adventure.PaperAdventure.asVanilla(title);
|
||||
}
|
||||
|
||||
- return getInventory(te);
|
||||
+ return this.getInventory(owner, type, te); // Paper
|
||||
}
|
||||
// Paper end
|
||||
|
||||
@@ -0,0 +0,0 @@ public abstract class CraftTileInventoryConverter implements CraftInventoryCreat
|
||||
((RandomizableContainerBlockEntity) te).name = CraftChatMessage.fromStringOrNull(title);
|
||||
}
|
||||
|
||||
- return this.getInventory(te);
|
||||
+ return this.getInventory(holder, type, te); // Paper
|
||||
}
|
||||
|
||||
+ @Deprecated // Paper - use getInventory with owner and type
|
||||
public Inventory getInventory(Container tileEntity) {
|
||||
+ // Paper start
|
||||
+ return this.getInventory(null, null, tileEntity);
|
||||
+ }
|
||||
+
|
||||
+ public Inventory getInventory(InventoryHolder owner, InventoryType type, Container tileEntity) { // Paper
|
||||
+ if (owner != null) return new org.bukkit.craftbukkit.inventory.CraftInventoryCustom(owner, type, tileEntity); // Paper
|
||||
+ // Paper end
|
||||
return new CraftInventory(tileEntity);
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ public abstract class CraftTileInventoryConverter implements CraftInventoryCreat
|
||||
@Override
|
||||
public Inventory createInventory(InventoryHolder owner, InventoryType type, net.kyori.adventure.text.Component title) {
|
||||
Container tileEntity = getTileEntity();
|
||||
- ((AbstractFurnaceBlockEntity) tileEntity).setCustomName(io.papermc.paper.adventure.PaperAdventure.asVanilla(title));
|
||||
- return getInventory(tileEntity);
|
||||
+ ((AbstractFurnaceBlockEntity) tileEntity).name = io.papermc.paper.adventure.PaperAdventure.asVanilla(title);
|
||||
+ return this.getInventory(owner, type, tileEntity); // Paper
|
||||
}
|
||||
// Paper end
|
||||
|
||||
@@ -0,0 +0,0 @@ public abstract class CraftTileInventoryConverter implements CraftInventoryCreat
|
||||
public Inventory createInventory(InventoryHolder owner, InventoryType type, String title) {
|
||||
Container tileEntity = this.getTileEntity();
|
||||
((AbstractFurnaceBlockEntity) tileEntity).name = CraftChatMessage.fromStringOrNull(title);
|
||||
- return this.getInventory(tileEntity);
|
||||
+ return this.getInventory(owner, type, tileEntity); // Paper
|
||||
}
|
||||
|
||||
@Override
|
||||
public Inventory getInventory(Container tileEntity) {
|
||||
+ // Paper start
|
||||
+ return getInventory(null, null, tileEntity);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public Inventory getInventory(InventoryHolder owner, InventoryType type, net.minecraft.world.Container tileEntity) { // Paper
|
||||
+ if (owner != null) return new org.bukkit.craftbukkit.inventory.CraftInventoryCustom(owner, type, tileEntity); // Paper
|
||||
+ // Paper end
|
||||
return new CraftInventoryFurnace((AbstractFurnaceBlockEntity) tileEntity);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public abstract class CraftTileInventoryConverter implements CraftInventoryCreat
|
||||
if (tileEntity instanceof BrewingStandBlockEntity) {
|
||||
((BrewingStandBlockEntity) tileEntity).name = io.papermc.paper.adventure.PaperAdventure.asVanilla(title);
|
||||
}
|
||||
- return getInventory(tileEntity);
|
||||
+ return this.getInventory(owner, type, tileEntity); // Paper
|
||||
}
|
||||
// Paper end
|
||||
|
||||
@@ -0,0 +0,0 @@ public abstract class CraftTileInventoryConverter implements CraftInventoryCreat
|
||||
if (tileEntity instanceof BrewingStandBlockEntity) {
|
||||
((BrewingStandBlockEntity) tileEntity).name = CraftChatMessage.fromStringOrNull(title);
|
||||
}
|
||||
- return this.getInventory(tileEntity);
|
||||
+ return this.getInventory(holder, type, tileEntity); // Paper
|
||||
}
|
||||
|
||||
@Override
|
||||
public Inventory getInventory(Container tileEntity) {
|
||||
+ // Paper start
|
||||
+ return getInventory(null, null, tileEntity);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public Inventory getInventory(InventoryHolder owner, InventoryType type, net.minecraft.world.Container tileEntity) { // Paper
|
||||
+ if (owner != null) return new org.bukkit.craftbukkit.inventory.CraftInventoryCustom(owner, type, tileEntity); // Paper
|
||||
+ // Paper end
|
||||
return new CraftInventoryBrewer(tileEntity);
|
||||
}
|
||||
}
|
@@ -1,20 +0,0 @@
|
||||
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 );
|
||||
}
|
||||
|
@@ -1,87 +0,0 @@
|
||||
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.ItemEnchantments;
|
||||
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
|
||||
}
|
@@ -1,154 +0,0 @@
|
||||
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 @@ 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
|
||||
+ 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 com.destroystokyo.paper.event.entity.SlimeSwimEvent((org.bukkit.entity.Slime) this.slime.getBukkitEntity()).callEvent(); // Paper - Slime pathfinder events
|
||||
}
|
||||
|
||||
@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 - Slime pathfinder events
|
||||
+ 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 com.destroystokyo.paper.event.entity.SlimeTargetLivingEntityEvent((org.bukkit.entity.Slime) this.slime.getBukkitEntity(), (org.bukkit.entity.LivingEntity) entityliving.getBukkitEntity()).callEvent();
|
||||
+ // Paper end - Slime pathfinder events
|
||||
}
|
||||
|
||||
@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 - Slime pathfinder events
|
||||
+ if (entityliving == null || !entityliving.isAlive()) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ if (!this.slime.canAttack(entityliving)) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ return --this.growTiredTimer > 0 && this.slime.canWander && new com.destroystokyo.paper.event.entity.SlimeTargetLivingEntityEvent((org.bukkit.entity.Slime) this.slime.getBukkitEntity(), (org.bukkit.entity.LivingEntity) entityliving.getBukkitEntity()).callEvent();
|
||||
+ // Paper end - Slime pathfinder events
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -0,0 +0,0 @@ public class Slime extends Mob implements Enemy {
|
||||
}
|
||||
|
||||
}
|
||||
+
|
||||
+ // Paper start - Slime pathfinder events; clear timer and target when goal resets
|
||||
+ public void stop() {
|
||||
+ this.growTiredTimer = 0;
|
||||
+ this.slime.setTarget(null);
|
||||
+ }
|
||||
+ // Paper end - Slime pathfinder events
|
||||
}
|
||||
|
||||
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 - Slime pathfinder events
|
||||
}
|
||||
|
||||
@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 - Slime pathfinder events
|
||||
+ com.destroystokyo.paper.event.entity.SlimeChangeDirectionEvent event = new com.destroystokyo.paper.event.entity.SlimeChangeDirectionEvent((org.bukkit.entity.Slime) this.slime.getBukkitEntity(), this.chosenDegrees);
|
||||
+ if (!this.slime.canWander || !event.callEvent()) return;
|
||||
+ this.chosenDegrees = event.getNewYaw();
|
||||
+ // Paper end - Slime pathfinder events
|
||||
}
|
||||
|
||||
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 com.destroystokyo.paper.event.entity.SlimeWanderEvent((org.bukkit.entity.Slime) this.slime.getBukkitEntity()).callEvent(); // Paper - Slime pathfinder events
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -0,0 +0,0 @@ public class Slime extends Mob implements Enemy {
|
||||
|
||||
}
|
||||
}
|
||||
+
|
||||
+ // Paper start - Slime pathfinder events
|
||||
+ private boolean canWander = true;
|
||||
+ public boolean canWander() {
|
||||
+ return canWander;
|
||||
+ }
|
||||
+
|
||||
+ public void setWander(boolean canWander) {
|
||||
+ this.canWander = canWander;
|
||||
+ }
|
||||
+ // Paper end - Slime pathfinder events
|
||||
}
|
||||
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 String toString() {
|
||||
return "CraftSlime";
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public boolean canWander() {
|
||||
+ return getHandle().canWander();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setWander(boolean canWander) {
|
||||
+ getHandle().setWander(canWander);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
@@ -1,83 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Sat, 29 Sep 2018 16:08:23 -0500
|
||||
Subject: [PATCH] Turtle API
|
||||
|
||||
== AT ==
|
||||
public net.minecraft.world.entity.animal.Turtle getHomePos()Lnet/minecraft/core/BlockPos;
|
||||
public net.minecraft.world.entity.animal.Turtle setHasEgg(Z)V
|
||||
public net.minecraft.world.entity.animal.Turtle isGoingHome()Z
|
||||
public net.minecraft.world.entity.animal.Turtle setGoingHome(Z)V
|
||||
public net.minecraft.world.entity.animal.Turtle isTravelling()Z
|
||||
public net.minecraft.world.entity.animal.Turtle setTravelling(Z)V
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/Turtle.java b/src/main/java/net/minecraft/world/entity/animal/Turtle.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/Turtle.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/Turtle.java
|
||||
@@ -0,0 +0,0 @@ public class Turtle extends Animal {
|
||||
|
||||
if (!this.turtle.isInWater() && this.isReachedTarget()) {
|
||||
if (this.turtle.layEggCounter < 1) {
|
||||
- this.turtle.setLayingEgg(true);
|
||||
+ this.turtle.setLayingEgg(new com.destroystokyo.paper.event.entity.TurtleStartDiggingEvent((org.bukkit.entity.Turtle) this.turtle.getBukkitEntity(), io.papermc.paper.util.MCUtil.toLocation(this.turtle.level(), this.blockPos)).callEvent()); // Paper - Turtle API
|
||||
} else if (this.turtle.layEggCounter > this.adjustedTickDelay(200)) {
|
||||
Level world = this.turtle.level();
|
||||
|
||||
- if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this.turtle, this.blockPos.above(), (BlockState) Blocks.TURTLE_EGG.defaultBlockState().setValue(TurtleEggBlock.EGGS, this.turtle.random.nextInt(4) + 1))) { // CraftBukkit
|
||||
+ // Paper start - Turtle API
|
||||
+ int eggCount = this.turtle.random.nextInt(4) + 1;
|
||||
+ com.destroystokyo.paper.event.entity.TurtleLayEggEvent layEggEvent = new com.destroystokyo.paper.event.entity.TurtleLayEggEvent((org.bukkit.entity.Turtle) this.turtle.getBukkitEntity(), io.papermc.paper.util.MCUtil.toLocation(this.turtle.level(), this.blockPos.above()), eggCount);
|
||||
+ if (layEggEvent.callEvent() && org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(this.turtle, this.blockPos.above(), Blocks.TURTLE_EGG.defaultBlockState().setValue(TurtleEggBlock.EGGS, layEggEvent.getEggCount()))) {
|
||||
world.playSound((Player) null, blockposition, SoundEvents.TURTLE_LAY_EGG, SoundSource.BLOCKS, 0.3F, 0.9F + world.random.nextFloat() * 0.2F);
|
||||
BlockPos blockposition1 = this.blockPos.above();
|
||||
- BlockState iblockdata = (BlockState) Blocks.TURTLE_EGG.defaultBlockState().setValue(TurtleEggBlock.EGGS, this.turtle.random.nextInt(4) + 1);
|
||||
+ BlockState iblockdata = (BlockState) Blocks.TURTLE_EGG.defaultBlockState().setValue(TurtleEggBlock.EGGS, layEggEvent.getEggCount()); // Paper
|
||||
|
||||
world.setBlock(blockposition1, iblockdata, 3);
|
||||
world.gameEvent((Holder) GameEvent.BLOCK_PLACE, blockposition1, GameEvent.Context.of(this.turtle, iblockdata));
|
||||
@@ -0,0 +0,0 @@ public class Turtle extends Animal {
|
||||
|
||||
@Override
|
||||
public boolean canUse() {
|
||||
- return this.turtle.isBaby() ? false : (this.turtle.hasEgg() ? true : (this.turtle.getRandom().nextInt(reducedTickDelay(700)) != 0 ? false : !this.turtle.getHomePos().closerToCenterThan(this.turtle.position(), 64.0D)));
|
||||
+ return this.turtle.isBaby() ? false : (this.turtle.hasEgg() ? true : (this.turtle.getRandom().nextInt(reducedTickDelay(700)) != 0 ? false : !this.turtle.getHomePos().closerToCenterThan(this.turtle.position(), 64.0D))) && new com.destroystokyo.paper.event.entity.TurtleGoHomeEvent((org.bukkit.entity.Turtle) this.turtle.getBukkitEntity()).callEvent(); // Paper - Turtle API
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftTurtle.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftTurtle.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftTurtle.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftTurtle.java
|
||||
@@ -0,0 +0,0 @@ public class CraftTurtle extends CraftAnimals implements Turtle {
|
||||
public boolean isLayingEgg() {
|
||||
return this.getHandle().isLayingEgg();
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public org.bukkit.Location getHome() {
|
||||
+ return io.papermc.paper.util.MCUtil.toLocation(this.getHandle().level(), this.getHandle().getHomePos());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setHome(org.bukkit.Location location) {
|
||||
+ this.getHandle().setHomePos(io.papermc.paper.util.MCUtil.toBlockPosition(location));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isGoingHome() {
|
||||
+ return this.getHandle().isGoingHome();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isDigging() {
|
||||
+ return this.getHandle().isLayingEgg();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setHasEgg(boolean hasEgg) {
|
||||
+ this.getHandle().setHasEgg(hasEgg);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
@@ -1,19 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sun, 10 Jun 2018 01:18:49 -0400
|
||||
Subject: [PATCH] Unset Ignited flag on cancel of Explosion Event
|
||||
|
||||
Otherwise the creeper infinite explodes
|
||||
|
||||
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 {
|
||||
// CraftBukkit start
|
||||
} else {
|
||||
this.swell = 0;
|
||||
+ this.entityData.set(DATA_IS_IGNITED, Boolean.valueOf(false)); // Paper
|
||||
}
|
||||
// CraftBukkit end
|
||||
}
|
@@ -1,108 +0,0 @@
|
||||
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 - ProfileWhitelistVerifyEvent
|
||||
//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 @@ 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();
|
||||
+ private final Map<String, V> map = Maps.newConcurrentMap(); // Paper - Use ConcurrentHashMap in JsonList
|
||||
|
||||
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 - Use ConcurrentHashMap in JsonList
|
||||
+ return (V) this.map.computeIfPresent(this.getKeyForUser(key), (k, v) -> {
|
||||
+ return v.hasExpired() ? null : v;
|
||||
+ });
|
||||
+ // Paper end - Use ConcurrentHashMap in JsonList
|
||||
}
|
||||
|
||||
public void remove(K key) {
|
||||
@@ -0,0 +0,0 @@ public abstract class StoredUserList<K, V extends StoredUserEntry<K>> {
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
- return this.map.size() < 1;
|
||||
+ return this.map.isEmpty(); // Paper - Use ConcurrentHashMap in JsonList
|
||||
}
|
||||
|
||||
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();
|
||||
-
|
||||
- while (iterator.hasNext()) {
|
||||
- V v0 = (V) iterator.next(); // CraftBukkit - decompile error
|
||||
-
|
||||
- if (v0.hasExpired()) {
|
||||
- list.add(v0.getUser());
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- iterator = list.iterator();
|
||||
-
|
||||
- while (iterator.hasNext()) {
|
||||
- K k0 = (K) iterator.next(); // CraftBukkit - decompile error
|
||||
-
|
||||
- this.map.remove(this.getKeyForUser(k0));
|
||||
- }
|
||||
-
|
||||
+ this.map.values().removeIf(StoredUserEntry::hasExpired); // Paper - Use ConcurrentHashMap in JsonList
|
||||
}
|
||||
|
||||
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();
|
@@ -1,39 +0,0 @@
|
||||
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 - Perf: use a proper queue
|
||||
@Nullable
|
||||
private QueryThreadGs4 queryThreadGs4;
|
||||
// private final RemoteControlCommandListener rconConsoleSource; // CraftBukkit - remove field
|
||||
@@ -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 - Perf: use proper queue
|
||||
}
|
||||
|
||||
public void handleConsoleInputs() {
|
||||
MinecraftTimings.serverCommandTimer.startTiming(); // Spigot
|
||||
- while (!this.consoleInput.isEmpty()) {
|
||||
- ConsoleInput servercommand = (ConsoleInput) this.consoleInput.remove(0);
|
||||
+ // Paper start - Perf: use proper queue
|
||||
+ ConsoleInput servercommand;
|
||||
+ while ((servercommand = this.serverCommandQueue.poll()) != null) {
|
||||
+ // Paper end - Perf: use proper queue
|
||||
|
||||
// CraftBukkit start - ServerCommand for preprocessing
|
||||
ServerCommandEvent event = new ServerCommandEvent(this.console, servercommand.msg);
|
@@ -1,109 +0,0 @@
|
||||
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 - Cancel hit for vanished players
|
||||
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 - Cancel hit for vanished players
|
||||
+ boolean defaultReturn = (!this.mustSurvive() || state.canSurvive(context.getLevel(), context.getClickedPos())) && world.checkEntityCollision(state, entityhuman, voxelshapecollision, context.getClickedPos(), true); // Paper - Cancel hit for vanished players
|
||||
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(this.spigotConfig.tileMaxTickTime);
|
||||
}
|
||||
|
||||
+ // Paper start - Cancel hit for vanished players
|
||||
+ // 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 - Cancel hit for vanished players
|
||||
@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;
|
||||
}
|
@@ -1,34 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Wed, 4 Jul 2018 15:30:22 -0400
|
||||
Subject: [PATCH] Vex#get/setSummoner API
|
||||
|
||||
Get's the NPC that summoned this Vex and
|
||||
Allow setting the vex's summoner
|
||||
|
||||
Co-authored-by: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftVex.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftVex.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftVex.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftVex.java
|
||||
@@ -0,0 +0,0 @@ public class CraftVex extends CraftMonster implements Vex {
|
||||
return (net.minecraft.world.entity.monster.Vex) super.getHandle();
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public org.bukkit.entity.Mob getSummoner() {
|
||||
+ net.minecraft.world.entity.Mob owner = getHandle().getOwner();
|
||||
+ return owner != null ? (org.bukkit.entity.Mob) owner.getBukkitEntity() : null;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setSummoner(org.bukkit.entity.Mob summoner) {
|
||||
+ getHandle().setOwner(summoner == null ? null : ((CraftMob) summoner).getHandle());
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CraftVex";
|
@@ -1,24 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: connorhartley <vectrixu+gh@gmail.com>
|
||||
Date: Mon, 7 Jan 2019 14:43:48 -0600
|
||||
Subject: [PATCH] Workaround for vehicle tracking issue on disconnect
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
index 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 void disconnect() {
|
||||
this.disconnected = true;
|
||||
this.ejectPassengers();
|
||||
+
|
||||
+ // Paper start - Workaround vehicle not tracking the passenger disconnection dismount
|
||||
+ if (this.isPassenger() && this.getVehicle() instanceof ServerPlayer) {
|
||||
+ this.stopRiding();
|
||||
+ }
|
||||
+ // Paper end - Workaround vehicle not tracking the passenger disconnection dismount
|
||||
+
|
||||
if (this.isSleeping()) {
|
||||
this.stopSleepInBed(true, false);
|
||||
}
|
@@ -1,20 +0,0 @@
|
||||
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 SyncedDataHolder, Nameable, EntityAccess
|
||||
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); // Paper - add more info
|
||||
}
|
||||
|
||||
public boolean isInvulnerableTo(DamageSource damageSource) {
|
@@ -1,166 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shane Freeder <theboyetronic@gmail.com>
|
||||
Date: Thu, 15 Nov 2018 13:38:37 +0000
|
||||
Subject: [PATCH] force entity dismount during teleportation
|
||||
|
||||
Entities must be dismounted before teleportation in order to avoid
|
||||
multiple issues in the server with regards to teleportation, shamefully,
|
||||
too many plugins rely on the events firing, which means that not firing
|
||||
these events caues more issues than it solves;
|
||||
|
||||
In order to counteract this, Entity dismount/exit vehicle events have
|
||||
been modified to supress cancellation (and has a method to allow plugins
|
||||
to check if this has been set), noting that cancellation will be silently
|
||||
surpressed given that plugins are not expecting this event to not be cancellable.
|
||||
|
||||
This is a far from ideal scenario, however: given the current state of this
|
||||
event and other alternatives causing issues elsewhere, I believe that
|
||||
this is going to be the best soultion all around.
|
||||
|
||||
Improvements/suggestions welcome!
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
index 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 {
|
||||
|
||||
@Override
|
||||
public void stopRiding() {
|
||||
+ // Paper start - Force entity dismount during teleportation
|
||||
+ this.stopRiding(false);
|
||||
+ }
|
||||
+ @Override
|
||||
+ public void stopRiding(boolean suppressCancellation) {
|
||||
+ // Paper end - Force entity dismount during teleportation
|
||||
Entity entity = this.getVehicle();
|
||||
|
||||
- super.stopRiding();
|
||||
+ super.stopRiding(suppressCancellation); // Paper - Force entity dismount during teleportation
|
||||
if (entity instanceof LivingEntity entityliving) {
|
||||
Iterator iterator = entityliving.getActiveEffects().iterator();
|
||||
|
||||
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 SyncedDataHolder, Nameable, EntityAccess
|
||||
}
|
||||
|
||||
public void removeVehicle() {
|
||||
+ // Paper start - Force entity dismount during teleportation
|
||||
+ this.removeVehicle(false);
|
||||
+ }
|
||||
+ public void removeVehicle(boolean suppressCancellation) {
|
||||
+ // Paper end - Force entity dismount during teleportation
|
||||
if (this.vehicle != null) {
|
||||
Entity entity = this.vehicle;
|
||||
|
||||
this.vehicle = null;
|
||||
- if (!entity.removePassenger(this)) this.vehicle = entity; // CraftBukkit
|
||||
+ if (!entity.removePassenger(this, suppressCancellation)) this.vehicle = entity; // CraftBukkit // Paper - Force entity dismount during teleportation
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void stopRiding() {
|
||||
- this.removeVehicle();
|
||||
+ // Paper start - Force entity dismount during teleportation
|
||||
+ this.stopRiding(false);
|
||||
+ }
|
||||
+
|
||||
+ public void stopRiding(boolean suppressCancellation) {
|
||||
+ this.removeVehicle(suppressCancellation);
|
||||
+ // Paper end - Force entity dismount during teleportation
|
||||
}
|
||||
|
||||
protected void addPassenger(Entity passenger) {
|
||||
@@ -0,0 +0,0 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
}
|
||||
}
|
||||
|
||||
- protected boolean removePassenger(Entity entity) { // CraftBukkit
|
||||
+ // Paper start - Force entity dismount during teleportation
|
||||
+ protected boolean removePassenger(Entity entity) { return removePassenger(entity, false);}
|
||||
+ protected boolean removePassenger(Entity entity, boolean suppressCancellation) { // CraftBukkit
|
||||
+ // Paper end - Force entity dismount during teleportation
|
||||
if (entity.getVehicle() == this) {
|
||||
throw new IllegalStateException("Use x.stopRiding(y), not y.removePassenger(x)");
|
||||
} else {
|
||||
@@ -0,0 +0,0 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
if (this.getBukkitEntity() instanceof Vehicle && entity.getBukkitEntity() instanceof LivingEntity) {
|
||||
VehicleExitEvent event = new VehicleExitEvent(
|
||||
(Vehicle) this.getBukkitEntity(),
|
||||
- (LivingEntity) entity.getBukkitEntity()
|
||||
+ (LivingEntity) entity.getBukkitEntity(), !suppressCancellation // Paper - Force entity dismount during teleportation
|
||||
);
|
||||
// Suppress during worldgen
|
||||
if (this.valid) {
|
||||
@@ -0,0 +0,0 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||
}
|
||||
}
|
||||
|
||||
- EntityDismountEvent event = new EntityDismountEvent(entity.getBukkitEntity(), this.getBukkitEntity());
|
||||
+ EntityDismountEvent event = new EntityDismountEvent(entity.getBukkitEntity(), this.getBukkitEntity(), !suppressCancellation); // Paper - Force entity dismount during teleportation
|
||||
// Suppress during worldgen
|
||||
if (this.valid) {
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
index 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 {
|
||||
|
||||
@Override
|
||||
public void stopRiding() {
|
||||
+ // Paper start - Force entity dismount during teleportation
|
||||
+ this.stopRiding(false);
|
||||
+ }
|
||||
+ @Override
|
||||
+ public void stopRiding(boolean suppressCancellation) {
|
||||
+ // Paper end - Force entity dismount during teleportation
|
||||
Entity entity = this.getVehicle();
|
||||
|
||||
- super.stopRiding();
|
||||
+ super.stopRiding(suppressCancellation); // Paper - Force entity dismount during teleportation
|
||||
if (entity != null && entity != this.getVehicle() && !this.level().isClientSide) {
|
||||
this.dismountVehicle(entity);
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/Shulker.java b/src/main/java/net/minecraft/world/entity/monster/Shulker.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Shulker.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Shulker.java
|
||||
@@ -0,0 +0,0 @@ public class Shulker extends AbstractGolem implements VariantHolder<Optional<Dye
|
||||
|
||||
@Override
|
||||
public void stopRiding() {
|
||||
- super.stopRiding();
|
||||
+ // Paper start - Force entity dismount during teleportation
|
||||
+ this.stopRiding(false);
|
||||
+ }
|
||||
+ @Override
|
||||
+ public void stopRiding(boolean suppressCancellation) {
|
||||
+ super.stopRiding(suppressCancellation);
|
||||
+ // Paper end - Force entity dismount during teleportation
|
||||
if (this.level().isClientSide) {
|
||||
this.clientOldAttachPosition = this.blockPosition();
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Player extends LivingEntity {
|
||||
|
||||
@Override
|
||||
public void removeVehicle() {
|
||||
- super.removeVehicle();
|
||||
+ // Paper start - Force entity dismount during teleportation
|
||||
+ this.removeVehicle(false);
|
||||
+ }
|
||||
+ @Override
|
||||
+ public void removeVehicle(boolean suppressCancellation) {
|
||||
+ super.removeVehicle(suppressCancellation);
|
||||
+ // Paper end - Force entity dismount during teleportation
|
||||
this.boardingCooldown = 0;
|
||||
}
|
||||
|
Reference in New Issue
Block a user