More more more work
This commit is contained in:
parent
01f5831171
commit
474a02835d
46 changed files with 183 additions and 220 deletions
|
@ -0,0 +1,780 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sun, 1 May 2016 21:19:14 -0400
|
||||
Subject: [PATCH] LootTable API & Replenishable Lootables Feature
|
||||
|
||||
Provides an API to control the loot table for an object.
|
||||
Also provides a feature that any Lootable Inventory (Chests in Structures)
|
||||
can automatically replenish after a given time.
|
||||
|
||||
This feature is good for long term worlds so that newer players
|
||||
do not suffer with "Every chest has been looted"
|
||||
|
||||
== AT ==
|
||||
public org.bukkit.craftbukkit.block.CraftBlockEntityState getTileEntity()Lnet/minecraft/world/level/block/entity/BlockEntity;
|
||||
public org.bukkit.craftbukkit.block.CraftLootable setLootTable(Lorg/bukkit/loot/LootTable;J)V
|
||||
public org.bukkit.craftbukkit.entity.CraftMinecartContainer setLootTable(Lorg/bukkit/loot/LootTable;J)V
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/loottable/PaperContainerEntityLootableInventory.java b/src/main/java/com/destroystokyo/paper/loottable/PaperContainerEntityLootableInventory.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..88e32ed64f90bfd277dac84ba4bd84f0d943f5f8
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/loottable/PaperContainerEntityLootableInventory.java
|
||||
@@ -0,0 +1,63 @@
|
||||
+package com.destroystokyo.paper.loottable;
|
||||
+
|
||||
+import net.minecraft.world.entity.Entity;
|
||||
+import net.minecraft.world.entity.vehicle.AbstractMinecartContainer;
|
||||
+import net.minecraft.world.entity.vehicle.ContainerEntity;
|
||||
+import net.minecraft.world.level.Level;
|
||||
+import org.bukkit.Bukkit;
|
||||
+import org.bukkit.craftbukkit.util.CraftNamespacedKey;
|
||||
+
|
||||
+public class PaperContainerEntityLootableInventory implements PaperLootableEntityInventory {
|
||||
+
|
||||
+ private final ContainerEntity entity;
|
||||
+
|
||||
+ public PaperContainerEntityLootableInventory(ContainerEntity entity) {
|
||||
+ this.entity = entity;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public org.bukkit.loot.LootTable getLootTable() {
|
||||
+ return entity.getLootTable() != null ? Bukkit.getLootTable(CraftNamespacedKey.fromMinecraft(entity.getLootTable())) : null;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setLootTable(org.bukkit.loot.LootTable table, long seed) {
|
||||
+ setLootTable(table);
|
||||
+ setSeed(seed);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setSeed(long seed) {
|
||||
+ entity.setLootTableSeed(seed);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public long getSeed() {
|
||||
+ return entity.getLootTableSeed();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setLootTable(org.bukkit.loot.LootTable table) {
|
||||
+ entity.setLootTable((table == null) ? null : CraftNamespacedKey.toMinecraft(table.getKey()));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public PaperLootableInventoryData getLootableData() {
|
||||
+ return entity.getLootableData();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public Entity getHandle() {
|
||||
+ return entity.getEntity();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public LootableInventory getAPILootableInventory() {
|
||||
+ return (LootableInventory) entity.getEntity().getBukkitEntity();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public Level getNMSWorld() {
|
||||
+ return entity.getLevel();
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/loottable/PaperLootableBlockInventory.java b/src/main/java/com/destroystokyo/paper/loottable/PaperLootableBlockInventory.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..24c6ff57cd25533e71f8a1d0b3c0ece2fdbbf87e
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/loottable/PaperLootableBlockInventory.java
|
||||
@@ -0,0 +1,33 @@
|
||||
+package com.destroystokyo.paper.loottable;
|
||||
+
|
||||
+import net.minecraft.core.BlockPos;
|
||||
+import net.minecraft.world.level.Level;
|
||||
+import net.minecraft.world.level.block.entity.RandomizableContainerBlockEntity;
|
||||
+import org.bukkit.Chunk;
|
||||
+import org.bukkit.block.Block;
|
||||
+
|
||||
+public interface PaperLootableBlockInventory extends LootableBlockInventory, PaperLootableInventory {
|
||||
+
|
||||
+ RandomizableContainerBlockEntity getTileEntity();
|
||||
+
|
||||
+ @Override
|
||||
+ default LootableInventory getAPILootableInventory() {
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ default Level getNMSWorld() {
|
||||
+ return this.getTileEntity().getLevel();
|
||||
+ }
|
||||
+
|
||||
+ default Block getBlock() {
|
||||
+ final BlockPos position = this.getTileEntity().getBlockPos();
|
||||
+ final Chunk bukkitChunk = this.getBukkitWorld().getChunkAt(org.bukkit.craftbukkit.block.CraftBlock.at(this.getNMSWorld(), position));
|
||||
+ return bukkitChunk.getBlock(position.getX(), position.getY(), position.getZ());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ default PaperLootableInventoryData getLootableData() {
|
||||
+ return this.getTileEntity().lootableData;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/loottable/PaperLootableEntityInventory.java b/src/main/java/com/destroystokyo/paper/loottable/PaperLootableEntityInventory.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..2fba5bc0f982e143ad5f5bda55d768edc5f847df
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/loottable/PaperLootableEntityInventory.java
|
||||
@@ -0,0 +1,28 @@
|
||||
+package com.destroystokyo.paper.loottable;
|
||||
+
|
||||
+import net.minecraft.world.level.Level;
|
||||
+import org.bukkit.entity.Entity;
|
||||
+
|
||||
+public interface PaperLootableEntityInventory extends LootableEntityInventory, PaperLootableInventory {
|
||||
+
|
||||
+ net.minecraft.world.entity.Entity getHandle();
|
||||
+
|
||||
+ @Override
|
||||
+ default LootableInventory getAPILootableInventory() {
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ default Entity getEntity() {
|
||||
+ return getHandle().getBukkitEntity();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ default Level getNMSWorld() {
|
||||
+ return getHandle().getCommandSenderWorld();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ default PaperLootableInventoryData getLootableData() {
|
||||
+ return getHandle().lootableData;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/loottable/PaperLootableInventory.java b/src/main/java/com/destroystokyo/paper/loottable/PaperLootableInventory.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..ce135d990c785b02df468391ea622aa236290f07
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/loottable/PaperLootableInventory.java
|
||||
@@ -0,0 +1,70 @@
|
||||
+package com.destroystokyo.paper.loottable;
|
||||
+
|
||||
+import org.bukkit.loot.Lootable;
|
||||
+import java.util.UUID;
|
||||
+import net.minecraft.world.level.Level;
|
||||
+
|
||||
+public interface PaperLootableInventory extends LootableInventory, Lootable {
|
||||
+
|
||||
+ PaperLootableInventoryData getLootableData();
|
||||
+ LootableInventory getAPILootableInventory();
|
||||
+
|
||||
+ Level getNMSWorld();
|
||||
+
|
||||
+ default org.bukkit.World getBukkitWorld() {
|
||||
+ return getNMSWorld().getWorld();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ default boolean isRefillEnabled() {
|
||||
+ return getNMSWorld().paperConfig().lootables.autoReplenish;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ default boolean hasBeenFilled() {
|
||||
+ return getLastFilled() != -1;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ default boolean hasPlayerLooted(UUID player) {
|
||||
+ return getLootableData().hasPlayerLooted(player);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ default Long getLastLooted(UUID player) {
|
||||
+ return getLootableData().getLastLooted(player);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ default boolean setHasPlayerLooted(UUID player, boolean looted) {
|
||||
+ final boolean hasLooted = hasPlayerLooted(player);
|
||||
+ if (hasLooted != looted) {
|
||||
+ getLootableData().setPlayerLootedState(player, looted);
|
||||
+ }
|
||||
+ return hasLooted;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ default boolean hasPendingRefill() {
|
||||
+ long nextRefill = getLootableData().getNextRefill();
|
||||
+ return nextRefill != -1 && nextRefill > getLootableData().getLastFill();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ default long getLastFilled() {
|
||||
+ return getLootableData().getLastFill();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ default long getNextRefill() {
|
||||
+ return getLootableData().getNextRefill();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ default long setNextRefill(long refillAt) {
|
||||
+ if (refillAt < -1) {
|
||||
+ refillAt = -1;
|
||||
+ }
|
||||
+ return getLootableData().setNextRefill(refillAt);
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/loottable/PaperLootableInventoryData.java b/src/main/java/com/destroystokyo/paper/loottable/PaperLootableInventoryData.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..e5ea9f27a1936ed9e329e74317c91c5df89b9fbd
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/loottable/PaperLootableInventoryData.java
|
||||
@@ -0,0 +1,179 @@
|
||||
+package com.destroystokyo.paper.loottable;
|
||||
+
|
||||
+import io.papermc.paper.configuration.WorldConfiguration;
|
||||
+import org.bukkit.entity.Player;
|
||||
+import org.bukkit.loot.LootTable;
|
||||
+import javax.annotation.Nullable;
|
||||
+import net.minecraft.nbt.CompoundTag;
|
||||
+import net.minecraft.nbt.ListTag;
|
||||
+import java.util.HashMap;
|
||||
+import java.util.Map;
|
||||
+import java.util.Random;
|
||||
+import java.util.UUID;
|
||||
+
|
||||
+public class PaperLootableInventoryData {
|
||||
+
|
||||
+ private static final Random RANDOM = new Random();
|
||||
+
|
||||
+ private long lastFill = -1;
|
||||
+ private long nextRefill = -1;
|
||||
+ private int numRefills = 0;
|
||||
+ private Map<UUID, Long> lootedPlayers;
|
||||
+ private final PaperLootableInventory lootable;
|
||||
+
|
||||
+ public PaperLootableInventoryData(PaperLootableInventory lootable) {
|
||||
+ this.lootable = lootable;
|
||||
+ }
|
||||
+
|
||||
+ long getLastFill() {
|
||||
+ return this.lastFill;
|
||||
+ }
|
||||
+
|
||||
+ long getNextRefill() {
|
||||
+ return this.nextRefill;
|
||||
+ }
|
||||
+
|
||||
+ long setNextRefill(long nextRefill) {
|
||||
+ long prev = this.nextRefill;
|
||||
+ this.nextRefill = nextRefill;
|
||||
+ return prev;
|
||||
+ }
|
||||
+
|
||||
+ public boolean shouldReplenish(@Nullable net.minecraft.world.entity.player.Player player) {
|
||||
+ LootTable table = this.lootable.getLootTable();
|
||||
+
|
||||
+ // No Loot Table associated
|
||||
+ if (table == null) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ // ALWAYS process the first fill or if the feature is disabled
|
||||
+ if (this.lastFill == -1 || !this.lootable.getNMSWorld().paperConfig().lootables.autoReplenish) {
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ // Only process refills when a player is set
|
||||
+ if (player == null) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ // Chest is not scheduled for refill
|
||||
+ if (this.nextRefill == -1) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ final WorldConfiguration paperConfig = this.lootable.getNMSWorld().paperConfig();
|
||||
+
|
||||
+ // Check if max refills has been hit
|
||||
+ if (paperConfig.lootables.maxRefills != -1 && this.numRefills >= paperConfig.lootables.maxRefills) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ // Refill has not been reached
|
||||
+ if (this.nextRefill > System.currentTimeMillis()) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ final Player bukkitPlayer = (Player) player.getBukkitEntity();
|
||||
+ LootableInventoryReplenishEvent event = new LootableInventoryReplenishEvent(bukkitPlayer, lootable.getAPILootableInventory());
|
||||
+ if (paperConfig.lootables.restrictPlayerReloot && hasPlayerLooted(player.getUUID())) {
|
||||
+ event.setCancelled(true);
|
||||
+ }
|
||||
+ return event.callEvent();
|
||||
+ }
|
||||
+ public void processRefill(@Nullable net.minecraft.world.entity.player.Player player) {
|
||||
+ this.lastFill = System.currentTimeMillis();
|
||||
+ final WorldConfiguration paperConfig = this.lootable.getNMSWorld().paperConfig();
|
||||
+ if (paperConfig.lootables.autoReplenish) {
|
||||
+ long min = paperConfig.lootables.refreshMin.seconds();
|
||||
+ long max = paperConfig.lootables.refreshMax.seconds();
|
||||
+ this.nextRefill = this.lastFill + (min + RANDOM.nextLong(max - min + 1)) * 1000L;
|
||||
+ this.numRefills++;
|
||||
+ if (paperConfig.lootables.resetSeedOnFill) {
|
||||
+ this.lootable.setSeed(0);
|
||||
+ }
|
||||
+ if (player != null) { // This means that numRefills can be incremented without a player being in the lootedPlayers list - Seems to be EntityMinecartChest specific
|
||||
+ this.setPlayerLootedState(player.getUUID(), true);
|
||||
+ }
|
||||
+ } else {
|
||||
+ this.lootable.clearLootTable();
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ public void loadNbt(CompoundTag base) {
|
||||
+ if (!base.contains("Paper.LootableData", 10)) { // 10 = compound
|
||||
+ return;
|
||||
+ }
|
||||
+ CompoundTag comp = base.getCompound("Paper.LootableData");
|
||||
+ if (comp.contains("lastFill")) {
|
||||
+ this.lastFill = comp.getLong("lastFill");
|
||||
+ }
|
||||
+ if (comp.contains("nextRefill")) {
|
||||
+ this.nextRefill = comp.getLong("nextRefill");
|
||||
+ }
|
||||
+
|
||||
+ if (comp.contains("numRefills")) {
|
||||
+ this.numRefills = comp.getInt("numRefills");
|
||||
+ }
|
||||
+ if (comp.contains("lootedPlayers", 9)) { // 9 = list
|
||||
+ ListTag list = comp.getList("lootedPlayers", 10); // 10 = compound
|
||||
+ final int size = list.size();
|
||||
+ if (size > 0) {
|
||||
+ this.lootedPlayers = new HashMap<>(list.size());
|
||||
+ }
|
||||
+ for (int i = 0; i < size; i++) {
|
||||
+ final CompoundTag cmp = list.getCompound(i);
|
||||
+ lootedPlayers.put(cmp.getUUID("UUID"), cmp.getLong("Time"));
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ public void saveNbt(CompoundTag base) {
|
||||
+ CompoundTag comp = new CompoundTag();
|
||||
+ if (this.nextRefill != -1) {
|
||||
+ comp.putLong("nextRefill", this.nextRefill);
|
||||
+ }
|
||||
+ if (this.lastFill != -1) {
|
||||
+ comp.putLong("lastFill", this.lastFill);
|
||||
+ }
|
||||
+ if (this.numRefills != 0) {
|
||||
+ comp.putInt("numRefills", this.numRefills);
|
||||
+ }
|
||||
+ if (this.lootedPlayers != null && !this.lootedPlayers.isEmpty()) {
|
||||
+ ListTag list = new ListTag();
|
||||
+ for (Map.Entry<UUID, Long> entry : this.lootedPlayers.entrySet()) {
|
||||
+ CompoundTag cmp = new CompoundTag();
|
||||
+ cmp.putUUID("UUID", entry.getKey());
|
||||
+ cmp.putLong("Time", entry.getValue());
|
||||
+ list.add(cmp);
|
||||
+ }
|
||||
+ comp.put("lootedPlayers", list);
|
||||
+ }
|
||||
+
|
||||
+ if (!comp.isEmpty()) {
|
||||
+ base.put("Paper.LootableData", comp);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ void setPlayerLootedState(UUID player, boolean looted) {
|
||||
+ if (looted && this.lootedPlayers == null) {
|
||||
+ this.lootedPlayers = new HashMap<>();
|
||||
+ }
|
||||
+ if (looted) {
|
||||
+ if (!this.lootedPlayers.containsKey(player)) {
|
||||
+ this.lootedPlayers.put(player, System.currentTimeMillis());
|
||||
+ }
|
||||
+ } else if (this.lootedPlayers != null) {
|
||||
+ this.lootedPlayers.remove(player);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ boolean hasPlayerLooted(UUID player) {
|
||||
+ return this.lootedPlayers != null && this.lootedPlayers.containsKey(player);
|
||||
+ }
|
||||
+
|
||||
+ Long getLastLooted(UUID player) {
|
||||
+ return lootedPlayers != null ? lootedPlayers.get(player) : null;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/loottable/PaperTileEntityLootableInventory.java b/src/main/java/com/destroystokyo/paper/loottable/PaperTileEntityLootableInventory.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..9cfa5d36a6991067a3866e0d437749fafcc0158e
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/loottable/PaperTileEntityLootableInventory.java
|
||||
@@ -0,0 +1,65 @@
|
||||
+package com.destroystokyo.paper.loottable;
|
||||
+
|
||||
+import io.papermc.paper.util.MCUtil;
|
||||
+import net.minecraft.world.level.Level;
|
||||
+import net.minecraft.world.level.block.entity.RandomizableContainerBlockEntity;
|
||||
+import org.bukkit.Bukkit;
|
||||
+import org.bukkit.craftbukkit.util.CraftNamespacedKey;
|
||||
+
|
||||
+public class PaperTileEntityLootableInventory implements PaperLootableBlockInventory {
|
||||
+ private RandomizableContainerBlockEntity tileEntityLootable;
|
||||
+
|
||||
+ public PaperTileEntityLootableInventory(RandomizableContainerBlockEntity tileEntityLootable) {
|
||||
+ this.tileEntityLootable = tileEntityLootable;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public org.bukkit.loot.LootTable getLootTable() {
|
||||
+ return tileEntityLootable.lootTable != null ? Bukkit.getLootTable(CraftNamespacedKey.fromMinecraft(tileEntityLootable.lootTable)) : null;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setLootTable(org.bukkit.loot.LootTable table, long seed) {
|
||||
+ setLootTable(table);
|
||||
+ setSeed(seed);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setLootTable(org.bukkit.loot.LootTable table) {
|
||||
+ tileEntityLootable.lootTable = (table == null) ? null : CraftNamespacedKey.toMinecraft(table.getKey());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setSeed(long seed) {
|
||||
+ tileEntityLootable.lootTableSeed = seed;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public long getSeed() {
|
||||
+ return tileEntityLootable.lootTableSeed;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public PaperLootableInventoryData getLootableData() {
|
||||
+ return tileEntityLootable.lootableData;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public RandomizableContainerBlockEntity getTileEntity() {
|
||||
+ return tileEntityLootable;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public LootableInventory getAPILootableInventory() {
|
||||
+ Level world = tileEntityLootable.getLevel();
|
||||
+ if (world == null) {
|
||||
+ return null;
|
||||
+ }
|
||||
+ return (LootableInventory) getBukkitWorld().getBlockAt(MCUtil.toLocation(world, tileEntityLootable.getBlockPos())).getState();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public Level getNMSWorld() {
|
||||
+ return tileEntityLootable.getLevel();
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
index 09cf1125221bdbebddabfc46095c3dbd153714c1..49f465d0009b084be2a8e809c53126af1ad72cd2 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -235,6 +235,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
|
||||
}
|
||||
// Paper end
|
||||
|
||||
+ public com.destroystokyo.paper.loottable.PaperLootableInventoryData lootableData; // Paper
|
||||
private CraftEntity bukkitEntity;
|
||||
|
||||
public CraftEntity getBukkitEntity() {
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java
|
||||
index 0ec2db500e4a0230a91286a709b8d444d1b529f4..272095d7a09ab41227d741172735f66fd2798ce1 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java
|
||||
@@ -32,6 +32,20 @@ public abstract class AbstractMinecartContainer extends AbstractMinecart impleme
|
||||
public ResourceLocation lootTable;
|
||||
public long lootTableSeed;
|
||||
|
||||
+ // Paper start
|
||||
+ {
|
||||
+ this.lootableData = new com.destroystokyo.paper.loottable.PaperLootableInventoryData(new com.destroystokyo.paper.loottable.PaperContainerEntityLootableInventory(this));
|
||||
+ }
|
||||
+ @Override
|
||||
+ public Entity getEntity() {
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public com.destroystokyo.paper.loottable.PaperLootableInventoryData getLootableData() {
|
||||
+ return this.lootableData;
|
||||
+ }
|
||||
+ // Paper end
|
||||
// CraftBukkit start
|
||||
public List<HumanEntity> transaction = new java.util.ArrayList<HumanEntity>();
|
||||
private int maxStack = MAX_STACK;
|
||||
@@ -134,12 +148,14 @@ public abstract class AbstractMinecartContainer extends AbstractMinecart impleme
|
||||
@Override
|
||||
protected void addAdditionalSaveData(CompoundTag nbt) {
|
||||
super.addAdditionalSaveData(nbt);
|
||||
+ this.lootableData.saveNbt(nbt); // Paper
|
||||
this.addChestVehicleSaveData(nbt);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void readAdditionalSaveData(CompoundTag nbt) {
|
||||
super.readAdditionalSaveData(nbt);
|
||||
+ this.lootableData.loadNbt(nbt); // Paper
|
||||
this.readChestVehicleSaveData(nbt);
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/vehicle/ChestBoat.java b/src/main/java/net/minecraft/world/entity/vehicle/ChestBoat.java
|
||||
index d88a6501917306eab57f46cb0d10dc03164a94da..e88c39d405fc7068db64ad34a03dec8d559e749e 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/vehicle/ChestBoat.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/vehicle/ChestBoat.java
|
||||
@@ -65,12 +65,14 @@ public class ChestBoat extends Boat implements HasCustomInventoryScreen, Contain
|
||||
@Override
|
||||
protected void addAdditionalSaveData(CompoundTag nbt) {
|
||||
super.addAdditionalSaveData(nbt);
|
||||
+ this.lootableData.saveNbt(nbt); // Paper
|
||||
this.addChestVehicleSaveData(nbt);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void readAdditionalSaveData(CompoundTag nbt) {
|
||||
super.readAdditionalSaveData(nbt);
|
||||
+ this.lootableData.loadNbt(nbt); // Paper
|
||||
this.readChestVehicleSaveData(nbt);
|
||||
}
|
||||
|
||||
@@ -245,6 +247,20 @@ public class ChestBoat extends Boat implements HasCustomInventoryScreen, Contain
|
||||
this.level().gameEvent(GameEvent.CONTAINER_CLOSE, this.position(), GameEvent.Context.of((Entity) player));
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ {
|
||||
+ this.lootableData = new com.destroystokyo.paper.loottable.PaperLootableInventoryData(new com.destroystokyo.paper.loottable.PaperContainerEntityLootableInventory(this));
|
||||
+ }
|
||||
+ @Override
|
||||
+ public Entity getEntity() {
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public com.destroystokyo.paper.loottable.PaperLootableInventoryData getLootableData() {
|
||||
+ return this.lootableData;
|
||||
+ }
|
||||
+ // Paper end
|
||||
// CraftBukkit start
|
||||
public List<HumanEntity> transaction = new java.util.ArrayList<HumanEntity>();
|
||||
private int maxStack = MAX_STACK;
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/vehicle/ContainerEntity.java b/src/main/java/net/minecraft/world/entity/vehicle/ContainerEntity.java
|
||||
index e0fbacd574e0c83c2e1d164ded8e9ccf4af30480..94252d346c4f8dfbd1501b142ea0b6985dc8e19a 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/vehicle/ContainerEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/vehicle/ContainerEntity.java
|
||||
@@ -59,7 +59,7 @@ public interface ContainerEntity extends Container, MenuProvider {
|
||||
if (this.getLootTableSeed() != 0L) {
|
||||
nbt.putLong("LootTableSeed", this.getLootTableSeed());
|
||||
}
|
||||
- } else {
|
||||
+ } else if (true) { // Paper - always load the items, table may still remain
|
||||
ContainerHelper.saveAllItems(nbt, this.getItemStacks());
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ public interface ContainerEntity extends Container, MenuProvider {
|
||||
if (nbt.contains("LootTable", 8)) {
|
||||
this.setLootTable(new ResourceLocation(nbt.getString("LootTable")));
|
||||
this.setLootTableSeed(nbt.getLong("LootTableSeed"));
|
||||
- } else {
|
||||
+ } else if (true) { // Paper - always load the items, table may still remain
|
||||
ContainerHelper.loadAllItems(nbt, this.getItemStacks());
|
||||
}
|
||||
|
||||
@@ -96,13 +96,13 @@ public interface ContainerEntity extends Container, MenuProvider {
|
||||
|
||||
default void unpackChestVehicleLootTable(@Nullable Player player) {
|
||||
MinecraftServer minecraftServer = this.level().getServer();
|
||||
- if (this.getLootTable() != null && minecraftServer != null) {
|
||||
+ if (this.getLootableData().shouldReplenish(player) && minecraftServer != null) { // Paper
|
||||
LootTable lootTable = minecraftServer.getLootData().getLootTable(this.getLootTable());
|
||||
if (player != null) {
|
||||
CriteriaTriggers.GENERATE_LOOT.trigger((ServerPlayer)player, this.getLootTable());
|
||||
}
|
||||
|
||||
- this.setLootTable((ResourceLocation)null);
|
||||
+ this.getLootableData().processRefill(player); // Paper
|
||||
LootParams.Builder builder = (new LootParams.Builder((ServerLevel)this.level())).withParameter(LootContextParams.ORIGIN, this.position());
|
||||
if (player != null) {
|
||||
builder.withLuck(player.getLuck()).withParameter(LootContextParams.THIS_ENTITY, player);
|
||||
@@ -176,4 +176,13 @@ public interface ContainerEntity extends Container, MenuProvider {
|
||||
default boolean isChestVehicleStillValid(Player player) {
|
||||
return !this.isRemoved() && this.position().closerThan(player.position(), 8.0D);
|
||||
}
|
||||
+ // Paper start
|
||||
+ default Entity getEntity() {
|
||||
+ throw new UnsupportedOperationException();
|
||||
+ }
|
||||
+
|
||||
+ default com.destroystokyo.paper.loottable.PaperLootableInventoryData getLootableData() {
|
||||
+ throw new UnsupportedOperationException();
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java
|
||||
index 111494c30a2b7d8464237a92cf5c98f7f4cca19d..e11618247ad889fa8fadbb2c7addd0de94caf249 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java
|
||||
@@ -29,6 +29,7 @@ public abstract class RandomizableContainerBlockEntity extends BaseContainerBloc
|
||||
@Nullable
|
||||
public ResourceLocation lootTable;
|
||||
public long lootTableSeed;
|
||||
+ public final com.destroystokyo.paper.loottable.PaperLootableInventoryData lootableData = new com.destroystokyo.paper.loottable.PaperLootableInventoryData(new com.destroystokyo.paper.loottable.PaperTileEntityLootableInventory(this)); // Paper
|
||||
|
||||
protected RandomizableContainerBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
|
||||
super(type, pos, state);
|
||||
@@ -43,16 +44,19 @@ public abstract class RandomizableContainerBlockEntity extends BaseContainerBloc
|
||||
}
|
||||
|
||||
protected boolean tryLoadLootTable(CompoundTag nbt) {
|
||||
+ this.lootableData.loadNbt(nbt); // Paper
|
||||
if (nbt.contains("LootTable", 8)) {
|
||||
this.lootTable = new ResourceLocation(nbt.getString("LootTable"));
|
||||
+ try { org.bukkit.craftbukkit.util.CraftNamespacedKey.fromMinecraft(this.lootTable); } catch (IllegalArgumentException ex) { this.lootTable = null; } // Paper - validate
|
||||
this.lootTableSeed = nbt.getLong("LootTableSeed");
|
||||
- return true;
|
||||
+ return false; // Paper - always load the items, table may still remain
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean trySaveLootTable(CompoundTag nbt) {
|
||||
+ this.lootableData.saveNbt(nbt); // Paper
|
||||
if (this.lootTable == null) {
|
||||
return false;
|
||||
} else {
|
||||
@@ -61,18 +65,18 @@ public abstract class RandomizableContainerBlockEntity extends BaseContainerBloc
|
||||
nbt.putLong("LootTableSeed", this.lootTableSeed);
|
||||
}
|
||||
|
||||
- return true;
|
||||
+ return false; // Paper - always save the items, table may still remain
|
||||
}
|
||||
}
|
||||
|
||||
public void unpackLootTable(@Nullable Player player) {
|
||||
- if (this.lootTable != null && this.level.getServer() != null) {
|
||||
+ if (this.lootableData.shouldReplenish(player) && this.level.getServer() != null) { // Paper
|
||||
LootTable lootTable = this.level.getServer().getLootData().getLootTable(this.lootTable);
|
||||
if (player instanceof ServerPlayer) {
|
||||
CriteriaTriggers.GENERATE_LOOT.trigger((ServerPlayer)player, this.lootTable);
|
||||
}
|
||||
|
||||
- this.lootTable = null;
|
||||
+ this.lootableData.processRefill(player); // Paper
|
||||
LootParams.Builder builder = (new LootParams.Builder((ServerLevel)this.level)).withParameter(LootContextParams.ORIGIN, Vec3.atCenterOf(this.worldPosition));
|
||||
if (player != null) {
|
||||
builder.withLuck(player.getLuck()).withParameter(LootContextParams.THIS_ENTITY, player);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBrushableBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBrushableBlock.java
|
||||
index d5bfa06a90158fb6d9cc54f7a9b44a277f2c480f..dbdf9b009a488767bb63b0867943fd932fac16e4 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBrushableBlock.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBrushableBlock.java
|
||||
@@ -60,7 +60,7 @@ public class CraftBrushableBlock extends CraftBlockEntityState<BrushableBlockEnt
|
||||
this.setLootTable(this.getLootTable(), seed);
|
||||
}
|
||||
|
||||
- private void setLootTable(LootTable table, long seed) {
|
||||
+ public void setLootTable(LootTable table, long seed) { // Paper - make public since it overrides a public method
|
||||
ResourceLocation key = (table == null) ? null : CraftNamespacedKey.toMinecraft(table.getKey());
|
||||
getSnapshot().setLootTable(key, seed);
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftChest.java b/src/main/java/org/bukkit/craftbukkit/block/CraftChest.java
|
||||
index b31fa63019822bc172d85427b3f3f2c154d7e179..82b3f3b3aced73ce136b6b94fe212972ac6090ef 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftChest.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftChest.java
|
||||
@@ -12,8 +12,9 @@ import org.bukkit.craftbukkit.CraftWorld;
|
||||
import org.bukkit.craftbukkit.inventory.CraftInventory;
|
||||
import org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
+import com.destroystokyo.paper.loottable.PaperLootableBlockInventory; // Paper
|
||||
|
||||
-public class CraftChest extends CraftLootable<ChestBlockEntity> implements Chest {
|
||||
+public class CraftChest extends CraftLootable<ChestBlockEntity> implements Chest, PaperLootableBlockInventory { // Paper
|
||||
|
||||
public CraftChest(World world, ChestBlockEntity tileEntity) {
|
||||
super(world, tileEntity);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftLootable.java b/src/main/java/org/bukkit/craftbukkit/block/CraftLootable.java
|
||||
index 982adacb361b0590799dc68f9b7c13c7195627fd..e49eece9bff3a53469673d03a7bbf8f9cf8776b8 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftLootable.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftLootable.java
|
||||
@@ -9,7 +9,7 @@ import org.bukkit.craftbukkit.util.CraftNamespacedKey;
|
||||
import org.bukkit.loot.LootTable;
|
||||
import org.bukkit.loot.Lootable;
|
||||
|
||||
-public abstract class CraftLootable<T extends RandomizableContainerBlockEntity> extends CraftContainer<T> implements Nameable, Lootable {
|
||||
+public abstract class CraftLootable<T extends RandomizableContainerBlockEntity> extends CraftContainer<T> implements Nameable, Lootable, com.destroystokyo.paper.loottable.PaperLootableBlockInventory { // Paper
|
||||
|
||||
public CraftLootable(World world, T tileEntity) {
|
||||
super(world, tileEntity);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftChestBoat.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftChestBoat.java
|
||||
index ae07db69b11b993b50782c94aa5c45b97d949612..06a96f027f90fd5bf05de72c8722ff5a81608b66 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftChestBoat.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftChestBoat.java
|
||||
@@ -11,8 +11,7 @@ import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.loot.LootTable;
|
||||
|
||||
-public class CraftChestBoat extends CraftBoat implements org.bukkit.entity.ChestBoat {
|
||||
-
|
||||
+public class CraftChestBoat extends CraftBoat implements org.bukkit.entity.ChestBoat, com.destroystokyo.paper.loottable.PaperLootableEntityInventory { // Paper
|
||||
private final Inventory inventory;
|
||||
|
||||
public CraftChestBoat(CraftServer server, ChestBoat entity) {
|
||||
@@ -66,7 +65,7 @@ public class CraftChestBoat extends CraftBoat implements org.bukkit.entity.Chest
|
||||
return this.getHandle().getLootTableSeed();
|
||||
}
|
||||
|
||||
- private void setLootTable(LootTable table, long seed) {
|
||||
+ public void setLootTable(LootTable table, long seed) { // Paper - change visibility since it overrides a public method
|
||||
ResourceLocation newKey = (table == null) ? null : CraftNamespacedKey.toMinecraft(table.getKey());
|
||||
this.getHandle().setLootTable(newKey);
|
||||
this.getHandle().setLootTableSeed(seed);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartChest.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartChest.java
|
||||
index eb21b8457774d5ac765fa9008157cb29d9b72509..abf58bef2042a9efba5a78fd7f97339deceaa780 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartChest.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartChest.java
|
||||
@@ -8,7 +8,7 @@ import org.bukkit.entity.minecart.StorageMinecart;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
-public class CraftMinecartChest extends CraftMinecartContainer implements StorageMinecart {
|
||||
+public class CraftMinecartChest extends CraftMinecartContainer implements StorageMinecart, com.destroystokyo.paper.loottable.PaperLootableEntityInventory { // Paper
|
||||
private final CraftInventory inventory;
|
||||
|
||||
public CraftMinecartChest(CraftServer server, MinecartChest entity) {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartHopper.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartHopper.java
|
||||
index 34b8f103625f087bb725bed595dd9c30f4a6f70c..ee9648739fb39c5842063d7442df6eb5c9336d7f 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartHopper.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartHopper.java
|
||||
@@ -7,7 +7,7 @@ import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.minecart.HopperMinecart;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
|
||||
-public final class CraftMinecartHopper extends CraftMinecartContainer implements HopperMinecart {
|
||||
+public final class CraftMinecartHopper extends CraftMinecartContainer implements HopperMinecart, com.destroystokyo.paper.loottable.PaperLootableEntityInventory { // Paper
|
||||
private final CraftInventory inventory;
|
||||
|
||||
public CraftMinecartHopper(CraftServer server, MinecartHopper entity) {
|
|
@ -0,0 +1,18 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sat, 7 May 2016 23:33:08 -0400
|
||||
Subject: [PATCH] Don't save empty scoreboard teams to scoreboard.dat
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/scores/ScoreboardSaveData.java b/src/main/java/net/minecraft/world/scores/ScoreboardSaveData.java
|
||||
index b837b6616a2384b253cca8ed62c9488b639f6298..2be7a697f08045b974579e6942b38571e744efac 100644
|
||||
--- a/src/main/java/net/minecraft/world/scores/ScoreboardSaveData.java
|
||||
+++ b/src/main/java/net/minecraft/world/scores/ScoreboardSaveData.java
|
||||
@@ -136,6 +136,7 @@ public class ScoreboardSaveData extends SavedData {
|
||||
ListTag listTag = new ListTag();
|
||||
|
||||
for(PlayerTeam playerTeam : this.scoreboard.getPlayerTeams()) {
|
||||
+ if (!io.papermc.paper.configuration.GlobalConfiguration.get().scoreboards.saveEmptyScoreboardTeams && playerTeam.getPlayers().isEmpty()) continue; // Paper
|
||||
CompoundTag compoundTag = new CompoundTag();
|
||||
compoundTag.putString("Name", playerTeam.getName());
|
||||
compoundTag.putString("DisplayName", Component.Serializer.toJson(playerTeam.getDisplayName()));
|
|
@ -0,0 +1,19 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <zach.brown@destroystokyo.com>
|
||||
Date: Thu, 12 May 2016 23:02:58 -0500
|
||||
Subject: [PATCH] System property for disabling watchdoge
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/spigotmc/WatchdogThread.java
|
||||
index 2693cc933d746e40d8a47d96c6cb6799f0a2472f..6e1fa4f0616ccfd258acd1b4f5b08fc0ad4c9529 100644
|
||||
--- a/src/main/java/org/spigotmc/WatchdogThread.java
|
||||
+++ b/src/main/java/org/spigotmc/WatchdogThread.java
|
||||
@@ -61,7 +61,7 @@ public class WatchdogThread extends Thread
|
||||
while ( !this.stopping )
|
||||
{
|
||||
//
|
||||
- if ( this.lastTick != 0 && this.timeoutTime > 0 && WatchdogThread.monotonicMillis() > this.lastTick + this.timeoutTime )
|
||||
+ if ( this.lastTick != 0 && this.timeoutTime > 0 && WatchdogThread.monotonicMillis() > this.lastTick + this.timeoutTime && !Boolean.getBoolean("disable.watchdog")) // Paper - Add property to disable
|
||||
{
|
||||
Logger log = Bukkit.getServer().getLogger();
|
||||
log.log( Level.SEVERE, "------------------------------" );
|
86
patches/server/0096-Async-GameProfileCache-saving.patch
Normal file
86
patches/server/0096-Async-GameProfileCache-saving.patch
Normal file
|
@ -0,0 +1,86 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 16 May 2016 20:47:41 -0400
|
||||
Subject: [PATCH] Async GameProfileCache saving
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index ac0a6cfb6fb7d9fa696b1e35ebdfb37935b74048..857cc4fcc586f7a8ea5baeeae69da62ebfdac77a 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -954,7 +954,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
} catch (java.lang.InterruptedException ignored) {} // Paper
|
||||
if (org.spigotmc.SpigotConfig.saveUserCacheOnStopOnly) {
|
||||
MinecraftServer.LOGGER.info("Saving usercache.json");
|
||||
- this.getProfileCache().save();
|
||||
+ this.getProfileCache().save(false); // Paper
|
||||
}
|
||||
// Spigot end
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
index 6f64d98021e842905cdd6410ec355a6f136ec18f..a9cf8960d487ee71385341285a4b1618007d06dc 100644
|
||||
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
@@ -242,7 +242,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
|
||||
}
|
||||
|
||||
if (this.convertOldUsers()) {
|
||||
- this.getProfileCache().save();
|
||||
+ this.getProfileCache().save(false); // Paper
|
||||
}
|
||||
|
||||
if (!OldUsersConverter.serverReadyAfterUserconversion(this)) {
|
||||
diff --git a/src/main/java/net/minecraft/server/players/GameProfileCache.java b/src/main/java/net/minecraft/server/players/GameProfileCache.java
|
||||
index d246563021c32127e570809f4d849b6a156f4dc6..225e15d686675e21969c4210fa38fef58d920355 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/GameProfileCache.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/GameProfileCache.java
|
||||
@@ -127,7 +127,7 @@ public class GameProfileCache {
|
||||
GameProfileCache.GameProfileInfo usercache_usercacheentry = new GameProfileCache.GameProfileInfo(profile, date);
|
||||
|
||||
this.safeAdd(usercache_usercacheentry);
|
||||
- if( !org.spigotmc.SpigotConfig.saveUserCacheOnStopOnly ) this.save(); // Spigot - skip saving if disabled
|
||||
+ if( !org.spigotmc.SpigotConfig.saveUserCacheOnStopOnly ) this.save(true); // Spigot - skip saving if disabled // Paper - async
|
||||
}
|
||||
|
||||
private long getNextOperation() {
|
||||
@@ -160,7 +160,7 @@ public class GameProfileCache {
|
||||
}
|
||||
|
||||
if (flag && !org.spigotmc.SpigotConfig.saveUserCacheOnStopOnly) { // Spigot - skip saving if disabled
|
||||
- this.save();
|
||||
+ this.save(true); // Paper
|
||||
}
|
||||
|
||||
return optional;
|
||||
@@ -274,7 +274,7 @@ public class GameProfileCache {
|
||||
return arraylist;
|
||||
}
|
||||
|
||||
- public void save() {
|
||||
+ public void save(boolean asyncSave) { // Paper
|
||||
JsonArray jsonarray = new JsonArray();
|
||||
DateFormat dateformat = GameProfileCache.createDateFormat();
|
||||
|
||||
@@ -282,6 +282,7 @@ public class GameProfileCache {
|
||||
jsonarray.add(GameProfileCache.writeGameProfile(usercache_usercacheentry, dateformat));
|
||||
});
|
||||
String s = this.gson.toJson(jsonarray);
|
||||
+ Runnable save = () -> { // Paper
|
||||
|
||||
try {
|
||||
BufferedWriter bufferedwriter = Files.newWriter(this.file, StandardCharsets.UTF_8);
|
||||
@@ -306,6 +307,14 @@ public class GameProfileCache {
|
||||
} catch (IOException ioexception) {
|
||||
;
|
||||
}
|
||||
+ // Paper start
|
||||
+ };
|
||||
+ if (asyncSave) {
|
||||
+ io.papermc.paper.util.MCUtil.scheduleAsyncTask(save);
|
||||
+ } else {
|
||||
+ save.run();
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
}
|
||||
|
63
patches/server/0097-Optional-TNT-doesn-t-move-in-water.patch
Normal file
63
patches/server/0097-Optional-TNT-doesn-t-move-in-water.patch
Normal file
|
@ -0,0 +1,63 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <zach.brown@destroystokyo.com>
|
||||
Date: Sun, 22 May 2016 20:20:55 -0500
|
||||
Subject: [PATCH] Optional TNT doesn't move in water
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java
|
||||
index 04ff01ba9f1f869f90d39645edb7aba42885725e..5ec480397fb043717c63961651f7c62440e57201 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerEntity.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerEntity.java
|
||||
@@ -70,7 +70,7 @@ public class ServerEntity {
|
||||
@Nullable
|
||||
private List<SynchedEntityData.DataValue<?>> trackedDataValues;
|
||||
// CraftBukkit start
|
||||
- private final Set<ServerPlayerConnection> trackedPlayers;
|
||||
+ final Set<ServerPlayerConnection> trackedPlayers; // Paper - private -> package
|
||||
|
||||
public ServerEntity(ServerLevel worldserver, Entity entity, int i, boolean flag, Consumer<Packet<?>> consumer, Set<ServerPlayerConnection> trackedPlayers) {
|
||||
this.trackedPlayers = trackedPlayers;
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java b/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java
|
||||
index 223cd451a952addec522711b6d3a0d6c0ab0f797..31473200264e6365fb149b11d0965f509f78218c 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java
|
||||
@@ -95,6 +95,27 @@ public class PrimedTnt extends Entity implements TraceableEntity {
|
||||
}
|
||||
}
|
||||
|
||||
+ // Paper start - Optional prevent TNT from moving in water
|
||||
+ if (!this.isRemoved() && this.wasTouchingWater && this.level.paperConfig().fixes.preventTntFromMovingInWater) {
|
||||
+ /*
|
||||
+ * Author: Jedediah Smith <jedediah@silencegreys.com>
|
||||
+ */
|
||||
+ // Send position and velocity updates to nearby players on every tick while the TNT is in water.
|
||||
+ // This does pretty well at keeping their clients in sync with the server.
|
||||
+ net.minecraft.server.level.ChunkMap.TrackedEntity ete = ((net.minecraft.server.level.ServerLevel)this.level).getChunkSource().chunkMap.entityMap.get(this.getId());
|
||||
+ if (ete != null) {
|
||||
+ net.minecraft.network.protocol.game.ClientboundSetEntityMotionPacket velocityPacket = new net.minecraft.network.protocol.game.ClientboundSetEntityMotionPacket(this);
|
||||
+ net.minecraft.network.protocol.game.ClientboundTeleportEntityPacket positionPacket = new net.minecraft.network.protocol.game.ClientboundTeleportEntityPacket(this);
|
||||
+
|
||||
+ ete.seenBy.stream()
|
||||
+ .filter(viewer -> (viewer.getPlayer().getX() - this.getX()) * (viewer.getPlayer().getY() - this.getY()) * (viewer.getPlayer().getZ() - this.getZ()) < 16 * 16)
|
||||
+ .forEach(viewer -> {
|
||||
+ viewer.send(velocityPacket);
|
||||
+ viewer.send(positionPacket);
|
||||
+ });
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
private void explode() {
|
||||
@@ -146,4 +167,11 @@ public class PrimedTnt extends Entity implements TraceableEntity {
|
||||
public int getFuse() {
|
||||
return (Integer) this.entityData.get(PrimedTnt.DATA_FUSE_ID);
|
||||
}
|
||||
+
|
||||
+ // Paper start - Optional prevent TNT from moving in water
|
||||
+ @Override
|
||||
+ public boolean isPushedByFluid() {
|
||||
+ return !level.paperConfig().fixes.preventTntFromMovingInWater && super.isPushedByFluid();
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Panzer <postremus1996@googlemail.com>
|
||||
Date: Mon, 23 May 2016 12:12:37 +0200
|
||||
Subject: [PATCH] Faster redstone torch rapid clock removal
|
||||
|
||||
Only resize the the redstone torch list once, since resizing arrays / lists is costly
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
|
||||
index dc84da6d6036802792cf9a31bb219cc24bb9e57b..9ac9a40e442a30b785ba79e015389f3308ae37c3 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/Level.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
||||
@@ -173,6 +173,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
private org.spigotmc.TickLimiter tileLimiter;
|
||||
private int tileTickPosition;
|
||||
public final Map<Explosion.CacheKey, Float> explosionDensityCache = new HashMap<>(); // Paper - Optimize explosions
|
||||
+ public java.util.ArrayDeque<net.minecraft.world.level.block.RedstoneTorchBlock.Toggle> redstoneUpdateInfos; // Paper - Move from Map in BlockRedstoneTorch to here
|
||||
|
||||
public CraftWorld getWorld() {
|
||||
return this.world;
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/RedstoneTorchBlock.java b/src/main/java/net/minecraft/world/level/block/RedstoneTorchBlock.java
|
||||
index 9b6f8508d16bcecd9dc148f75598655e3585f175..da07fce0cf7c9fbdb57d2c59e431b59bf583bf50 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/RedstoneTorchBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/RedstoneTorchBlock.java
|
||||
@@ -21,7 +21,7 @@ import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit
|
||||
public class RedstoneTorchBlock extends TorchBlock {
|
||||
|
||||
public static final BooleanProperty LIT = BlockStateProperties.LIT;
|
||||
- private static final Map<BlockGetter, List<RedstoneTorchBlock.Toggle>> RECENT_TOGGLES = new WeakHashMap();
|
||||
+ // Paper - Move the mapped list to World
|
||||
public static final int RECENT_TOGGLE_TIMER = 60;
|
||||
public static final int MAX_RECENT_TOGGLES = 8;
|
||||
public static final int RESTART_DELAY = 160;
|
||||
@@ -72,11 +72,15 @@ public class RedstoneTorchBlock extends TorchBlock {
|
||||
@Override
|
||||
public void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) {
|
||||
boolean flag = this.hasNeighborSignal(world, pos, state);
|
||||
- List list = (List) RedstoneTorchBlock.RECENT_TOGGLES.get(world);
|
||||
-
|
||||
- while (list != null && !list.isEmpty() && world.getGameTime() - ((RedstoneTorchBlock.Toggle) list.get(0)).when > 60L) {
|
||||
- list.remove(0);
|
||||
+ // Paper start
|
||||
+ java.util.ArrayDeque<RedstoneTorchBlock.Toggle> redstoneUpdateInfos = world.redstoneUpdateInfos;
|
||||
+ if (redstoneUpdateInfos != null) {
|
||||
+ RedstoneTorchBlock.Toggle curr;
|
||||
+ while ((curr = redstoneUpdateInfos.peek()) != null && world.getGameTime() - curr.when > 60L) {
|
||||
+ redstoneUpdateInfos.poll();
|
||||
+ }
|
||||
}
|
||||
+ // Paper end
|
||||
|
||||
// CraftBukkit start
|
||||
org.bukkit.plugin.PluginManager manager = world.getCraftServer().getPluginManager();
|
||||
@@ -152,9 +156,12 @@ public class RedstoneTorchBlock extends TorchBlock {
|
||||
}
|
||||
|
||||
private static boolean isToggledTooFrequently(Level world, BlockPos pos, boolean addNew) {
|
||||
- List<RedstoneTorchBlock.Toggle> list = (List) RedstoneTorchBlock.RECENT_TOGGLES.computeIfAbsent(world, (iblockaccess) -> {
|
||||
- return Lists.newArrayList();
|
||||
- });
|
||||
+ // Paper start
|
||||
+ java.util.ArrayDeque<RedstoneTorchBlock.Toggle> list = world.redstoneUpdateInfos;
|
||||
+ if (list == null) {
|
||||
+ list = world.redstoneUpdateInfos = new java.util.ArrayDeque<>();
|
||||
+ }
|
||||
+
|
||||
|
||||
if (addNew) {
|
||||
list.add(new RedstoneTorchBlock.Toggle(pos.immutable(), world.getGameTime()));
|
||||
@@ -162,9 +169,9 @@ public class RedstoneTorchBlock extends TorchBlock {
|
||||
|
||||
int i = 0;
|
||||
|
||||
- for (int j = 0; j < list.size(); ++j) {
|
||||
- RedstoneTorchBlock.Toggle blockredstonetorch_redstoneupdateinfo = (RedstoneTorchBlock.Toggle) list.get(j);
|
||||
-
|
||||
+ for (java.util.Iterator<RedstoneTorchBlock.Toggle> iterator = list.iterator(); iterator.hasNext();) {
|
||||
+ RedstoneTorchBlock.Toggle blockredstonetorch_redstoneupdateinfo = iterator.next();
|
||||
+ // Paper end
|
||||
if (blockredstonetorch_redstoneupdateinfo.pos.equals(pos)) {
|
||||
++i;
|
||||
if (i >= 8) {
|
25
patches/server/0099-Add-server-name-parameter.patch
Normal file
25
patches/server/0099-Add-server-name-parameter.patch
Normal file
|
@ -0,0 +1,25 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Panzer <postremus1996@googlemail.com>
|
||||
Date: Sat, 28 May 2016 16:54:03 +0200
|
||||
Subject: [PATCH] Add server-name parameter
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java
|
||||
index a20eaa9b1d030ccd7e1fc49df47acee46f4e7e20..b96652b7bcad07c39a81858c1a2c285efbf67905 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/Main.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/Main.java
|
||||
@@ -166,6 +166,14 @@ public class Main {
|
||||
.defaultsTo(new File[] {})
|
||||
.describedAs("Jar file");
|
||||
// Paper end
|
||||
+
|
||||
+ // Paper start
|
||||
+ acceptsAll(asList("server-name"), "Name of the server")
|
||||
+ .withRequiredArg()
|
||||
+ .ofType(String.class)
|
||||
+ .defaultsTo("Unknown Server")
|
||||
+ .describedAs("Name");
|
||||
+ // Paper end
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 31 May 2016 22:53:50 -0400
|
||||
Subject: [PATCH] Only send global sounds to same world if limiting radius
|
||||
|
||||
Co-authored-by: Evan McCarthy <evanmccarthy@outlook.com>
|
||||
Co-authored-by: lexikiq <noellekiq@gmail.com>
|
||||
|
||||
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 29798faa9cc9aead40e3329307dc63cb7bf838b6..27f99f9ce39aac0bae5e9a7b34fd63833aa4ad26 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
|
||||
@@ -689,7 +689,7 @@ public class EnderDragon extends Mob implements Enemy {
|
||||
// CraftBukkit start - Use relative location for far away sounds
|
||||
// this.level().globalLevelEvent(1028, this.blockPosition(), 0);
|
||||
int viewDistance = ((ServerLevel) this.level()).getCraftServer().getViewDistance() * 16;
|
||||
- for (net.minecraft.server.level.ServerPlayer player : this.level().getServer().getPlayerList().players) {
|
||||
+ for (net.minecraft.server.level.ServerPlayer player : this.level().spigotConfig.dragonDeathSoundRadius > 0 ? ((ServerLevel) this.level()).players() : this.level().getServer().getPlayerList().players) { // Paper
|
||||
double deltaX = this.getX() - player.getX();
|
||||
double deltaZ = this.getZ() - player.getZ();
|
||||
double distanceSquared = deltaX * deltaX + deltaZ * deltaZ;
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java b/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java
|
||||
index e23347faf763f22301136a013034367ac847c35b..4576c96f85fe5a614a78e53926dfbc2705618423 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java
|
||||
@@ -271,7 +271,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob
|
||||
// CraftBukkit start - Use relative location for far away sounds
|
||||
// this.level().globalLevelEvent(1023, new BlockPosition(this), 0);
|
||||
int viewDistance = ((ServerLevel) this.level()).getCraftServer().getViewDistance() * 16;
|
||||
- for (ServerPlayer player : (List<ServerPlayer>) MinecraftServer.getServer().getPlayerList().players) {
|
||||
+ for (ServerPlayer player : this.level().spigotConfig.witherSpawnSoundRadius > 0 ? ((ServerLevel) this.level()).players() : this.level().getServer().getPlayerList().players) { // Paper
|
||||
double deltaX = this.getX() - player.getX();
|
||||
double deltaZ = this.getZ() - player.getZ();
|
||||
double distanceSquared = deltaX * deltaX + deltaZ * deltaZ;
|
||||
diff --git a/src/main/java/net/minecraft/world/item/EnderEyeItem.java b/src/main/java/net/minecraft/world/item/EnderEyeItem.java
|
||||
index 5bc68514a1e8a212e2681f06b918548c0ec565b6..1fddc9025a9e5079f05dd6c86f6ca43c5d51d9c3 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/EnderEyeItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/EnderEyeItem.java
|
||||
@@ -64,7 +64,7 @@ public class EnderEyeItem extends Item {
|
||||
// world.b(1038, blockposition1.c(1, 0, 1), 0);
|
||||
int viewDistance = world.getCraftServer().getViewDistance() * 16;
|
||||
BlockPos soundPos = blockposition1.offset(1, 0, 1);
|
||||
- for (ServerPlayer player : world.getServer().getPlayerList().players) {
|
||||
+ for (ServerPlayer player : world.spigotConfig.endPortalSoundRadius > 0 ? ((ServerLevel) world).players() : world.getServer().getPlayerList().players) { // Paper
|
||||
double deltaX = soundPos.getX() - player.getX();
|
||||
double deltaZ = soundPos.getZ() - player.getZ();
|
||||
double distanceSquared = deltaX * deltaX + deltaZ * deltaZ;
|
|
@ -0,0 +1,45 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 16 May 2016 23:19:16 -0400
|
||||
Subject: [PATCH] Avoid blocking on Network Manager creation
|
||||
|
||||
Per Paper issue 294
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerConnectionListener.java b/src/main/java/net/minecraft/server/network/ServerConnectionListener.java
|
||||
index 6c4e41d1d9e16492b1e47b5047810b8ffca992e5..776528e50a5abc0e02d9de99231fb47352aa4f43 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerConnectionListener.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerConnectionListener.java
|
||||
@@ -60,6 +60,15 @@ public class ServerConnectionListener {
|
||||
public volatile boolean running;
|
||||
private final List<ChannelFuture> channels = Collections.synchronizedList(Lists.newArrayList());
|
||||
final List<Connection> connections = Collections.synchronizedList(Lists.newArrayList());
|
||||
+ // Paper start - prevent blocking on adding a new network manager while the server is ticking
|
||||
+ private final java.util.Queue<Connection> pending = new java.util.concurrent.ConcurrentLinkedQueue<>();
|
||||
+ private final void addPending() {
|
||||
+ Connection manager = null;
|
||||
+ while ((manager = pending.poll()) != null) {
|
||||
+ connections.add(manager);
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
public ServerConnectionListener(MinecraftServer server) {
|
||||
this.server = server;
|
||||
@@ -97,7 +106,8 @@ public class ServerConnectionListener {
|
||||
int j = ServerConnectionListener.this.server.getRateLimitPacketsPerSecond();
|
||||
Connection object = j > 0 ? new RateKickingConnection(j) : new Connection(PacketFlow.SERVERBOUND); // CraftBukkit - decompile error
|
||||
|
||||
- ServerConnectionListener.this.connections.add(object);
|
||||
+ //ServerConnectionListener.this.connections.add(object);
|
||||
+ pending.add(object); // Paper
|
||||
channelpipeline.addLast("packet_handler", (ChannelHandler) object);
|
||||
((Connection) object).setListener(new ServerHandshakePacketListenerImpl(ServerConnectionListener.this.server, (Connection) object));
|
||||
}
|
||||
@@ -158,6 +168,7 @@ public class ServerConnectionListener {
|
||||
|
||||
synchronized (this.connections) {
|
||||
// Spigot Start
|
||||
+ this.addPending(); // Paper
|
||||
// This prevents players from 'gaming' the server, and strategically relogging to increase their position in the tick order
|
||||
if ( org.spigotmc.SpigotConfig.playerShuffle > 0 && MinecraftServer.currentTick % org.spigotmc.SpigotConfig.playerShuffle == 0 )
|
||||
{
|
|
@ -0,0 +1,18 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <zach.brown@destroystokyo.com>
|
||||
Date: Sat, 16 Jul 2016 19:11:17 -0500
|
||||
Subject: [PATCH] Don't lookup game profiles that have no UUID and no name
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/players/GameProfileCache.java b/src/main/java/net/minecraft/server/players/GameProfileCache.java
|
||||
index 225e15d686675e21969c4210fa38fef58d920355..5288aec173549a982e42aeeccf7f5f394080955d 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/GameProfileCache.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/GameProfileCache.java
|
||||
@@ -98,6 +98,7 @@ public class GameProfileCache {
|
||||
}
|
||||
};
|
||||
|
||||
+ if (!org.apache.commons.lang3.StringUtils.isBlank(name)) // Paper - Don't lookup a profile with a blank name)
|
||||
repository.findProfilesByNames(new String[]{name}, Agent.MINECRAFT, profilelookupcallback);
|
||||
GameProfile gameprofile = (GameProfile) atomicreference.get();
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Gabriele C <sgdc3.mail@gmail.com>
|
||||
Date: Fri, 5 Aug 2016 01:03:08 +0200
|
||||
Subject: [PATCH] Add setting for proxy online mode status
|
||||
|
||||
TODO: Add isProxyOnlineMode check to Metrics
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/players/GameProfileCache.java b/src/main/java/net/minecraft/server/players/GameProfileCache.java
|
||||
index 5288aec173549a982e42aeeccf7f5f394080955d..58e923f4ef1980bc7fff1e3b3fcdaad8c4eded53 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/GameProfileCache.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/GameProfileCache.java
|
||||
@@ -98,7 +98,8 @@ public class GameProfileCache {
|
||||
}
|
||||
};
|
||||
|
||||
- if (!org.apache.commons.lang3.StringUtils.isBlank(name)) // Paper - Don't lookup a profile with a blank name)
|
||||
+ if (!org.apache.commons.lang3.StringUtils.isBlank(name) // Paper - Don't lookup a profile with a blank name
|
||||
+ && io.papermc.paper.configuration.GlobalConfiguration.get().proxies.isProxyOnlineMode()) // Paper - only run in online mode - 100 COL
|
||||
repository.findProfilesByNames(new String[]{name}, Agent.MINECRAFT, profilelookupcallback);
|
||||
GameProfile gameprofile = (GameProfile) atomicreference.get();
|
||||
|
||||
@@ -116,7 +117,7 @@ public class GameProfileCache {
|
||||
}
|
||||
|
||||
private static boolean usesAuthentication() {
|
||||
- return GameProfileCache.usesAuthentication;
|
||||
+ return io.papermc.paper.configuration.GlobalConfiguration.get().proxies.isProxyOnlineMode(); // Paper
|
||||
}
|
||||
|
||||
public void add(GameProfile profile) {
|
||||
diff --git a/src/main/java/net/minecraft/server/players/OldUsersConverter.java b/src/main/java/net/minecraft/server/players/OldUsersConverter.java
|
||||
index da98f074ccd5a40c635824112c97fd174c393cb1..6599f874d9f97e9ef4862039ecad7277bbc5fd91 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/OldUsersConverter.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/OldUsersConverter.java
|
||||
@@ -66,7 +66,8 @@ public class OldUsersConverter {
|
||||
return new String[i];
|
||||
});
|
||||
|
||||
- if (server.usesAuthentication() || org.spigotmc.SpigotConfig.bungee) { // Spigot: bungee = online mode, for now.
|
||||
+ if (server.usesAuthentication()
|
||||
+ || (io.papermc.paper.configuration.GlobalConfiguration.get().proxies.isProxyOnlineMode())) { // Spigot: bungee = online mode, for now. // Paper - Handle via setting
|
||||
server.getProfileRepository().findProfilesByNames(astring, Agent.MINECRAFT, callback);
|
||||
} else {
|
||||
String[] astring1 = astring;
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index bc0bff6f06a74e2bb3f00fac2fdcc543bc970c2f..0b9eccd6bfb90fe282a9ce48dbf6379c717ec83a 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -1735,7 +1735,7 @@ public final class CraftServer implements Server {
|
||||
// Spigot Start
|
||||
GameProfile profile = null;
|
||||
// Only fetch an online UUID in online mode
|
||||
- if ( this.getOnlineMode() || org.spigotmc.SpigotConfig.bungee )
|
||||
+ if ( this.getOnlineMode() || io.papermc.paper.configuration.GlobalConfiguration.get().proxies.isProxyOnlineMode() ) // Paper - Handle via setting
|
||||
{
|
||||
profile = this.console.getProfileCache().get(name).orElse(null);
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Alfie Cleveland <alfeh@me.com>
|
||||
Date: Fri, 19 Aug 2016 01:52:56 +0100
|
||||
Subject: [PATCH] Optimise BlockState's hashCode/equals
|
||||
|
||||
These are singleton "single instance" objects. We can rely on
|
||||
object identity checks safely.
|
||||
|
||||
Use a simpler optimized hashcode
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/state/properties/BooleanProperty.java b/src/main/java/net/minecraft/world/level/block/state/properties/BooleanProperty.java
|
||||
index 6cdb0716f2a4b29f7a5ecd109bf3c4700ebd22ad..ff1a0d125edd2ea10c870cbb62ae9aa23644b6dc 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/state/properties/BooleanProperty.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/state/properties/BooleanProperty.java
|
||||
@@ -30,8 +30,7 @@ public class BooleanProperty extends Property<Boolean> {
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
- @Override
|
||||
- public boolean equals(Object object) {
|
||||
+ public boolean equals_unused(Object object) { // Paper
|
||||
if (this == object) {
|
||||
return true;
|
||||
} else if (object instanceof BooleanProperty && super.equals(object)) {
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/state/properties/EnumProperty.java b/src/main/java/net/minecraft/world/level/block/state/properties/EnumProperty.java
|
||||
index 4d6e7b5889ecb81195c7152225ae8e3343d3408c..0bca0f971dac994bd8b6ecd87e8b33e26c0f18f9 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/state/properties/EnumProperty.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/state/properties/EnumProperty.java
|
||||
@@ -45,8 +45,7 @@ public class EnumProperty<T extends Enum<T> & StringRepresentable> extends Prope
|
||||
return value.getSerializedName();
|
||||
}
|
||||
|
||||
- @Override
|
||||
- public boolean equals(Object object) {
|
||||
+ public boolean equals_unused(Object object) { // Paper
|
||||
if (this == object) {
|
||||
return true;
|
||||
} else if (object instanceof EnumProperty && super.equals(object)) {
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/state/properties/IntegerProperty.java b/src/main/java/net/minecraft/world/level/block/state/properties/IntegerProperty.java
|
||||
index 59b5b22a567e4e2be499a2a35aedb10218a7432a..bdbe0362e49e73c05237f9f3143230e0b03e494e 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/state/properties/IntegerProperty.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/state/properties/IntegerProperty.java
|
||||
@@ -35,8 +35,7 @@ public class IntegerProperty extends Property<Integer> {
|
||||
return this.values;
|
||||
}
|
||||
|
||||
- @Override
|
||||
- public boolean equals(Object object) {
|
||||
+ public boolean equals_unused(Object object) { // Paper
|
||||
if (this == object) {
|
||||
return true;
|
||||
} else if (object instanceof IntegerProperty && super.equals(object)) {
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/state/properties/Property.java b/src/main/java/net/minecraft/world/level/block/state/properties/Property.java
|
||||
index d1f2e29623b15fdb99ba082fd757a54fd4713761..66b8e23d799adaf872233ea44c54330d75135544 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/state/properties/Property.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/state/properties/Property.java
|
||||
@@ -70,14 +70,7 @@ public abstract class Property<T extends Comparable<T>> {
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
- if (this == object) {
|
||||
- return true;
|
||||
- } else if (!(object instanceof Property)) {
|
||||
- return false;
|
||||
- } else {
|
||||
- Property<?> property = (Property)object;
|
||||
- return this.clazz.equals(property.clazz) && this.name.equals(property.name);
|
||||
- }
|
||||
+ return this == object; // Paper
|
||||
}
|
||||
|
||||
@Override
|
|
@ -0,0 +1,27 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <zach.brown@destroystokyo.com>
|
||||
Date: Sun, 11 Sep 2016 14:30:57 -0500
|
||||
Subject: [PATCH] Configurable packet in spam threshold
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index c65282a85e2822b86f56c528ab838e628ea27411..96e38a914db34ed165bd5071585bc7e5ec7fb41d 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -1588,13 +1588,14 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
|
||||
// Spigot start - limit place/interactions
|
||||
private int limitedPackets;
|
||||
private long lastLimitedPacket = -1;
|
||||
+ private static final int THRESHOLD = io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.incomingPacketThreshold; // Paper - Configurable threshold
|
||||
|
||||
private boolean checkLimit(long timestamp) {
|
||||
- if (this.lastLimitedPacket != -1 && timestamp - this.lastLimitedPacket < 30 && this.limitedPackets++ >= 4) {
|
||||
+ if (this.lastLimitedPacket != -1 && timestamp - this.lastLimitedPacket < THRESHOLD && this.limitedPackets++ >= 8) { // Paper - Use threshold, raise packet limit to 8
|
||||
return false;
|
||||
}
|
||||
|
||||
- if (this.lastLimitedPacket == -1 || timestamp - this.lastLimitedPacket >= 30) {
|
||||
+ if (this.lastLimitedPacket == -1 || timestamp - this.lastLimitedPacket >= THRESHOLD) { // Paper
|
||||
this.lastLimitedPacket = timestamp;
|
||||
this.limitedPackets = 0;
|
||||
return true;
|
28
patches/server/0106-Configurable-flying-kick-messages.patch
Normal file
28
patches/server/0106-Configurable-flying-kick-messages.patch
Normal file
|
@ -0,0 +1,28 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: kashike <kashike@vq.lc>
|
||||
Date: Tue, 20 Sep 2016 00:58:01 +0000
|
||||
Subject: [PATCH] Configurable flying kick messages
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 96e38a914db34ed165bd5071585bc7e5ec7fb41d..590880b71c3c1930eb84538af5f6c3b690bb690f 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -355,7 +355,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
|
||||
if (this.clientIsFloating && !this.player.isSleeping() && !this.player.isPassenger() && !this.player.isDeadOrDying()) {
|
||||
if (++this.aboveGroundTickCount > 80) {
|
||||
ServerGamePacketListenerImpl.LOGGER.warn("{} was kicked for floating too long!", this.player.getName().getString());
|
||||
- this.disconnect(Component.translatable("multiplayer.disconnect.flying"));
|
||||
+ this.disconnect(io.papermc.paper.configuration.GlobalConfiguration.get().messages.kick.flyingPlayer); // Paper - use configurable kick message
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
@@ -374,7 +374,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
|
||||
if (this.clientVehicleIsFloating && this.player.getRootVehicle().getControllingPassenger() == this.player) {
|
||||
if (++this.aboveGroundVehicleTickCount > 80) {
|
||||
ServerGamePacketListenerImpl.LOGGER.warn("{} was kicked for floating a vehicle too long!", this.player.getName().getString());
|
||||
- this.disconnect(Component.translatable("multiplayer.disconnect.flying"));
|
||||
+ this.disconnect(io.papermc.paper.configuration.GlobalConfiguration.get().messages.kick.flyingVehicle); // Paper - use configurable kick message
|
||||
return;
|
||||
}
|
||||
} else {
|
48
patches/server/0107-Add-EntityZapEvent.patch
Normal file
48
patches/server/0107-Add-EntityZapEvent.patch
Normal file
|
@ -0,0 +1,48 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: AlphaBlend <whizkid3000@hotmail.com>
|
||||
Date: Sun, 16 Oct 2016 23:19:30 -0700
|
||||
Subject: [PATCH] Add EntityZapEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/npc/Villager.java b/src/main/java/net/minecraft/world/entity/npc/Villager.java
|
||||
index f9704b20e71564ac721a24655b2792c689edf6ba..e04f3f1159c5d5fa2e3956a36e95f8afb5a1d4aa 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/npc/Villager.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java
|
||||
@@ -850,10 +850,17 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
|
||||
@Override
|
||||
public void thunderHit(ServerLevel world, LightningBolt lightning) {
|
||||
if (world.getDifficulty() != Difficulty.PEACEFUL) {
|
||||
- Villager.LOGGER.info("Villager {} was struck by lightning {}.", this, lightning);
|
||||
+ // Paper - move log down, event can cancel
|
||||
Witch entitywitch = (Witch) EntityType.WITCH.create(world);
|
||||
|
||||
if (entitywitch != null) {
|
||||
+ // Paper start
|
||||
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityZapEvent(this, lightning, entitywitch).isCancelled()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ if (org.spigotmc.SpigotConfig.logVillagerDeaths) Villager.LOGGER.info("Villager {} was struck by lightning {}.", this, lightning); // Move down
|
||||
+ // Paper end
|
||||
+
|
||||
entitywitch.moveTo(this.getX(), this.getY(), this.getZ(), this.getYRot(), this.getXRot());
|
||||
entitywitch.finalizeSpawn(world, world.getCurrentDifficultyAt(entitywitch.blockPosition()), MobSpawnType.CONVERSION, (SpawnGroupData) null, (CompoundTag) null);
|
||||
entitywitch.setNoAi(this.isNoAi());
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
index 1b9a08098199f305606289724ee047e8075ffcea..8d9b25f3c8c840baf9c203f80d46201434920aa5 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
@@ -1189,6 +1189,14 @@ public class CraftEventFactory {
|
||||
return event;
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ public static com.destroystokyo.paper.event.entity.EntityZapEvent callEntityZapEvent (Entity entity, Entity lightning, Entity changedEntity) {
|
||||
+ com.destroystokyo.paper.event.entity.EntityZapEvent event = new com.destroystokyo.paper.event.entity.EntityZapEvent(entity.getBukkitEntity(), (LightningStrike) lightning.getBukkitEntity(), changedEntity.getBukkitEntity());
|
||||
+ entity.getBukkitEntity().getServer().getPluginManager().callEvent(event);
|
||||
+ return event;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
public static HorseJumpEvent callHorseJumpEvent(Entity horse, float power) {
|
||||
HorseJumpEvent event = new HorseJumpEvent((AbstractHorse) horse.getBukkitEntity(), power);
|
||||
horse.getBukkitEntity().getServer().getPluginManager().callEvent(event);
|
|
@ -0,0 +1,19 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <zach.brown@destroystokyo.com>
|
||||
Date: Sat, 12 Nov 2016 23:25:22 -0600
|
||||
Subject: [PATCH] Filter bad tile entity nbt data from falling blocks
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java b/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java
|
||||
index 4488d112b280a2020712708940adf65b69ca0a3c..d859e01a6cc4225c514c4023b8adc066e73d3bb7 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java
|
||||
@@ -332,7 +332,7 @@ public class FallingBlockEntity extends Entity {
|
||||
this.dropItem = nbt.getBoolean("DropItem");
|
||||
}
|
||||
|
||||
- if (nbt.contains("TileEntityData", 10)) {
|
||||
+ if (nbt.contains("TileEntityData", 10) && !(this.level.paperConfig().entities.spawning.filterBadTileEntityNbtFromFallingBlocks && this.blockState.getBlock() instanceof net.minecraft.world.level.block.GameMasterBlock)) {
|
||||
this.blockData = nbt.getCompound("TileEntityData");
|
||||
}
|
||||
|
63
patches/server/0109-Cache-user-authenticator-threads.patch
Normal file
63
patches/server/0109-Cache-user-authenticator-threads.patch
Normal file
|
@ -0,0 +1,63 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Alfie Cleveland <alfeh@me.com>
|
||||
Date: Fri, 25 Nov 2016 13:22:40 +0000
|
||||
Subject: [PATCH] Cache user authenticator threads
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
index 7983033160b77e28eb8135f8709dacd6b806ebe3..9fd44505c33b7ad578d6a471aca8e1c2df5c7dcd 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
@@ -112,6 +112,8 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener,
|
||||
|
||||
}
|
||||
|
||||
+ private static final java.util.concurrent.ExecutorService authenticatorPool = java.util.concurrent.Executors.newCachedThreadPool(new com.google.common.util.concurrent.ThreadFactoryBuilder().setNameFormat("User Authenticator #%d").setUncaughtExceptionHandler(new DefaultUncaughtExceptionHandler(LOGGER)).build()); // Paper - Cache authenticator threads
|
||||
+
|
||||
// Spigot start
|
||||
public void initUUID()
|
||||
{
|
||||
@@ -208,8 +210,8 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener,
|
||||
this.connection.send(new ClientboundHelloPacket("", this.server.getKeyPair().getPublic().getEncoded(), this.challenge));
|
||||
} else {
|
||||
// Spigot start
|
||||
- new Thread("User Authenticator #" + ServerLoginPacketListenerImpl.UNIQUE_THREAD_ID.incrementAndGet()) {
|
||||
-
|
||||
+ // Paper start - Cache authenticator threads
|
||||
+ authenticatorPool.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
@@ -220,7 +222,8 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener,
|
||||
server.server.getLogger().log(java.util.logging.Level.WARNING, "Exception verifying " + ServerLoginPacketListenerImpl.this.gameProfile.getName(), ex);
|
||||
}
|
||||
}
|
||||
- }.start();
|
||||
+ });
|
||||
+ // Paper end
|
||||
// Spigot end
|
||||
}
|
||||
|
||||
@@ -257,7 +260,8 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener,
|
||||
throw new IllegalStateException("Protocol error", cryptographyexception);
|
||||
}
|
||||
|
||||
- Thread thread = new Thread("User Authenticator #" + ServerLoginPacketListenerImpl.UNIQUE_THREAD_ID.incrementAndGet()) {
|
||||
+ // Paper start - Cache authenticator threads
|
||||
+ authenticatorPool.execute(new Runnable() {
|
||||
public void run() {
|
||||
GameProfile gameprofile = ServerLoginPacketListenerImpl.this.gameProfile;
|
||||
|
||||
@@ -302,10 +306,8 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener,
|
||||
|
||||
return ServerLoginPacketListenerImpl.this.server.getPreventProxyConnections() && socketaddress instanceof InetSocketAddress ? ((InetSocketAddress) socketaddress).getAddress() : null;
|
||||
}
|
||||
- };
|
||||
-
|
||||
- thread.setUncaughtExceptionHandler(new DefaultUncaughtExceptionHandler(ServerLoginPacketListenerImpl.LOGGER));
|
||||
- thread.start();
|
||||
+ });
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
// Spigot start
|
36
patches/server/0110-Allow-Reloading-of-Command-Aliases.patch
Normal file
36
patches/server/0110-Allow-Reloading-of-Command-Aliases.patch
Normal file
|
@ -0,0 +1,36 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: willies952002 <admin@domnian.com>
|
||||
Date: Mon, 28 Nov 2016 10:21:52 -0500
|
||||
Subject: [PATCH] Allow Reloading of Command Aliases
|
||||
|
||||
Reload the aliases stored in commands.yml
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index 0b9eccd6bfb90fe282a9ce48dbf6379c717ec83a..3d6c25424c859f63c8f4661b39c82c269c3837fb 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -2629,5 +2629,24 @@ public final class CraftServer implements Server {
|
||||
DefaultPermissions.registerCorePermissions();
|
||||
CraftDefaultPermissions.registerCorePermissions();
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean reloadCommandAliases() {
|
||||
+ Set<String> removals = getCommandAliases().keySet().stream()
|
||||
+ .map(key -> key.toLowerCase(java.util.Locale.ENGLISH))
|
||||
+ .collect(java.util.stream.Collectors.toSet());
|
||||
+ getCommandMap().getKnownCommands().keySet().removeIf(removals::contains);
|
||||
+ File file = getCommandsConfigFile();
|
||||
+ try {
|
||||
+ commandsConfiguration.load(file);
|
||||
+ } catch (FileNotFoundException ex) {
|
||||
+ return false;
|
||||
+ } catch (IOException | org.bukkit.configuration.InvalidConfigurationException ex) {
|
||||
+ Bukkit.getLogger().log(Level.SEVERE, "Cannot load " + file, ex);
|
||||
+ return false;
|
||||
+ }
|
||||
+ commandMap.registerServerAliases();
|
||||
+ return true;
|
||||
+ }
|
||||
// Paper end
|
||||
}
|
41
patches/server/0111-Add-source-to-PlayerExpChangeEvent.patch
Normal file
41
patches/server/0111-Add-source-to-PlayerExpChangeEvent.patch
Normal file
|
@ -0,0 +1,41 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: AlphaBlend <whizkid3000@hotmail.com>
|
||||
Date: Thu, 8 Sep 2016 08:48:33 -0700
|
||||
Subject: [PATCH] Add source to PlayerExpChangeEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/ExperienceOrb.java b/src/main/java/net/minecraft/world/entity/ExperienceOrb.java
|
||||
index 93c83cfedc7d3a169ad0504aa6e63f600873501b..9dffdfe5bbd0517e9a2c6a6770eea07b43ef9b33 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ExperienceOrb.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ExperienceOrb.java
|
||||
@@ -254,7 +254,7 @@ public class ExperienceOrb extends Entity {
|
||||
int i = this.repairPlayerItems(player, this.value);
|
||||
|
||||
if (i > 0) {
|
||||
- player.giveExperiencePoints(CraftEventFactory.callPlayerExpChangeEvent(player, i).getAmount()); // CraftBukkit - this.value -> event.getAmount()
|
||||
+ player.giveExperiencePoints(CraftEventFactory.callPlayerExpChangeEvent(player, this).getAmount()); // CraftBukkit - this.value -> event.getAmount() // Paper - supply experience orb object
|
||||
}
|
||||
|
||||
--this.count;
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
index 8d9b25f3c8c840baf9c203f80d46201434920aa5..09d11ea7905a5760ab5ee63e5976d67fb6392bed 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
@@ -1148,6 +1148,17 @@ public class CraftEventFactory {
|
||||
return event;
|
||||
}
|
||||
|
||||
+ // Paper start - Add orb
|
||||
+ public static PlayerExpChangeEvent callPlayerExpChangeEvent(net.minecraft.world.entity.player.Player entity, net.minecraft.world.entity.ExperienceOrb entityOrb) {
|
||||
+ Player player = (Player) entity.getBukkitEntity();
|
||||
+ ExperienceOrb source = (ExperienceOrb) entityOrb.getBukkitEntity();
|
||||
+ int expAmount = source.getExperience();
|
||||
+ PlayerExpChangeEvent event = new PlayerExpChangeEvent(player, source, expAmount);
|
||||
+ Bukkit.getPluginManager().callEvent(event);
|
||||
+ return event;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
public static boolean handleBlockGrowEvent(Level world, BlockPos pos, net.minecraft.world.level.block.state.BlockState block) {
|
||||
return CraftEventFactory.handleBlockGrowEvent(world, pos, block, 3);
|
||||
}
|
45
patches/server/0112-Add-ProjectileCollideEvent.patch
Normal file
45
patches/server/0112-Add-ProjectileCollideEvent.patch
Normal file
|
@ -0,0 +1,45 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Techcable <Techcable@outlook.com>
|
||||
Date: Fri, 16 Dec 2016 21:25:39 -0600
|
||||
Subject: [PATCH] Add ProjectileCollideEvent
|
||||
|
||||
Deprecated now and replaced with ProjectileHitEvent
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
index 09d11ea7905a5760ab5ee63e5976d67fb6392bed..beacc9af36eface8cf855ee15fb7bcf7e08f9439 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
@@ -1292,6 +1292,17 @@ public class CraftEventFactory {
|
||||
return CraftItemStack.asNMSCopy(bitem);
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Deprecated
|
||||
+ public static com.destroystokyo.paper.event.entity.ProjectileCollideEvent callProjectileCollideEvent(Entity entity, EntityHitResult position) {
|
||||
+ 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);
|
||||
+ Bukkit.getPluginManager().callEvent(event);
|
||||
+ return event;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
public static ProjectileLaunchEvent callProjectileLaunchEvent(Entity entity) {
|
||||
Projectile bukkitEntity = (Projectile) entity.getBukkitEntity();
|
||||
ProjectileLaunchEvent event = new ProjectileLaunchEvent(bukkitEntity);
|
||||
@@ -1316,8 +1327,15 @@ public class CraftEventFactory {
|
||||
if (position.getType() == HitResult.Type.ENTITY) {
|
||||
hitEntity = ((EntityHitResult) position).getEntity().getBukkitEntity();
|
||||
}
|
||||
+ // Paper start - legacy event
|
||||
+ boolean cancelled = false;
|
||||
+ if (hitEntity != null && position instanceof EntityHitResult entityHitResult) {
|
||||
+ cancelled = callProjectileCollideEvent(entity, entityHitResult).isCancelled();
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
ProjectileHitEvent event = new ProjectileHitEvent((Projectile) entity.getBukkitEntity(), hitEntity, hitBlock, hitFace);
|
||||
+ event.setCancelled(cancelled); // Paper - propagate legacy event cancellation to modern event
|
||||
entity.level().getCraftServer().getPluginManager().callEvent(event);
|
||||
return event;
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 19 Dec 2016 23:07:42 -0500
|
||||
Subject: [PATCH] Prevent Pathfinding out of World Border
|
||||
|
||||
This prevents Entities from trying to run outside of the World Border
|
||||
|
||||
TODO: This doesn't prevent the pathfinder from using blocks outside the world border as nodes. We can fix this
|
||||
by adding code to all overrides in:
|
||||
NodeEvaluator:
|
||||
public abstract BlockPathTypes getBlockPathType(BlockGetter world, int x, int y, int z);
|
||||
|
||||
to return BLOCKED if it is outside the world border.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java b/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java
|
||||
index de87f2e7b8a1662767bab4b0c86ee7cf014ed5cf..eb10ecb4dde7a3df869307fd96c652eb62a8f83e 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java
|
||||
@@ -158,7 +158,7 @@ public abstract class PathNavigation {
|
||||
// Paper start - Pathfind event
|
||||
boolean copiedSet = false;
|
||||
for (BlockPos possibleTarget : positions) {
|
||||
- if (!new com.destroystokyo.paper.event.entity.EntityPathfindEvent(this.mob.getBukkitEntity(),
|
||||
+ if (!this.mob.getCommandSenderWorld().getWorldBorder().isWithinBounds(possibleTarget) || !new com.destroystokyo.paper.event.entity.EntityPathfindEvent(this.mob.getBukkitEntity(), // Paper - don't path out of world border
|
||||
io.papermc.paper.util.MCUtil.toLocation(this.mob.level, possibleTarget), target == null ? null : target.getBukkitEntity()).callEvent()) {
|
||||
if (!copiedSet) {
|
||||
copiedSet = true;
|
|
@ -0,0 +1,23 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Fri, 2 Dec 2016 00:11:43 -0500
|
||||
Subject: [PATCH] Optimize World.isLoaded(BlockPosition)Z
|
||||
|
||||
Reduce method invocations for World.isLoaded(BlockPosition)Z
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
|
||||
index 9ac9a40e442a30b785ba79e015389f3308ae37c3..2bf5dffc7f392278bff9f07e97bef95ba786a916 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/Level.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
||||
@@ -343,6 +343,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
return chunk == null ? null : chunk.getFluidState(blockposition);
|
||||
}
|
||||
|
||||
+ @Override
|
||||
+ public final boolean hasChunkAt(BlockPos pos) {
|
||||
+ return getChunkIfLoaded(pos.getX() >> 4, pos.getZ() >> 4) != null; // Paper
|
||||
+ }
|
||||
+
|
||||
public final boolean isLoadedAndInBounds(BlockPos blockposition) { // Paper - final for inline
|
||||
return getWorldBorder().isWithinBounds(blockposition) && getChunkIfLoadedImmediately(blockposition.getX() >> 4, blockposition.getZ() >> 4) != null;
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 20 Dec 2016 15:15:11 -0500
|
||||
Subject: [PATCH] Bound Treasure Maps to World Border
|
||||
|
||||
Make it so a Treasure Map does not target a structure outside of the
|
||||
World Border, where players are not even able to reach.
|
||||
|
||||
This also would help the case where a players close to the border, and one
|
||||
that is outside happens to be closer, but unreachable, yet another reachable
|
||||
one is in border that would of been missed.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/border/WorldBorder.java b/src/main/java/net/minecraft/world/level/border/WorldBorder.java
|
||||
index 52325a99ea38530ad69a39ac0215233139f35268..dd74e8a034022fe72a1652f92712182b4910f651 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/border/WorldBorder.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/border/WorldBorder.java
|
||||
@@ -37,6 +37,18 @@ public class WorldBorder {
|
||||
return (double) (pos.getX() + 1) > this.getMinX() && (double) pos.getX() < this.getMaxX() && (double) (pos.getZ() + 1) > this.getMinZ() && (double) pos.getZ() < this.getMaxZ();
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ private final BlockPos.MutableBlockPos mutPos = new BlockPos.MutableBlockPos();
|
||||
+ public boolean isBlockInBounds(int chunkX, int chunkZ) {
|
||||
+ this.mutPos.set(chunkX, 64, chunkZ);
|
||||
+ return this.isWithinBounds(this.mutPos);
|
||||
+ }
|
||||
+ public boolean isChunkInBounds(int chunkX, int chunkZ) {
|
||||
+ this.mutPos.set(((chunkX << 4) + 15), 64, (chunkZ << 4) + 15);
|
||||
+ return this.isWithinBounds(this.mutPos);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
public boolean isWithinBounds(ChunkPos pos) {
|
||||
return (double) pos.getMaxBlockX() > this.getMinX() && (double) pos.getMinBlockX() < this.getMaxX() && (double) pos.getMaxBlockZ() > this.getMinZ() && (double) pos.getMinBlockZ() < this.getMaxZ();
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java
|
||||
index 8bb14230beb4b012f38997eec70934b96bae4db5..d19585f0833d13867f242768dc7ed952add87e05 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java
|
||||
@@ -217,6 +217,7 @@ public abstract class ChunkGenerator {
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
ChunkPos chunkcoordintpair = (ChunkPos) iterator.next();
|
||||
+ if (!world.getWorldBorder().isChunkInBounds(chunkcoordintpair.x, chunkcoordintpair.z)) { continue; } // Paper
|
||||
|
||||
blockposition_mutableblockposition.set(SectionPos.sectionToBlockCoord(chunkcoordintpair.x, 8), 32, SectionPos.sectionToBlockCoord(chunkcoordintpair.z, 8));
|
||||
double d1 = blockposition_mutableblockposition.distSqr(center);
|
|
@ -0,0 +1,46 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 20 Dec 2016 15:26:27 -0500
|
||||
Subject: [PATCH] Configurable Cartographer Treasure Maps
|
||||
|
||||
Allow configuring for cartographers to return the same map location
|
||||
|
||||
Also allow turning off treasure maps all together as they can eat up Map ID's
|
||||
which are limited in quantity.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/npc/VillagerTrades.java b/src/main/java/net/minecraft/world/entity/npc/VillagerTrades.java
|
||||
index c29d488d223d817f46bf777656a0c737916c4416..518ef9867421ed9c489fbf5f15e9cbdcaceef6a5 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/npc/VillagerTrades.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/npc/VillagerTrades.java
|
||||
@@ -386,7 +386,8 @@ public class VillagerTrades {
|
||||
return null;
|
||||
} else {
|
||||
ServerLevel serverLevel = (ServerLevel)entity.level();
|
||||
- BlockPos blockPos = serverLevel.findNearestMapStructure(this.destination, entity.blockPosition(), 100, true);
|
||||
+ if (!serverLevel.paperConfig().environment.treasureMaps.enabled) return null; // Paper
|
||||
+ BlockPos blockPos = serverLevel.findNearestMapStructure(this.destination, entity.blockPosition(), 100, !serverLevel.paperConfig().environment.treasureMaps.findAlreadyDiscoveredVillager); // Paper
|
||||
if (blockPos != null) {
|
||||
ItemStack itemStack = MapItem.create(serverLevel, blockPos.getX(), blockPos.getZ(), (byte)2, true, true);
|
||||
MapItem.renderBiomePreviewMap(serverLevel, itemStack);
|
||||
diff --git a/src/main/java/net/minecraft/world/level/storage/loot/functions/ExplorationMapFunction.java b/src/main/java/net/minecraft/world/level/storage/loot/functions/ExplorationMapFunction.java
|
||||
index a8a1e71cfa1cc956d81e5c0d118c57658d272a2d..481456fd69d773e8f3b4eaede3849ce4e599c80f 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/storage/loot/functions/ExplorationMapFunction.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/storage/loot/functions/ExplorationMapFunction.java
|
||||
@@ -68,7 +68,16 @@ public class ExplorationMapFunction extends LootItemConditionalFunction {
|
||||
Vec3 vec3 = context.getParamOrNull(LootContextParams.ORIGIN);
|
||||
if (vec3 != null) {
|
||||
ServerLevel serverLevel = context.getLevel();
|
||||
- BlockPos blockPos = serverLevel.findNearestMapStructure(this.destination, BlockPos.containing(vec3), this.searchRadius, this.skipKnownStructures);
|
||||
+ // Paper start
|
||||
+ if (!serverLevel.paperConfig().environment.treasureMaps.enabled) {
|
||||
+ /*
|
||||
+ * NOTE: I fear users will just get a plain map as their "treasure"
|
||||
+ * This is preferable to disrespecting the config.
|
||||
+ */
|
||||
+ return stack;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+ BlockPos blockPos = serverLevel.findNearestMapStructure(this.destination, BlockPos.containing(vec3), this.searchRadius, !serverLevel.paperConfig().environment.treasureMaps.findAlreadyDiscoveredLootTable.or(!this.skipKnownStructures)); // Paper
|
||||
if (blockPos != null) {
|
||||
ItemStack itemStack = MapItem.create(serverLevel, blockPos.getX(), blockPos.getZ(), this.zoom, true, true);
|
||||
MapItem.renderBiomePreviewMap(serverLevel, itemStack);
|
|
@ -0,0 +1,52 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: kashike <kashike@vq.lc>
|
||||
Date: Wed, 21 Dec 2016 11:47:25 -0600
|
||||
Subject: [PATCH] Add API methods to control if armour stands can move
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
index af6a2e8c4ce41aaf55b645c37f809c2de7ea780a..be7ed906b4a5a8ffda87ecf66f967061b58f8034 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
@@ -92,6 +92,7 @@ public class ArmorStand extends LivingEntity {
|
||||
public Rotations rightArmPose;
|
||||
public Rotations leftLegPose;
|
||||
public Rotations rightLegPose;
|
||||
+ public boolean canMove = true; // Paper
|
||||
|
||||
public ArmorStand(EntityType<? extends ArmorStand> type, Level world) {
|
||||
super(type, world);
|
||||
@@ -942,4 +943,13 @@ public class ArmorStand extends LivingEntity {
|
||||
public boolean canBeSeenByAnyone() {
|
||||
return !this.isInvisible() && !this.isMarker();
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public void move(net.minecraft.world.entity.MoverType type, Vec3 movement) {
|
||||
+ if (this.canMove) {
|
||||
+ super.move(type, movement);
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java
|
||||
index 47ca72e264950dd950f037a21bb0ad6cc1700751..06cedeea447f53d100e32a6eba6f83b4719cb231 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java
|
||||
@@ -228,4 +228,15 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand {
|
||||
public boolean hasEquipmentLock(EquipmentSlot equipmentSlot, LockType lockType) {
|
||||
return (this.getHandle().disabledSlots & (1 << CraftEquipmentSlot.getNMS(equipmentSlot).getFilterFlag() + lockType.ordinal() * 8)) != 0;
|
||||
}
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public boolean canMove() {
|
||||
+ return getHandle().canMove;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setCanMove(boolean move) {
|
||||
+ getHandle().canMove = move;
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
61
patches/server/0118-String-based-Action-Bar-API.patch
Normal file
61
patches/server/0118-String-based-Action-Bar-API.patch
Normal file
|
@ -0,0 +1,61 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 27 Dec 2016 15:02:42 -0500
|
||||
Subject: [PATCH] String based Action Bar API
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundSetActionBarTextPacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundSetActionBarTextPacket.java
|
||||
index 32ef3edebe94a2014168b7e438752a80b2687e5f..ab6c58eed6707ab7b0aa3e7549a871ad7dfad87f 100644
|
||||
--- a/src/main/java/net/minecraft/network/protocol/game/ClientboundSetActionBarTextPacket.java
|
||||
+++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundSetActionBarTextPacket.java
|
||||
@@ -7,6 +7,7 @@ import net.minecraft.network.protocol.Packet;
|
||||
public class ClientboundSetActionBarTextPacket implements Packet<ClientGamePacketListener> {
|
||||
private final Component text;
|
||||
public net.kyori.adventure.text.Component adventure$text; // Paper
|
||||
+ public net.md_5.bungee.api.chat.BaseComponent[] components; // Paper
|
||||
|
||||
public ClientboundSetActionBarTextPacket(Component message) {
|
||||
this.text = message;
|
||||
@@ -21,6 +22,8 @@ public class ClientboundSetActionBarTextPacket implements Packet<ClientGamePacke
|
||||
// Paper start
|
||||
if (this.adventure$text != null) {
|
||||
buf.writeComponent(this.adventure$text);
|
||||
+ } else if (this.components != null) {
|
||||
+ buf.writeComponent(this.components);
|
||||
} else
|
||||
// Paper end
|
||||
buf.writeComponent(this.text);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
index 55715c017e4e08a0e3db95dea5b8ec4fd4acf00d..2dc0233821172a91f471bf7099f2c051c11331e6 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
@@ -289,6 +289,29 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
}
|
||||
|
||||
// Paper start
|
||||
+ @Override
|
||||
+ @Deprecated
|
||||
+ public void sendActionBar(BaseComponent[] message) {
|
||||
+ if (getHandle().connection == null) return;
|
||||
+ net.minecraft.network.protocol.game.ClientboundSetActionBarTextPacket packet = new net.minecraft.network.protocol.game.ClientboundSetActionBarTextPacket((net.minecraft.network.chat.Component) null);
|
||||
+ packet.components = message;
|
||||
+ getHandle().connection.send(packet);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ @Deprecated
|
||||
+ public void sendActionBar(String message) {
|
||||
+ if (getHandle().connection == null || message == null || message.isEmpty()) return;
|
||||
+ getHandle().connection.send(new net.minecraft.network.protocol.game.ClientboundSetActionBarTextPacket(CraftChatMessage.fromStringOrNull(message)));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ @Deprecated
|
||||
+ public void sendActionBar(char alternateChar, String message) {
|
||||
+ if (message == null || message.isEmpty()) return;
|
||||
+ sendActionBar(org.bukkit.ChatColor.translateAlternateColorCodes(alternateChar, message));
|
||||
+ }
|
||||
+
|
||||
@Override
|
||||
public void setPlayerListHeaderFooter(BaseComponent[] header, BaseComponent[] footer) {
|
||||
if (header != null) {
|
33
patches/server/0119-Properly-fix-item-duplication-bug.patch
Normal file
33
patches/server/0119-Properly-fix-item-duplication-bug.patch
Normal file
|
@ -0,0 +1,33 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Alfie Cleveland <alfeh@me.com>
|
||||
Date: Tue, 27 Dec 2016 01:57:57 +0000
|
||||
Subject: [PATCH] Properly fix item duplication bug
|
||||
|
||||
Credit to prplz for figuring out the real issue
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
index d834b6570c9a45fb415afc19262c8735463c27d9..8b35e6804aba52865bda5d9f17ca5cb8576fba6f 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -2350,7 +2350,7 @@ public class ServerPlayer extends Player {
|
||||
|
||||
@Override
|
||||
public boolean isImmobile() {
|
||||
- return super.isImmobile() || !this.getBukkitEntity().isOnline();
|
||||
+ return super.isImmobile() || (this.connection != null && this.connection.isDisconnected()); // Paper
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 590880b71c3c1930eb84538af5f6c3b690bb690f..ec78328916a7cc544fea868afc904208d446739f 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -3142,7 +3142,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
|
||||
}
|
||||
|
||||
public final boolean isDisconnected() {
|
||||
- return !this.player.joining && !this.connection.isConnected();
|
||||
+ return (!this.player.joining && !this.connection.isConnected()) || this.processedDisconnect; // Paper
|
||||
}
|
||||
// CraftBukkit end
|
||||
|
93
patches/server/0120-Firework-API-s.patch
Normal file
93
patches/server/0120-Firework-API-s.patch
Normal file
|
@ -0,0 +1,93 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Wed, 28 Dec 2016 07:18:33 +0100
|
||||
Subject: [PATCH] Firework API's
|
||||
|
||||
== AT ==
|
||||
public net.minecraft.world.entity.projectile.FireworkRocketEntity attachedToEntity
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/projectile/FireworkRocketEntity.java b/src/main/java/net/minecraft/world/entity/projectile/FireworkRocketEntity.java
|
||||
index b16add0be6ac782a7e40be0cdeea4c1829a19d4e..288910fb168ddc5d3a61971778b8038a56772fa8 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/FireworkRocketEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/FireworkRocketEntity.java
|
||||
@@ -38,6 +38,7 @@ public class FireworkRocketEntity extends Projectile implements ItemSupplier {
|
||||
public int lifetime;
|
||||
@Nullable
|
||||
public LivingEntity attachedToEntity;
|
||||
+ public java.util.UUID spawningEntity; // Paper
|
||||
|
||||
public FireworkRocketEntity(EntityType<? extends FireworkRocketEntity> type, Level world) {
|
||||
super(type, world);
|
||||
@@ -317,6 +318,11 @@ public class FireworkRocketEntity extends Projectile implements ItemSupplier {
|
||||
}
|
||||
|
||||
nbt.putBoolean("ShotAtAngle", (Boolean) this.entityData.get(FireworkRocketEntity.DATA_SHOT_AT_ANGLE));
|
||||
+ // Paper start
|
||||
+ if (this.spawningEntity != null) {
|
||||
+ nbt.putUUID("SpawningEntity", this.spawningEntity);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -333,7 +339,11 @@ public class FireworkRocketEntity extends Projectile implements ItemSupplier {
|
||||
if (nbt.contains("ShotAtAngle")) {
|
||||
this.entityData.set(FireworkRocketEntity.DATA_SHOT_AT_ANGLE, nbt.getBoolean("ShotAtAngle"));
|
||||
}
|
||||
-
|
||||
+ // Paper start
|
||||
+ if (nbt.hasUUID("SpawningEntity")) {
|
||||
+ this.spawningEntity = nbt.getUUID("SpawningEntity");
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/net/minecraft/world/item/CrossbowItem.java b/src/main/java/net/minecraft/world/item/CrossbowItem.java
|
||||
index da12a95c230129a3a57dc3d2d7d64012dd8bbae6..9bea5e94c246d843f3d67680ffb57075bd9d3467 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/CrossbowItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/CrossbowItem.java
|
||||
@@ -221,6 +221,7 @@ public class CrossbowItem extends ProjectileWeaponItem implements Vanishable {
|
||||
|
||||
if (flag1) {
|
||||
object = new FireworkRocketEntity(world, projectile, shooter, shooter.getX(), shooter.getEyeY() - 0.15000000596046448D, shooter.getZ(), true);
|
||||
+ ((FireworkRocketEntity) object).spawningEntity = shooter.getUUID(); // Paper
|
||||
} else {
|
||||
object = CrossbowItem.getArrow(world, shooter, crossbow, projectile);
|
||||
if (creative || simulated != 0.0F) {
|
||||
diff --git a/src/main/java/net/minecraft/world/item/FireworkRocketItem.java b/src/main/java/net/minecraft/world/item/FireworkRocketItem.java
|
||||
index 5cafb6f0b507127665393741b372286da098d603..7c627d27300247db9122ab2081049345ef306073 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/FireworkRocketItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/FireworkRocketItem.java
|
||||
@@ -46,6 +46,7 @@ public class FireworkRocketItem extends Item {
|
||||
Vec3 vec3 = context.getClickLocation();
|
||||
Direction direction = context.getClickedFace();
|
||||
FireworkRocketEntity fireworkRocketEntity = new FireworkRocketEntity(level, context.getPlayer(), vec3.x + (double)direction.getStepX() * 0.15D, vec3.y + (double)direction.getStepY() * 0.15D, vec3.z + (double)direction.getStepZ() * 0.15D, itemStack);
|
||||
+ fireworkRocketEntity.spawningEntity = context.getPlayer() == null ? null : context.getPlayer().getUUID(); // Paper
|
||||
level.addFreshEntity(fireworkRocketEntity);
|
||||
itemStack.shrink(1);
|
||||
}
|
||||
@@ -59,6 +60,7 @@ public class FireworkRocketItem extends Item {
|
||||
ItemStack itemStack = user.getItemInHand(hand);
|
||||
if (!world.isClientSide) {
|
||||
FireworkRocketEntity fireworkRocketEntity = new FireworkRocketEntity(world, itemStack, user);
|
||||
+ fireworkRocketEntity.spawningEntity = user.getUUID(); // Paper
|
||||
world.addFreshEntity(fireworkRocketEntity);
|
||||
if (!user.getAbilities().instabuild) {
|
||||
itemStack.shrink(1);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java
|
||||
index 59d5c314711b4ec239e5bcb4272b11ed72705c5a..c242f654c88ca1773429348939d3bb2ffae3768c 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java
|
||||
@@ -135,4 +135,11 @@ public class CraftFirework extends CraftProjectile implements Firework {
|
||||
public void setShotAtAngle(boolean shotAtAngle) {
|
||||
this.getHandle().getEntityData().set(FireworkRocketEntity.DATA_SHOT_AT_ANGLE, shotAtAngle);
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public java.util.UUID getSpawningEntity() {
|
||||
+ return getHandle().spawningEntity;
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
28
patches/server/0121-PlayerTeleportEndGatewayEvent.patch
Normal file
28
patches/server/0121-PlayerTeleportEndGatewayEvent.patch
Normal file
|
@ -0,0 +1,28 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sat, 31 Dec 2016 21:44:50 -0500
|
||||
Subject: [PATCH] PlayerTeleportEndGatewayEvent
|
||||
|
||||
Allows you to access the Gateway being used in a teleport event
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java
|
||||
index 97c57619ebcf31f17f8430ffb68043771d1377f9..9f685b4fe6d57d921e9e7a4d817e0913b863c0ad 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java
|
||||
@@ -12,6 +12,7 @@ import net.minecraft.data.worldgen.features.EndFeatures;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.NbtUtils;
|
||||
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
|
||||
+import io.papermc.paper.util.MCUtil;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.util.Mth;
|
||||
@@ -211,7 +212,7 @@ public class TheEndGatewayBlockEntity extends TheEndPortalBlockEntity {
|
||||
location.setPitch(player.getLocation().getPitch());
|
||||
location.setYaw(player.getLocation().getYaw());
|
||||
|
||||
- PlayerTeleportEvent teleEvent = new PlayerTeleportEvent(player, player.getLocation(), location, PlayerTeleportEvent.TeleportCause.END_GATEWAY);
|
||||
+ PlayerTeleportEvent teleEvent = new com.destroystokyo.paper.event.player.PlayerTeleportEndGatewayEvent(player, player.getLocation(), location, new org.bukkit.craftbukkit.block.CraftEndGateway(worldserver.getWorld(), blockEntity)); // Paper
|
||||
Bukkit.getPluginManager().callEvent(teleEvent);
|
||||
if (teleEvent.isCancelled()) {
|
||||
return;
|
|
@ -0,0 +1,82 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sat, 7 Jan 2017 15:24:46 -0500
|
||||
Subject: [PATCH] Provide E/TE/Chunk count stat methods
|
||||
|
||||
Provides counts without the ineffeciency of using .getEntities().size()
|
||||
which creates copy of the collections.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
|
||||
index 2bf5dffc7f392278bff9f07e97bef95ba786a916..3d04a9f0e9dd14e34c82c0b6225a6ee6d464ee5c 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/Level.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
||||
@@ -116,7 +116,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
public static final int TICKS_PER_DAY = 24000;
|
||||
public static final int MAX_ENTITY_SPAWN_Y = 20000000;
|
||||
public static final int MIN_ENTITY_SPAWN_Y = -20000000;
|
||||
- protected final List<TickingBlockEntity> blockEntityTickers = Lists.newArrayList();
|
||||
+ protected final List<TickingBlockEntity> blockEntityTickers = Lists.newArrayList(); public final int getTotalTileEntityTickers() { return this.blockEntityTickers.size(); } // Paper
|
||||
protected final NeighborUpdater neighborUpdater;
|
||||
private final List<TickingBlockEntity> pendingBlockEntityTickers = Lists.newArrayList();
|
||||
private boolean tickingBlockEntities;
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
index 1440b6b8b71ece71b076601752b06bdcff45542f..1278b114db828606dcd2f70c8f0ab53da490c19f 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
@@ -155,6 +155,56 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
private final CraftPersistentDataContainer persistentDataContainer = new CraftPersistentDataContainer(CraftWorld.DATA_TYPE_REGISTRY);
|
||||
private net.kyori.adventure.pointer.Pointers adventure$pointers; // Paper - implement pointers
|
||||
|
||||
+ // Paper start - Provide fast information methods
|
||||
+ @Override
|
||||
+ public int getEntityCount() {
|
||||
+ int ret = 0;
|
||||
+ for (net.minecraft.world.entity.Entity entity : world.getEntities().getAll()) {
|
||||
+ if (entity.isChunkLoaded()) {
|
||||
+ ++ret;
|
||||
+ }
|
||||
+ }
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getTileEntityCount() {
|
||||
+ // We don't use the full world tile entity list, so we must iterate chunks
|
||||
+ int size = 0;
|
||||
+ for (ChunkHolder playerchunk : io.papermc.paper.chunk.system.ChunkSystem.getVisibleChunkHolders(this.world)) {
|
||||
+ net.minecraft.world.level.chunk.LevelChunk chunk = playerchunk.getTickingChunk();
|
||||
+ if (chunk == null) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ size += chunk.blockEntities.size();
|
||||
+ }
|
||||
+ return size;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getTickableTileEntityCount() {
|
||||
+ return world.getTotalTileEntityTickers();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getChunkCount() {
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ for (ChunkHolder chunkHolder : io.papermc.paper.chunk.system.ChunkSystem.getVisibleChunkHolders(this.world)) {
|
||||
+ if (chunkHolder.getTickingChunk() != null) {
|
||||
+ ++ret;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getPlayerCount() {
|
||||
+ return world.players().size();
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
private static final Random rand = new Random();
|
||||
|
||||
public CraftWorld(ServerLevel world, ChunkGenerator gen, BiomeProvider biomeProvider, Environment env) {
|
27
patches/server/0123-Enforce-Sync-Player-Saves.patch
Normal file
27
patches/server/0123-Enforce-Sync-Player-Saves.patch
Normal file
|
@ -0,0 +1,27 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sat, 7 Jan 2017 15:41:58 -0500
|
||||
Subject: [PATCH] Enforce Sync Player Saves
|
||||
|
||||
Saving players async is extremely dangerous. This will force it to main
|
||||
the same way we handle async chunk loads.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
index 1fa3e06326a871d2d9562433c31e3b17a80fd08c..985b23356a7b5a18b358b5bedd21c5fdd57d6504 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
@@ -1069,11 +1069,13 @@ public abstract class PlayerList {
|
||||
}
|
||||
|
||||
public void saveAll() {
|
||||
+ io.papermc.paper.util.MCUtil.ensureMain("Save Players" , () -> { // Paper - Ensure main
|
||||
MinecraftTimings.savePlayers.startTiming(); // Paper
|
||||
for (int i = 0; i < this.players.size(); ++i) {
|
||||
- this.save((ServerPlayer) this.players.get(i));
|
||||
+ this.save(this.players.get(i));
|
||||
}
|
||||
MinecraftTimings.savePlayers.stopTiming(); // Paper
|
||||
+ return null; }); // Paper - ensure main
|
||||
}
|
||||
|
||||
public UserWhiteList getWhiteList() {
|
|
@ -0,0 +1,18 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Alfie Cleveland <alfeh@me.com>
|
||||
Date: Sun, 8 Jan 2017 04:31:36 +0000
|
||||
Subject: [PATCH] Don't allow entities to ride themselves - #572
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
index 49f465d0009b084be2a8e809c53126af1ad72cd2..20d5a46c4022dfea24f275fe143c32b8ddf629cb 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -2485,6 +2485,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
|
||||
}
|
||||
|
||||
protected boolean addPassenger(Entity entity) { // CraftBukkit
|
||||
+ if (entity == this) throw new IllegalArgumentException("Entities cannot become a passenger of themselves"); // Paper - issue 572
|
||||
if (entity.getVehicle() != this) {
|
||||
throw new IllegalStateException("Use x.startRiding(y), not y.addPassenger(x)");
|
||||
} else {
|
|
@ -0,0 +1,340 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 19 Dec 2017 16:31:46 -0500
|
||||
Subject: [PATCH] ExperienceOrbs API for Reason/Source/Triggering player
|
||||
|
||||
Adds lots of information about why this orb exists.
|
||||
|
||||
Replaces isFromBottle() with logic that persists entity reloads too.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
|
||||
index b1fcdd896fe76fc96f94b626c5a8ffbcce8008ef..2e3b1eb4c4303d40f12c2e80f0608f2308225e97 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
|
||||
@@ -427,7 +427,7 @@ public class ServerPlayerGameMode {
|
||||
|
||||
// Drop event experience
|
||||
if (flag && event != null) {
|
||||
- iblockdata.getBlock().popExperience(this.level, pos, event.getExpToDrop());
|
||||
+ iblockdata.getBlock().popExperience(this.level, pos, event.getExpToDrop(), this.player); // Paper
|
||||
}
|
||||
|
||||
return true;
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/ExperienceOrb.java b/src/main/java/net/minecraft/world/entity/ExperienceOrb.java
|
||||
index 9dffdfe5bbd0517e9a2c6a6770eea07b43ef9b33..558b09a482da3035e37c108e60e9d08849017a8d 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ExperienceOrb.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ExperienceOrb.java
|
||||
@@ -39,13 +39,65 @@ public class ExperienceOrb extends Entity {
|
||||
public int value;
|
||||
private int count;
|
||||
private Player followingPlayer;
|
||||
+ // Paper start
|
||||
+ public java.util.UUID sourceEntityId;
|
||||
+ public java.util.UUID triggerEntityId;
|
||||
+ public org.bukkit.entity.ExperienceOrb.SpawnReason spawnReason = org.bukkit.entity.ExperienceOrb.SpawnReason.UNKNOWN;
|
||||
+
|
||||
+ private void loadPaperNBT(CompoundTag nbttagcompound) {
|
||||
+ if (!nbttagcompound.contains("Paper.ExpData", 10)) { // 10 = compound
|
||||
+ return;
|
||||
+ }
|
||||
+ CompoundTag comp = nbttagcompound.getCompound("Paper.ExpData");
|
||||
+ if (comp.hasUUID("source")) {
|
||||
+ this.sourceEntityId = comp.getUUID("source");
|
||||
+ }
|
||||
+ if (comp.hasUUID("trigger")) {
|
||||
+ this.triggerEntityId = comp.getUUID("trigger");
|
||||
+ }
|
||||
+ if (comp.contains("reason")) {
|
||||
+ String reason = comp.getString("reason");
|
||||
+ try {
|
||||
+ this.spawnReason = org.bukkit.entity.ExperienceOrb.SpawnReason.valueOf(reason);
|
||||
+ } catch (Exception e) {
|
||||
+ this.level.getCraftServer().getLogger().warning("Invalid spawnReason set for experience orb: " + e.getMessage() + " - " + reason);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ private void savePaperNBT(CompoundTag nbttagcompound) {
|
||||
+ CompoundTag comp = new CompoundTag();
|
||||
+ if (this.sourceEntityId != null) {
|
||||
+ comp.putUUID("source", this.sourceEntityId);
|
||||
+ }
|
||||
+ if (this.triggerEntityId != null) {
|
||||
+ comp.putUUID("trigger", triggerEntityId);
|
||||
+ }
|
||||
+ if (this.spawnReason != null && this.spawnReason != org.bukkit.entity.ExperienceOrb.SpawnReason.UNKNOWN) {
|
||||
+ comp.putString("reason", this.spawnReason.name());
|
||||
+ }
|
||||
+ nbttagcompound.put("Paper.ExpData", comp);
|
||||
+ }
|
||||
|
||||
+ @io.papermc.paper.annotation.DoNotUse
|
||||
+ @Deprecated
|
||||
public ExperienceOrb(Level world, double x, double y, double z, int amount) {
|
||||
+ this(world, x, y, z, amount, null, null);
|
||||
+ }
|
||||
+
|
||||
+ public ExperienceOrb(Level world, double d0, double d1, double d2, int i, org.bukkit.entity.ExperienceOrb.SpawnReason reason, Entity triggerId) {
|
||||
+ this(world, d0, d1, d2, i, reason, triggerId, null);
|
||||
+ }
|
||||
+
|
||||
+ public ExperienceOrb(Level world, double d0, double d1, double d2, int i, org.bukkit.entity.ExperienceOrb.SpawnReason reason, Entity triggerId, Entity sourceId) {
|
||||
this(EntityType.EXPERIENCE_ORB, world);
|
||||
- this.setPos(x, y, z);
|
||||
+ this.sourceEntityId = sourceId != null ? sourceId.getUUID() : null;
|
||||
+ this.triggerEntityId = triggerId != null ? triggerId.getUUID() : null;
|
||||
+ this.spawnReason = reason != null ? reason : org.bukkit.entity.ExperienceOrb.SpawnReason.UNKNOWN;
|
||||
+ // Paper end
|
||||
+ this.setPos(d0, d1, d2);
|
||||
this.setYRot((float) (this.random.nextDouble() * 360.0D));
|
||||
this.setDeltaMovement((this.random.nextDouble() * 0.20000000298023224D - 0.10000000149011612D) * 2.0D, this.random.nextDouble() * 0.2D * 2.0D, (this.random.nextDouble() * 0.20000000298023224D - 0.10000000149011612D) * 2.0D);
|
||||
- this.value = amount;
|
||||
+ this.value = i;
|
||||
}
|
||||
|
||||
public ExperienceOrb(EntityType<? extends ExperienceOrb> type, Level world) {
|
||||
@@ -160,12 +212,20 @@ public class ExperienceOrb extends Entity {
|
||||
}
|
||||
|
||||
public static void award(ServerLevel world, Vec3 pos, int amount) {
|
||||
+ // Paper start - add reasons for orbs
|
||||
+ award(world, pos, amount, null, null, null);
|
||||
+ }
|
||||
+ public static void award(ServerLevel world, Vec3 pos, int amount, org.bukkit.entity.ExperienceOrb.SpawnReason reason, Entity triggerId) {
|
||||
+ award(world, pos, amount, reason, triggerId, null);
|
||||
+ }
|
||||
+ public static void award(ServerLevel world, Vec3 pos, int amount, org.bukkit.entity.ExperienceOrb.SpawnReason reason, Entity triggerId, Entity sourceId) {
|
||||
+ // Paper end - add reasons for orbs
|
||||
while (amount > 0) {
|
||||
int j = ExperienceOrb.getExperienceValue(amount);
|
||||
|
||||
amount -= j;
|
||||
if (!ExperienceOrb.tryMergeToExisting(world, pos, j)) {
|
||||
- world.addFreshEntity(new ExperienceOrb(world, pos.x(), pos.y(), pos.z(), j));
|
||||
+ world.addFreshEntity(new ExperienceOrb(world, pos.x(), pos.y(), pos.z(), j, reason, triggerId, sourceId)); // Paper - add reason
|
||||
}
|
||||
}
|
||||
|
||||
@@ -235,6 +295,7 @@ public class ExperienceOrb extends Entity {
|
||||
nbt.putShort("Age", (short) this.age);
|
||||
nbt.putShort("Value", (short) this.value);
|
||||
nbt.putInt("Count", this.count);
|
||||
+ this.savePaperNBT(nbt); // Paper
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -243,6 +304,7 @@ public class ExperienceOrb extends Entity {
|
||||
this.age = nbt.getShort("Age");
|
||||
this.value = nbt.getShort("Value");
|
||||
this.count = Math.max(nbt.getInt("Count"), 1);
|
||||
+ this.loadPaperNBT(nbt); // Paper
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
index ad9f1b9b7adc799af751bfbd0ee6fe6d27a58851..61ee6996b412d74c0d4e632ef05992c6e93187d0 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -1769,7 +1769,8 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
protected void dropExperience() {
|
||||
// CraftBukkit start - Update getExpReward() above if the removed if() changes!
|
||||
if (true && !(this instanceof net.minecraft.world.entity.boss.enderdragon.EnderDragon)) { // CraftBukkit - SPIGOT-2420: Special case ender dragon will drop the xp over time
|
||||
- ExperienceOrb.award((ServerLevel) this.level(), this.position(), this.expToDrop);
|
||||
+ LivingEntity attacker = this.lastHurtByPlayer != null ? this.lastHurtByPlayer : this.lastHurtByMob; // Paper
|
||||
+ ExperienceOrb.award((ServerLevel) this.level(), this.position(), this.expToDrop, this instanceof ServerPlayer ? org.bukkit.entity.ExperienceOrb.SpawnReason.PLAYER_DEATH : org.bukkit.entity.ExperienceOrb.SpawnReason.ENTITY_DEATH, attacker, this); // Paper
|
||||
this.expToDrop = 0;
|
||||
}
|
||||
// CraftBukkit end
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/Animal.java b/src/main/java/net/minecraft/world/entity/animal/Animal.java
|
||||
index fb207550efc5a387ea3346664998882b89e5cdae..8b5e0b9624bdecc3e158d9fc4b2c78f526c6bdeb 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/Animal.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/Animal.java
|
||||
@@ -264,7 +264,7 @@ public abstract class Animal extends AgeableMob {
|
||||
if (world.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) {
|
||||
// CraftBukkit start - use event experience
|
||||
if (experience > 0) {
|
||||
- world.addFreshEntity(new ExperienceOrb(world, this.getX(), this.getY(), this.getZ(), experience));
|
||||
+ world.addFreshEntity(new ExperienceOrb(world, this.getX(), this.getY(), this.getZ(), experience, org.bukkit.entity.ExperienceOrb.SpawnReason.BREED, null)); // Paper //TODO trigger
|
||||
}
|
||||
// CraftBukkit 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 79b99311bcf318aa1aff78c0c905378d99147716..c2a87255178917a9555ec48ff7e705efef2da7ab 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/Fox.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/Fox.java
|
||||
@@ -898,7 +898,7 @@ public class Fox extends Animal implements VariantHolder<Fox.Type> {
|
||||
if (this.level.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) {
|
||||
// CraftBukkit start - use event experience
|
||||
if (experience > 0) {
|
||||
- this.level.addFreshEntity(new ExperienceOrb(this.level, this.animal.getX(), this.animal.getY(), this.animal.getZ(), experience));
|
||||
+ this.level.addFreshEntity(new ExperienceOrb(this.level, this.animal.getX(), this.animal.getY(), this.animal.getZ(), experience, org.bukkit.entity.ExperienceOrb.SpawnReason.BREED, entityplayer, entityfox)); // Paper
|
||||
}
|
||||
// CraftBukkit end
|
||||
}
|
||||
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 6ab7ffe2b0da45c38edd46e9d29df603d3a0b0bc..fcd760cb88f84ff79811631612956fde79905132 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/Turtle.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/Turtle.java
|
||||
@@ -455,7 +455,7 @@ public class Turtle extends Animal {
|
||||
RandomSource randomsource = this.animal.getRandom();
|
||||
|
||||
if (this.level.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) {
|
||||
- this.level.addFreshEntity(new ExperienceOrb(this.level, this.animal.getX(), this.animal.getY(), this.animal.getZ(), randomsource.nextInt(7) + 1));
|
||||
+ this.level.addFreshEntity(new ExperienceOrb(this.level, this.animal.getX(), this.animal.getY(), this.animal.getZ(), randomsource.nextInt(7) + 1, org.bukkit.entity.ExperienceOrb.SpawnReason.BREED, entityplayer)); // Paper;
|
||||
}
|
||||
|
||||
}
|
||||
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 27f99f9ce39aac0bae5e9a7b34fd63833aa4ad26..0f39550f82aa1646dd5e4a887e33c414160ee7d9 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
|
||||
@@ -682,7 +682,7 @@ public class EnderDragon extends Mob implements Enemy {
|
||||
|
||||
if (this.level() instanceof ServerLevel) {
|
||||
if (this.dragonDeathTime > 150 && this.dragonDeathTime % 5 == 0 && true) { // CraftBukkit - SPIGOT-2420: Already checked for the game rule when calculating the xp
|
||||
- ExperienceOrb.award((ServerLevel) this.level(), this.position(), Mth.floor((float) short0 * 0.08F));
|
||||
+ ExperienceOrb.award((ServerLevel) this.level(), this.position(), Mth.floor((float) short0 * 0.08F), org.bukkit.entity.ExperienceOrb.SpawnReason.ENTITY_DEATH, this.lastHurtByPlayer, this); // Paper
|
||||
}
|
||||
|
||||
if (this.dragonDeathTime == 1 && !this.isSilent()) {
|
||||
@@ -710,7 +710,7 @@ public class EnderDragon extends Mob implements Enemy {
|
||||
this.move(MoverType.SELF, new Vec3(0.0D, 0.10000000149011612D, 0.0D));
|
||||
if (this.dragonDeathTime == 200 && this.level() instanceof ServerLevel) {
|
||||
if (true) { // CraftBukkit - SPIGOT-2420: Already checked for the game rule when calculating the xp
|
||||
- ExperienceOrb.award((ServerLevel) this.level(), this.position(), Mth.floor((float) short0 * 0.2F));
|
||||
+ ExperienceOrb.award((ServerLevel) this.level(), this.position(), Mth.floor((float) short0 * 0.2F), org.bukkit.entity.ExperienceOrb.SpawnReason.ENTITY_DEATH, this.lastHurtByPlayer, this); // Paper
|
||||
}
|
||||
|
||||
if (this.dragonFight != null) {
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/npc/Villager.java b/src/main/java/net/minecraft/world/entity/npc/Villager.java
|
||||
index e04f3f1159c5d5fa2e3956a36e95f8afb5a1d4aa..68594d2621267f4b112b4d14d2bec3a0dd6a044a 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/npc/Villager.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java
|
||||
@@ -637,7 +637,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
|
||||
}
|
||||
|
||||
if (offer.shouldRewardExp()) {
|
||||
- this.level().addFreshEntity(new ExperienceOrb(this.level(), this.getX(), this.getY() + 0.5D, this.getZ(), i));
|
||||
+ this.level().addFreshEntity(new ExperienceOrb(this.level(), this.getX(), this.getY() + 0.5D, this.getZ(), i, org.bukkit.entity.ExperienceOrb.SpawnReason.VILLAGER_TRADE, this.getTradingPlayer(), this)); // Paper
|
||||
}
|
||||
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java b/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java
|
||||
index fb80311e90ec83ca39b213d9348c821c402a1933..65592c41b1519eff77ccd7ddd3c885058f3ed138 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java
|
||||
@@ -186,7 +186,7 @@ public class WanderingTrader extends net.minecraft.world.entity.npc.AbstractVill
|
||||
if (offer.shouldRewardExp()) {
|
||||
int i = 3 + this.random.nextInt(4);
|
||||
|
||||
- this.level().addFreshEntity(new ExperienceOrb(this.level(), this.getX(), this.getY() + 0.5D, this.getZ(), i));
|
||||
+ this.level().addFreshEntity(new ExperienceOrb(this.level(), this.getX(), this.getY() + 0.5D, this.getZ(), i, org.bukkit.entity.ExperienceOrb.SpawnReason.VILLAGER_TRADE, this.getTradingPlayer(), this)); // Paper
|
||||
}
|
||||
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java
|
||||
index 4377a0f7387a09983a5580d408775f386ea5f487..dbff697927e6a6c745377aafd3b476b58f005882 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java
|
||||
@@ -522,7 +522,7 @@ public class FishingHook extends Projectile {
|
||||
this.level().addFreshEntity(entityitem);
|
||||
// CraftBukkit start - this.random.nextInt(6) + 1 -> playerFishEvent.getExpToDrop()
|
||||
if (playerFishEvent.getExpToDrop() > 0) {
|
||||
- entityhuman.level().addFreshEntity(new ExperienceOrb(entityhuman.level(), entityhuman.getX(), entityhuman.getY() + 0.5D, entityhuman.getZ() + 0.5D, playerFishEvent.getExpToDrop()));
|
||||
+ entityhuman.level().addFreshEntity(new ExperienceOrb(entityhuman.level(), entityhuman.getX(), entityhuman.getY() + 0.5D, entityhuman.getZ() + 0.5D, playerFishEvent.getExpToDrop(), org.bukkit.entity.ExperienceOrb.SpawnReason.FISHING, this.getPlayerOwner(), this)); // Paper
|
||||
}
|
||||
// CraftBukkit end
|
||||
if (itemstack1.is(ItemTags.FISHES)) {
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/projectile/ThrownExperienceBottle.java b/src/main/java/net/minecraft/world/entity/projectile/ThrownExperienceBottle.java
|
||||
index 2191af62f4202413738542d738456ca71febdbf4..5b3059460d4b18d984483d655526d83204fb1c73 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/ThrownExperienceBottle.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/ThrownExperienceBottle.java
|
||||
@@ -51,7 +51,7 @@ public class ThrownExperienceBottle extends ThrowableItemProjectile {
|
||||
}
|
||||
// CraftBukkit end
|
||||
|
||||
- ExperienceOrb.award((ServerLevel) this.level(), this.position(), i);
|
||||
+ ExperienceOrb.award((ServerLevel) this.level(), this.position(), i, org.bukkit.entity.ExperienceOrb.SpawnReason.EXP_BOTTLE, this.getOwner(), this); // Paper
|
||||
this.discard();
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java b/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java
|
||||
index c858b987cb6f92cc6fa705bbe1ae11a720eb242c..2c263447aa8853f18d1c1d476b49a47f6e9ca2ad 100644
|
||||
--- a/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java
|
||||
+++ b/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java
|
||||
@@ -97,7 +97,7 @@ public class GrindstoneMenu extends AbstractContainerMenu {
|
||||
public void onTake(net.minecraft.world.entity.player.Player player, ItemStack stack) {
|
||||
context.execute((world, blockposition) -> {
|
||||
if (world instanceof ServerLevel) {
|
||||
- ExperienceOrb.award((ServerLevel) world, Vec3.atCenterOf(blockposition), this.getExperienceAmount(world));
|
||||
+ ExperienceOrb.award((ServerLevel) world, Vec3.atCenterOf(blockposition), this.getExperienceAmount(world), org.bukkit.entity.ExperienceOrb.SpawnReason.GRINDSTONE, player); // Paper
|
||||
}
|
||||
|
||||
world.levelEvent(1042, blockposition, 0);
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/Block.java b/src/main/java/net/minecraft/world/level/block/Block.java
|
||||
index 7ed82beb538a25a5246f6288c1dddb4f5f85e997..7646b66bc5ba0288608de0d836c7307e02eebe67 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/Block.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/Block.java
|
||||
@@ -362,8 +362,13 @@ public class Block extends BlockBehaviour implements ItemLike {
|
||||
}
|
||||
|
||||
public void popExperience(ServerLevel world, BlockPos pos, int size) {
|
||||
+ // Paper start - add player parameter
|
||||
+ popExperience(world, pos, size, null);
|
||||
+ }
|
||||
+ public void popExperience(ServerLevel world, BlockPos pos, int size, net.minecraft.server.level.ServerPlayer player) {
|
||||
+ // Paper end - add player parameter
|
||||
if (world.getGameRules().getBoolean(GameRules.RULE_DOBLOCKDROPS)) {
|
||||
- ExperienceOrb.award(world, Vec3.atCenterOf(pos), size);
|
||||
+ ExperienceOrb.award(world, Vec3.atCenterOf(pos), size, org.bukkit.entity.ExperienceOrb.SpawnReason.BLOCK_BREAK, player); // Paper
|
||||
}
|
||||
|
||||
}
|
||||
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 9113fd7070596ecf504837f335022d5eb4ef9a77..d56a64b058d8848e405e33d9884a61ea952a8f71 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
|
||||
@@ -647,7 +647,7 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit
|
||||
j = event.getExpToDrop();
|
||||
// CraftBukkit end
|
||||
|
||||
- ExperienceOrb.award(worldserver, vec3d, j);
|
||||
+ ExperienceOrb.award(worldserver, vec3d, j, org.bukkit.entity.ExperienceOrb.SpawnReason.FURNACE, entityhuman); // Paper
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java
|
||||
index e6eb4a903a43572cfda72db52a1d9c6a6fd46dee..101dac0fcabc5fd696f58ec52ad1fc93a2d0afeb 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java
|
||||
@@ -946,7 +946,7 @@ public abstract class CraftRegionAccessor implements RegionAccessor {
|
||||
} else if (TNTPrimed.class.isAssignableFrom(clazz)) {
|
||||
entity = new PrimedTnt(world, x, y, z, null);
|
||||
} else if (ExperienceOrb.class.isAssignableFrom(clazz)) {
|
||||
- entity = new net.minecraft.world.entity.ExperienceOrb(world, x, y, z, 0);
|
||||
+ entity = new net.minecraft.world.entity.ExperienceOrb(world, x, y, z, 0, org.bukkit.entity.ExperienceOrb.SpawnReason.CUSTOM, null, null); // Paper
|
||||
} else if (LightningStrike.class.isAssignableFrom(clazz)) {
|
||||
entity = net.minecraft.world.entity.EntityType.LIGHTNING_BOLT.create(world);
|
||||
entity.moveTo(location.getX(), location.getY(), location.getZ());
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftExperienceOrb.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftExperienceOrb.java
|
||||
index 40713228b149b4532fcee3a54bbe63e161318258..84899284703baeb04bfc79251941265d52ac07e8 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftExperienceOrb.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftExperienceOrb.java
|
||||
@@ -19,6 +19,18 @@ public class CraftExperienceOrb extends CraftEntity implements ExperienceOrb {
|
||||
this.getHandle().value = value;
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ public java.util.UUID getTriggerEntityId() {
|
||||
+ return getHandle().triggerEntityId;
|
||||
+ }
|
||||
+ public java.util.UUID getSourceEntityId() {
|
||||
+ return getHandle().sourceEntityId;
|
||||
+ }
|
||||
+ public SpawnReason getSpawnReason() {
|
||||
+ return getHandle().spawnReason;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public net.minecraft.world.entity.ExperienceOrb getHandle() {
|
||||
return (net.minecraft.world.entity.ExperienceOrb) entity;
|
42
patches/server/0126-Cap-Entity-Collisions.patch
Normal file
42
patches/server/0126-Cap-Entity-Collisions.patch
Normal file
|
@ -0,0 +1,42 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sun, 22 Jan 2017 18:07:56 -0500
|
||||
Subject: [PATCH] Cap Entity Collisions
|
||||
|
||||
Limit a single entity to colliding a max of configurable times per tick.
|
||||
This will alleviate issues where living entities are hoarded in 1x1 pens
|
||||
|
||||
This is not tied to the maxEntityCramming rule. Cramming will still apply
|
||||
just as it does in Vanilla, but entity pushing logic will be capped.
|
||||
|
||||
You can set this to 0 to disable collisions.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
index 20d5a46c4022dfea24f275fe143c32b8ddf629cb..568631c8711788053af407574ab928cb57c11560 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -387,6 +387,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
|
||||
public void inactiveTick() { }
|
||||
// Spigot end
|
||||
// Paper start
|
||||
+ protected int numCollisions = 0; // Paper
|
||||
@javax.annotation.Nullable
|
||||
private org.bukkit.util.Vector origin;
|
||||
@javax.annotation.Nullable
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
index 61ee6996b412d74c0d4e632ef05992c6e93187d0..a266f06422ddf52666eb11663cbf287279245596 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -3327,8 +3327,11 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
}
|
||||
}
|
||||
|
||||
- for (j = 0; j < list.size(); ++j) {
|
||||
+ this.numCollisions = Math.max(0, this.numCollisions - this.level.paperConfig().collisions.maxEntityCollisions); // Paper
|
||||
+ for (j = 0; j < list.size() && this.numCollisions < this.level.paperConfig().collisions.maxEntityCollisions; ++j) { // Paper
|
||||
Entity entity = (Entity) list.get(j);
|
||||
+ entity.numCollisions++; // Paper
|
||||
+ this.numCollisions++; // Paper
|
||||
|
||||
this.doPush(entity);
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sun, 5 Feb 2017 00:04:04 -0500
|
||||
Subject: [PATCH] Remove CraftScheduler Async Task Debugger
|
||||
|
||||
I have not once ever seen this system help debug a crash.
|
||||
One report of a suspected memory leak with the system.
|
||||
|
||||
This adds additional overhead to asynchronous task dispatching
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
|
||||
index dfc2789009fcaa08baa8054bdac915590b8701d6..d96292052633941102c052894bef747817b2998f 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
|
||||
@@ -445,7 +445,7 @@ public class CraftScheduler implements BukkitScheduler {
|
||||
}
|
||||
this.parsePending();
|
||||
} else {
|
||||
- this.debugTail = this.debugTail.setNext(new CraftAsyncDebugger(currentTick + CraftScheduler.RECENT_TICKS, task.getOwner(), task.getTaskClass()));
|
||||
+ //this.debugTail = this.debugTail.setNext(new CraftAsyncDebugger(currentTick + CraftScheduler.RECENT_TICKS, task.getOwner(), task.getTaskClass())); // Paper
|
||||
this.executor.execute(new ServerSchedulerReportingWrapper(task)); // Paper
|
||||
// We don't need to parse pending
|
||||
// (async tasks must live with race-conditions if they attempt to cancel between these few lines of code)
|
||||
@@ -462,7 +462,7 @@ public class CraftScheduler implements BukkitScheduler {
|
||||
this.pending.addAll(temp);
|
||||
temp.clear();
|
||||
MinecraftTimings.bukkitSchedulerFinishTimer.stopTiming(); // Paper
|
||||
- this.debugHead = this.debugHead.getNextHead(currentTick);
|
||||
+ //this.debugHead = this.debugHead.getNextHead(currentTick); // Paper
|
||||
}
|
||||
|
||||
private void addTask(final CraftTask task) {
|
||||
@@ -527,10 +527,15 @@ public class CraftScheduler implements BukkitScheduler {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
+ // Paper start
|
||||
+ return "";
|
||||
+ /*
|
||||
int debugTick = this.currentTick;
|
||||
StringBuilder string = new StringBuilder("Recent tasks from ").append(debugTick - CraftScheduler.RECENT_TICKS).append('-').append(debugTick).append('{');
|
||||
this.debugHead.debugTo(string);
|
||||
return string.append('}').toString();
|
||||
+ */
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
@Deprecated
|
23
patches/server/0128-Do-not-let-armorstands-drown.patch
Normal file
23
patches/server/0128-Do-not-let-armorstands-drown.patch
Normal file
|
@ -0,0 +1,23 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <zach.brown@destroystokyo.com>
|
||||
Date: Sat, 18 Feb 2017 19:29:58 -0600
|
||||
Subject: [PATCH] Do not let armorstands drown
|
||||
|
||||
|
||||
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 be7ed906b4a5a8ffda87ecf66f967061b58f8034..68ac3ffae5d800bde3c5b5163a52768a43bb5963 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
@@ -951,5 +951,12 @@ public class ArmorStand extends LivingEntity {
|
||||
super.move(type, movement);
|
||||
}
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public boolean canBreatheUnderwater() { // Skips a bit of damage handling code, probably a micro-optimization
|
||||
+ return true;
|
||||
+ }
|
||||
+ // Paper end
|
||||
// Paper end
|
||||
}
|
|
@ -0,0 +1,290 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <zach.brown@destroystokyo.com>
|
||||
Date: Fri, 12 May 2017 23:34:11 -0500
|
||||
Subject: [PATCH] Properly handle async calls to restart the server
|
||||
|
||||
The watchdog thread calls the server restart function asynchronously. Prior to
|
||||
this change, it attempted to do several non-safe operations from the watchdog
|
||||
thread, rather than the main. Specifically, because of a separate upstream change,
|
||||
it causes player entities to be ticked asynchronously, among other things.
|
||||
|
||||
This is dangerous.
|
||||
|
||||
This patch moves the old handling into a synchronous variant, for calls from the
|
||||
restart command, and adds separate handling for async calls, such as those from
|
||||
the watchdog thread.
|
||||
|
||||
When calling from the watchdog thread, we cannot assume the main thread is in a
|
||||
tickable state; it may be completely deadlocked. In order to handle this, we mark
|
||||
the server as stopping, in order to account for situations where the server should
|
||||
complete a tick reasonbly soon, i.e. 99% of cases.
|
||||
|
||||
Should the server not enter a state where it is stopping within 10 seconds, We
|
||||
will assume that the server has in fact deadlocked and will proceed to force
|
||||
kill the server.
|
||||
|
||||
This modification does not force restart the server should we actually enter a
|
||||
deadlocked state where the server is stopping, whereas this will in most cases
|
||||
exit within a reasonable amount of time, to put a fixed limit on a process that
|
||||
will have plugins and worlds saving to the disk has a high potential to result
|
||||
in corruption/dataloss.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index 857cc4fcc586f7a8ea5baeeae69da62ebfdac77a..e292035cf361c8efa8845450b72a6986694a8ca9 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -237,6 +237,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
private Map<ResourceKey<Level>, ServerLevel> levels;
|
||||
private PlayerList playerList;
|
||||
private volatile boolean running;
|
||||
+ private volatile boolean isRestarting = false; // Paper - flag to signify we're attempting to restart
|
||||
private boolean stopped;
|
||||
private int tickCount;
|
||||
protected final Proxy proxy;
|
||||
@@ -893,7 +894,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
if (this.playerList != null) {
|
||||
MinecraftServer.LOGGER.info("Saving players");
|
||||
this.playerList.saveAll();
|
||||
- this.playerList.removeAll();
|
||||
+ this.playerList.removeAll(this.isRestarting); // Paper
|
||||
try { Thread.sleep(100); } catch (InterruptedException ex) {} // CraftBukkit - SPIGOT-625 - give server at least a chance to send packets
|
||||
}
|
||||
|
||||
@@ -973,6 +974,12 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
}
|
||||
|
||||
public void halt(boolean waitForShutdown) {
|
||||
+ // Paper start - allow passing of the intent to restart
|
||||
+ this.safeShutdown(waitForShutdown, false);
|
||||
+ }
|
||||
+ public void safeShutdown(boolean waitForShutdown, boolean isRestarting) {
|
||||
+ this.isRestarting = isRestarting;
|
||||
+ // Paper end
|
||||
this.running = false;
|
||||
if (waitForShutdown) {
|
||||
try {
|
||||
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
index 985b23356a7b5a18b358b5bedd21c5fdd57d6504..d28f662d4a935994525118a403f3dc39cfa81a49 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
@@ -1181,8 +1181,15 @@ public abstract class PlayerList {
|
||||
}
|
||||
|
||||
public void removeAll() {
|
||||
+ // Paper start - Extract method to allow for restarting flag
|
||||
+ this.removeAll(false);
|
||||
+ }
|
||||
+
|
||||
+ public void removeAll(boolean isRestarting) {
|
||||
+ // Paper end
|
||||
// CraftBukkit start - disconnect safely
|
||||
for (ServerPlayer player : this.players) {
|
||||
+ if (isRestarting) player.connection.disconnect(org.spigotmc.SpigotConfig.restartMessage); else // Paper
|
||||
player.connection.disconnect(this.server.server.shutdownMessage()); // CraftBukkit - add custom shutdown message // Paper - Adventure
|
||||
}
|
||||
// CraftBukkit end
|
||||
diff --git a/src/main/java/org/spigotmc/RestartCommand.java b/src/main/java/org/spigotmc/RestartCommand.java
|
||||
index 94d8ba376cd1f024b244654cac9bb62bb19e3060..a142a56a920e153ed84c08cece993f10d76f7793 100644
|
||||
--- a/src/main/java/org/spigotmc/RestartCommand.java
|
||||
+++ b/src/main/java/org/spigotmc/RestartCommand.java
|
||||
@@ -46,86 +46,134 @@ public class RestartCommand extends Command
|
||||
org.spigotmc.AsyncCatcher.shuttingDown = true; // Paper
|
||||
try
|
||||
{
|
||||
- String[] split = restartScript.split( " " );
|
||||
- if ( split.length > 0 && new File( split[0] ).isFile() )
|
||||
+ // Paper - extract method and cleanup
|
||||
+ boolean isRestarting = addShutdownHook( restartScript );
|
||||
+ if ( isRestarting )
|
||||
{
|
||||
- System.out.println( "Attempting to restart with " + restartScript );
|
||||
+ System.out.println( "Attempting to restart with " + SpigotConfig.restartScript );
|
||||
+ } else
|
||||
+ {
|
||||
+ System.out.println( "Startup script '" + SpigotConfig.restartScript + "' does not exist! Stopping server." );
|
||||
+ }
|
||||
+ // Stop the watchdog
|
||||
+ WatchdogThread.doStop();
|
||||
|
||||
- // Disable Watchdog
|
||||
- WatchdogThread.doStop();
|
||||
+ shutdownServer( isRestarting );
|
||||
+ // Paper end
|
||||
+ } catch ( Exception ex )
|
||||
+ {
|
||||
+ ex.printStackTrace();
|
||||
+ }
|
||||
+ }
|
||||
|
||||
- // Kick all players
|
||||
- for ( ServerPlayer p : (List<ServerPlayer>) MinecraftServer.getServer().getPlayerList().players )
|
||||
- {
|
||||
- p.connection.disconnect(SpigotConfig.restartMessage);
|
||||
- }
|
||||
- // Give the socket a chance to send the packets
|
||||
- try
|
||||
- {
|
||||
- Thread.sleep( 100 );
|
||||
- } catch ( InterruptedException ex )
|
||||
- {
|
||||
- }
|
||||
- // Close the socket so we can rebind with the new process
|
||||
- MinecraftServer.getServer().getConnection().stop();
|
||||
+ // Paper start - sync copied from above with minor changes, async added
|
||||
+ private static void shutdownServer(boolean isRestarting)
|
||||
+ {
|
||||
+ if ( MinecraftServer.getServer().isSameThread() )
|
||||
+ {
|
||||
+ // Kick all players
|
||||
+ for ( ServerPlayer p : com.google.common.collect.ImmutableList.copyOf( MinecraftServer.getServer().getPlayerList().players ) )
|
||||
+ {
|
||||
+ p.connection.disconnect(SpigotConfig.restartMessage);
|
||||
+ }
|
||||
+ // Give the socket a chance to send the packets
|
||||
+ try
|
||||
+ {
|
||||
+ Thread.sleep( 100 );
|
||||
+ } catch ( InterruptedException ex )
|
||||
+ {
|
||||
+ }
|
||||
|
||||
- // Give time for it to kick in
|
||||
- try
|
||||
- {
|
||||
- Thread.sleep( 100 );
|
||||
- } catch ( InterruptedException ex )
|
||||
- {
|
||||
- }
|
||||
+ closeSocket();
|
||||
|
||||
- // Actually shutdown
|
||||
- try
|
||||
- {
|
||||
- MinecraftServer.getServer().close();
|
||||
- } catch ( Throwable t )
|
||||
- {
|
||||
- }
|
||||
+ // Actually shutdown
|
||||
+ try
|
||||
+ {
|
||||
+ MinecraftServer.getServer().close(); // calls stop()
|
||||
+ } catch ( Throwable t )
|
||||
+ {
|
||||
+ }
|
||||
+
|
||||
+ // Actually stop the JVM
|
||||
+ System.exit( 0 );
|
||||
|
||||
- // This will be done AFTER the server has completely halted
|
||||
- Thread shutdownHook = new Thread()
|
||||
+ } else
|
||||
+ {
|
||||
+ // Mark the server to shutdown at the end of the tick
|
||||
+ MinecraftServer.getServer().safeShutdown( false, isRestarting );
|
||||
+
|
||||
+ // wait 10 seconds to see if we're actually going to try shutdown
|
||||
+ try
|
||||
+ {
|
||||
+ Thread.sleep( 10000 );
|
||||
+ }
|
||||
+ catch (InterruptedException ignored)
|
||||
+ {
|
||||
+ }
|
||||
+
|
||||
+ // Check if we've actually hit a state where the server is going to safely shutdown
|
||||
+ // if we have, let the server stop as usual
|
||||
+ if (MinecraftServer.getServer().isStopped()) return;
|
||||
+
|
||||
+ // If the server hasn't stopped by now, assume worse case and kill
|
||||
+ closeSocket();
|
||||
+ System.exit( 0 );
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
+ // Paper - Split from moved code
|
||||
+ private static void closeSocket()
|
||||
+ {
|
||||
+ // Close the socket so we can rebind with the new process
|
||||
+ MinecraftServer.getServer().getConnection().stop();
|
||||
+
|
||||
+ // Give time for it to kick in
|
||||
+ try
|
||||
+ {
|
||||
+ Thread.sleep( 100 );
|
||||
+ } catch ( InterruptedException ex )
|
||||
+ {
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
+ // Paper start - copied from above and modified to return if the hook registered
|
||||
+ private static boolean addShutdownHook(String restartScript)
|
||||
+ {
|
||||
+ String[] split = restartScript.split( " " );
|
||||
+ if ( split.length > 0 && new File( split[0] ).isFile() )
|
||||
+ {
|
||||
+ Thread shutdownHook = new Thread()
|
||||
+ {
|
||||
+ @Override
|
||||
+ public void run()
|
||||
{
|
||||
- @Override
|
||||
- public void run()
|
||||
+ try
|
||||
{
|
||||
- try
|
||||
+ String os = System.getProperty( "os.name" ).toLowerCase(java.util.Locale.ENGLISH);
|
||||
+ if ( os.contains( "win" ) )
|
||||
{
|
||||
- String os = System.getProperty( "os.name" ).toLowerCase(java.util.Locale.ENGLISH);
|
||||
- if ( os.contains( "win" ) )
|
||||
- {
|
||||
- Runtime.getRuntime().exec( "cmd /c start " + restartScript );
|
||||
- } else
|
||||
- {
|
||||
- Runtime.getRuntime().exec( "sh " + restartScript );
|
||||
- }
|
||||
- } catch ( Exception e )
|
||||
+ Runtime.getRuntime().exec( "cmd /c start " + restartScript );
|
||||
+ } else
|
||||
{
|
||||
- e.printStackTrace();
|
||||
+ Runtime.getRuntime().exec( "sh " + restartScript );
|
||||
}
|
||||
+ } catch ( Exception e )
|
||||
+ {
|
||||
+ e.printStackTrace();
|
||||
}
|
||||
- };
|
||||
-
|
||||
- shutdownHook.setDaemon( true );
|
||||
- Runtime.getRuntime().addShutdownHook( shutdownHook );
|
||||
- } else
|
||||
- {
|
||||
- System.out.println( "Startup script '" + SpigotConfig.restartScript + "' does not exist! Stopping server." );
|
||||
-
|
||||
- // Actually shutdown
|
||||
- try
|
||||
- {
|
||||
- MinecraftServer.getServer().close();
|
||||
- } catch ( Throwable t )
|
||||
- {
|
||||
}
|
||||
- }
|
||||
- System.exit( 0 );
|
||||
- } catch ( Exception ex )
|
||||
+ };
|
||||
+
|
||||
+ shutdownHook.setDaemon( true );
|
||||
+ Runtime.getRuntime().addShutdownHook( shutdownHook );
|
||||
+ return true;
|
||||
+ } else
|
||||
{
|
||||
- ex.printStackTrace();
|
||||
+ return false;
|
||||
}
|
||||
}
|
||||
+ // Paper end
|
||||
+
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <zach.brown@destroystokyo.com>
|
||||
Date: Tue, 16 May 2017 21:29:08 -0500
|
||||
Subject: [PATCH] Add option to make parrots stay on shoulders despite movement
|
||||
|
||||
Makes parrots not fall off whenever the player changes height, or touches water, or gets hit by a passing leaf.
|
||||
Instead, switches the behavior so that players have to sneak to make the birds leave.
|
||||
|
||||
I suspect Mojang may switch to this behavior before full release.
|
||||
|
||||
To be converted into a Paper-API event at some point in the future?
|
||||
|
||||
== AT ==
|
||||
public net.minecraft.world.entity.player.Player removeEntitiesOnShoulder()V
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index ec78328916a7cc544fea868afc904208d446739f..5f79819a8168592138e0b2297825402502c6b54d 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -2322,6 +2322,13 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
|
||||
switch (packet.getAction()) {
|
||||
case PRESS_SHIFT_KEY:
|
||||
this.player.setShiftKeyDown(true);
|
||||
+
|
||||
+ // Paper start - Hang on!
|
||||
+ if (this.player.level.paperConfig().entities.behavior.parrotsAreUnaffectedByPlayerMovement) {
|
||||
+ this.player.removeEntitiesOnShoulder();
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
break;
|
||||
case RELEASE_SHIFT_KEY:
|
||||
this.player.setShiftKeyDown(false);
|
||||
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 5ef9abc0903fc06468c35f5a8cc450a8f6c03165..90aba22c91bf9950c4df2204afc3fc97e411ea9a 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
@@ -588,6 +588,7 @@ public abstract class Player extends LivingEntity {
|
||||
this.playShoulderEntityAmbientSound(this.getShoulderEntityLeft());
|
||||
this.playShoulderEntityAmbientSound(this.getShoulderEntityRight());
|
||||
if (!this.level().isClientSide && (this.fallDistance > 0.5F || this.isInWater()) || this.abilities.flying || this.isSleeping() || this.isInPowderSnow) {
|
||||
+ if (!this.level().paperConfig().entities.behavior.parrotsAreUnaffectedByPlayerMovement) // Paper - Hang on!
|
||||
this.removeEntitiesOnShoulder();
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: kashike <kashike@vq.lc>
|
||||
Date: Fri, 9 Jun 2017 07:24:34 -0700
|
||||
Subject: [PATCH] Add configuration option to prevent player names from being
|
||||
suggested
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index 3d6c25424c859f63c8f4661b39c82c269c3837fb..12c36e02e271cc8e13b20059fbfb30f4e8172023 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -2648,5 +2648,10 @@ public final class CraftServer implements Server {
|
||||
commandMap.registerServerAliases();
|
||||
return true;
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean suggestPlayerNamesWhenNullTabCompletions() {
|
||||
+ return io.papermc.paper.configuration.GlobalConfiguration.get().commands.suggestPlayerNamesWhenNullTabCompletions;
|
||||
+ }
|
||||
// Paper end
|
||||
}
|
|
@ -0,0 +1,517 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Minecrell <minecrell@minecrell.net>
|
||||
Date: Fri, 9 Jun 2017 19:03:43 +0200
|
||||
Subject: [PATCH] Use TerminalConsoleAppender for console improvements
|
||||
|
||||
Rewrite console improvements (console colors, tab completion,
|
||||
persistent input line, ...) using JLine 3.x and TerminalConsoleAppender.
|
||||
|
||||
New features:
|
||||
- Support console colors for Vanilla commands
|
||||
- Add console colors for warnings and errors
|
||||
- Server can now be turned off safely using CTRL + C. JLine catches
|
||||
the signal and the implementation shuts down the server cleanly.
|
||||
- Support console colors and persistent input line when running in
|
||||
IntelliJ IDEA
|
||||
|
||||
Other changes:
|
||||
- Server starts 1-2 seconds faster thanks to optimizations in Log4j
|
||||
configuration
|
||||
|
||||
diff --git a/build.gradle.kts b/build.gradle.kts
|
||||
index bdd78d14723211bfec493126d603b99611cdf748..9fb608d9cfb0dcd8d937244ecbe97487757af479 100644
|
||||
--- a/build.gradle.kts
|
||||
+++ b/build.gradle.kts
|
||||
@@ -8,7 +8,17 @@ plugins {
|
||||
|
||||
dependencies {
|
||||
implementation(project(":paper-api"))
|
||||
- implementation("jline:jline:2.12.1")
|
||||
+ // Paper start
|
||||
+ implementation("org.jline:jline-terminal-jansi:3.21.0")
|
||||
+ implementation("net.minecrell:terminalconsoleappender:1.3.0")
|
||||
+ /*
|
||||
+ Required to add the missing Log4j2Plugins.dat file from log4j-core
|
||||
+ which has been removed by Mojang. Without it, log4j has to classload
|
||||
+ all its classes to check if they are plugins.
|
||||
+ Scanning takes about 1-2 seconds so adding this speeds up the server start.
|
||||
+ */
|
||||
+ runtimeOnly("org.apache.logging.log4j:log4j-core:2.14.1")
|
||||
+ // Paper end
|
||||
implementation("org.apache.logging.log4j:log4j-iostreams:2.19.0") // Paper - remove exclusion
|
||||
implementation("org.ow2.asm:asm:9.4")
|
||||
implementation("org.ow2.asm:asm-commons:9.4") // Paper - ASM event executor generation
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/console/PaperConsole.java b/src/main/java/com/destroystokyo/paper/console/PaperConsole.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..a4070b59e261f0f1ac4beec47b11492f4724bf27
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/console/PaperConsole.java
|
||||
@@ -0,0 +1,41 @@
|
||||
+package com.destroystokyo.paper.console;
|
||||
+
|
||||
+import net.minecraft.server.dedicated.DedicatedServer;
|
||||
+import net.minecrell.terminalconsole.SimpleTerminalConsole;
|
||||
+import org.bukkit.craftbukkit.command.ConsoleCommandCompleter;
|
||||
+import org.jline.reader.LineReader;
|
||||
+import org.jline.reader.LineReaderBuilder;
|
||||
+
|
||||
+public final class PaperConsole extends SimpleTerminalConsole {
|
||||
+
|
||||
+ private final DedicatedServer server;
|
||||
+
|
||||
+ public PaperConsole(DedicatedServer server) {
|
||||
+ this.server = server;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ protected LineReader buildReader(LineReaderBuilder builder) {
|
||||
+ return super.buildReader(builder
|
||||
+ .appName("Paper")
|
||||
+ .variable(LineReader.HISTORY_FILE, java.nio.file.Paths.get(".console_history"))
|
||||
+ .completer(new ConsoleCommandCompleter(this.server))
|
||||
+ );
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ protected boolean isRunning() {
|
||||
+ return !this.server.isStopped() && this.server.isRunning();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ protected void runCommand(String command) {
|
||||
+ this.server.handleConsoleInput(command, this.server.createCommandSourceStack());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ protected void shutdown() {
|
||||
+ this.server.halt(false);
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/console/TerminalConsoleCommandSender.java b/src/main/java/com/destroystokyo/paper/console/TerminalConsoleCommandSender.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..685deaa0e5d1ddc13e3a7c0471b1cfcf1710c869
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/console/TerminalConsoleCommandSender.java
|
||||
@@ -0,0 +1,17 @@
|
||||
+package com.destroystokyo.paper.console;
|
||||
+
|
||||
+import org.apache.logging.log4j.LogManager;
|
||||
+import org.apache.logging.log4j.Logger;
|
||||
+import org.bukkit.craftbukkit.command.CraftConsoleCommandSender;
|
||||
+
|
||||
+public class TerminalConsoleCommandSender extends CraftConsoleCommandSender {
|
||||
+
|
||||
+ private static final Logger LOGGER = LogManager.getRootLogger();
|
||||
+
|
||||
+ @Override
|
||||
+ public void sendRawMessage(String message) {
|
||||
+ // TerminalConsoleAppender supports color codes directly in log messages
|
||||
+ LOGGER.info(message);
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index e292035cf361c8efa8845450b72a6986694a8ca9..9fad7c117033694bc5850b9f9585e439c44ef0dd 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -165,7 +165,7 @@ import com.mojang.datafixers.util.Pair;
|
||||
import com.mojang.serialization.DynamicOps;
|
||||
import com.mojang.serialization.Lifecycle;
|
||||
import java.util.Random;
|
||||
-import jline.console.ConsoleReader;
|
||||
+// import jline.console.ConsoleReader; // Paper
|
||||
import joptsimple.OptionSet;
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.resources.RegistryOps;
|
||||
@@ -286,7 +286,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
public OptionSet options;
|
||||
public org.bukkit.command.ConsoleCommandSender console;
|
||||
public org.bukkit.command.RemoteConsoleCommandSender remoteConsole;
|
||||
- public ConsoleReader reader;
|
||||
+ //public ConsoleReader reader; // Paper
|
||||
public static int currentTick = 0; // Paper - Further improve tick loop
|
||||
public java.util.Queue<Runnable> processQueue = new java.util.concurrent.ConcurrentLinkedQueue<Runnable>();
|
||||
public int autosavePeriod;
|
||||
@@ -370,7 +370,9 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
this.options = options;
|
||||
this.worldLoader = worldLoader;
|
||||
this.vanillaCommandDispatcher = worldstem.dataPackResources().commands; // CraftBukkit
|
||||
+ // Paper start - Handled by TerminalConsoleAppender
|
||||
// Try to see if we're actually running in a terminal, disable jline if not
|
||||
+ /*
|
||||
if (System.console() == null && System.getProperty("jline.terminal") == null) {
|
||||
System.setProperty("jline.terminal", "jline.UnsupportedTerminal");
|
||||
Main.useJline = false;
|
||||
@@ -391,6 +393,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
MinecraftServer.LOGGER.warn((String) null, ex);
|
||||
}
|
||||
}
|
||||
+ */
|
||||
+ // Paper end
|
||||
Runtime.getRuntime().addShutdownHook(new org.bukkit.craftbukkit.util.ServerShutdownThread(this));
|
||||
this.paperConfigurations = services.paperConfigurations(); // Paper
|
||||
}
|
||||
@@ -1146,7 +1150,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
org.spigotmc.WatchdogThread.doStop(); // Spigot
|
||||
// CraftBukkit start - Restore terminal to original settings
|
||||
try {
|
||||
- this.reader.getTerminal().restore();
|
||||
+ net.minecrell.terminalconsole.TerminalConsoleAppender.close(); // Paper - Use TerminalConsoleAppender
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
// CraftBukkit end
|
||||
@@ -1595,7 +1599,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
|
||||
@Override
|
||||
public void sendSystemMessage(Component message) {
|
||||
- MinecraftServer.LOGGER.info(message.getString());
|
||||
+ MinecraftServer.LOGGER.info(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().serialize(io.papermc.paper.adventure.PaperAdventure.asAdventure(message))); // Paper - Log message with colors
|
||||
}
|
||||
|
||||
public KeyPair getKeyPair() {
|
||||
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
index a9cf8960d487ee71385341285a4b1618007d06dc..95f39630c9b4d2a41d8469d0d53da92e5578c347 100644
|
||||
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
@@ -98,6 +98,9 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
|
||||
if (!org.bukkit.craftbukkit.Main.useConsole) {
|
||||
return;
|
||||
}
|
||||
+ // Paper start - Use TerminalConsoleAppender
|
||||
+ new com.destroystokyo.paper.console.PaperConsole(DedicatedServer.this).start();
|
||||
+ /*
|
||||
jline.console.ConsoleReader bufferedreader = reader;
|
||||
|
||||
// MC-33041, SPIGOT-5538: if System.in is not valid due to javaw, then return
|
||||
@@ -129,7 +132,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
|
||||
continue;
|
||||
}
|
||||
if (s.trim().length() > 0) { // Trim to filter lines which are just spaces
|
||||
- DedicatedServer.this.handleConsoleInput(s, DedicatedServer.this.createCommandSourceStack());
|
||||
+ DedicatedServer.this.issueCommand(s, DedicatedServer.this.getServerCommandListener());
|
||||
}
|
||||
// CraftBukkit end
|
||||
}
|
||||
@@ -137,6 +140,8 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
|
||||
DedicatedServer.LOGGER.error("Exception handling console input", ioexception);
|
||||
}
|
||||
|
||||
+ */
|
||||
+ // Paper end
|
||||
}
|
||||
};
|
||||
|
||||
@@ -148,6 +153,9 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
|
||||
}
|
||||
global.addHandler(new org.bukkit.craftbukkit.util.ForwardLogHandler());
|
||||
|
||||
+ // Paper start - Not needed with TerminalConsoleAppender
|
||||
+ final org.apache.logging.log4j.Logger logger = LogManager.getRootLogger();
|
||||
+ /*
|
||||
final org.apache.logging.log4j.core.Logger logger = ((org.apache.logging.log4j.core.Logger) LogManager.getRootLogger());
|
||||
for (org.apache.logging.log4j.core.Appender appender : logger.getAppenders().values()) {
|
||||
if (appender instanceof org.apache.logging.log4j.core.appender.ConsoleAppender) {
|
||||
@@ -156,6 +164,8 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
|
||||
}
|
||||
|
||||
new org.bukkit.craftbukkit.util.TerminalConsoleWriterThread(System.out, this.reader).start();
|
||||
+ */
|
||||
+ // Paper end
|
||||
|
||||
System.setOut(IoBuilder.forLogger(logger).setLevel(Level.INFO).buildPrintStream());
|
||||
System.setErr(IoBuilder.forLogger(logger).setLevel(Level.WARN).buildPrintStream());
|
||||
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
index d28f662d4a935994525118a403f3dc39cfa81a49..9089a25ce49e7e192f7e1c3de46ffe1f93c69bc5 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
@@ -169,8 +169,7 @@ public abstract class PlayerList {
|
||||
|
||||
public PlayerList(MinecraftServer server, LayeredRegistryAccess<RegistryLayer> registryManager, PlayerDataStorage saveHandler, int maxPlayers) {
|
||||
this.cserver = server.server = new CraftServer((DedicatedServer) server, this);
|
||||
- server.console = org.bukkit.craftbukkit.command.ColouredConsoleSender.getInstance();
|
||||
- server.reader.addCompleter(new org.bukkit.craftbukkit.command.ConsoleCommandCompleter(server.server));
|
||||
+ server.console = new com.destroystokyo.paper.console.TerminalConsoleCommandSender(); // Paper
|
||||
// CraftBukkit end
|
||||
|
||||
this.bans = new UserBanList(PlayerList.USERBANLIST_FILE);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index 12c36e02e271cc8e13b20059fbfb30f4e8172023..adc35bbaa95f852a7ff28eeaa974c30ad4d22baa 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -42,7 +42,6 @@ import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.imageio.ImageIO;
|
||||
-import jline.console.ConsoleReader;
|
||||
import net.minecraft.advancements.Advancement;
|
||||
import net.minecraft.commands.CommandSourceStack;
|
||||
import net.minecraft.commands.Commands;
|
||||
@@ -1303,9 +1302,13 @@ public final class CraftServer implements Server {
|
||||
return this.logger;
|
||||
}
|
||||
|
||||
+ // Paper start - JLine update
|
||||
+ /*
|
||||
public ConsoleReader getReader() {
|
||||
return console.reader;
|
||||
}
|
||||
+ */
|
||||
+ // Paper end
|
||||
|
||||
@Override
|
||||
public PluginCommand getPluginCommand(String name) {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java
|
||||
index b96652b7bcad07c39a81858c1a2c285efbf67905..cb1f050efb85e3b31dba2063fb3a316db1e0430d 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/Main.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/Main.java
|
||||
@@ -13,7 +13,6 @@ import java.util.logging.Logger;
|
||||
import joptsimple.OptionParser;
|
||||
import joptsimple.OptionSet;
|
||||
import joptsimple.util.PathConverter;
|
||||
-import org.fusesource.jansi.AnsiConsole;
|
||||
|
||||
public class Main {
|
||||
public static boolean useJline = true;
|
||||
@@ -219,6 +218,8 @@ public class Main {
|
||||
}
|
||||
|
||||
try {
|
||||
+ // Paper start - Handled by TerminalConsoleAppender
|
||||
+ /*
|
||||
// This trick bypasses Maven Shade's clever rewriting of our getProperty call when using String literals
|
||||
String jline_UnsupportedTerminal = new String(new char[]{'j', 'l', 'i', 'n', 'e', '.', 'U', 'n', 's', 'u', 'p', 'p', 'o', 'r', 't', 'e', 'd', 'T', 'e', 'r', 'm', 'i', 'n', 'a', 'l'});
|
||||
String jline_terminal = new String(new char[]{'j', 'l', 'i', 'n', 'e', '.', 't', 'e', 'r', 'm', 'i', 'n', 'a', 'l'});
|
||||
@@ -236,9 +237,18 @@ public class Main {
|
||||
// This ensures the terminal literal will always match the jline implementation
|
||||
System.setProperty(jline.TerminalFactory.JLINE_TERMINAL, jline.UnsupportedTerminal.class.getName());
|
||||
}
|
||||
+ */
|
||||
+
|
||||
+ if (options.has("nojline")) {
|
||||
+ System.setProperty(net.minecrell.terminalconsole.TerminalConsoleAppender.JLINE_OVERRIDE_PROPERTY, "false");
|
||||
+ useJline = false;
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
if (options.has("noconsole")) {
|
||||
Main.useConsole = false;
|
||||
+ useJline = false; // Paper
|
||||
+ System.setProperty(net.minecrell.terminalconsole.TerminalConsoleAppender.JLINE_OVERRIDE_PROPERTY, "false"); // Paper
|
||||
}
|
||||
|
||||
if (Main.class.getPackage().getImplementationVendor() != null && System.getProperty("IReallyKnowWhatIAmDoingISwear") == null) {
|
||||
@@ -266,7 +276,7 @@ public class Main {
|
||||
System.out.println("Unable to read system info");
|
||||
}
|
||||
// Paper end
|
||||
-
|
||||
+ System.setProperty( "library.jansi.version", "Paper" ); // Paper - set meaningless jansi version to prevent git builds from crashing on Windows
|
||||
System.out.println("Loading libraries, please wait...");
|
||||
net.minecraft.server.Main.main(options);
|
||||
} catch (Throwable t) {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/command/ColouredConsoleSender.java b/src/main/java/org/bukkit/craftbukkit/command/ColouredConsoleSender.java
|
||||
index 76fb1ecd47cb86b50486effe8cc7fe4abf8e311c..21f889ddec72b40f5954eec07417e08d192b4661 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/command/ColouredConsoleSender.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/command/ColouredConsoleSender.java
|
||||
@@ -5,15 +5,13 @@ import java.util.EnumMap;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
-import jline.Terminal;
|
||||
+//import jline.Terminal;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.ConsoleCommandSender;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
-import org.fusesource.jansi.Ansi;
|
||||
-import org.fusesource.jansi.Ansi.Attribute;
|
||||
|
||||
-public class ColouredConsoleSender extends CraftConsoleCommandSender {
|
||||
+public class ColouredConsoleSender /*extends CraftConsoleCommandSender */{/* // Paper - disable
|
||||
private final Terminal terminal;
|
||||
private final Map<ChatColor, String> replacements = new EnumMap<ChatColor, String>(ChatColor.class);
|
||||
private final ChatColor[] colors = ChatColor.values();
|
||||
@@ -93,5 +91,5 @@ public class ColouredConsoleSender extends CraftConsoleCommandSender {
|
||||
} else {
|
||||
return new ColouredConsoleSender();
|
||||
}
|
||||
- }
|
||||
+ }*/ // Paper
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/command/ConsoleCommandCompleter.java b/src/main/java/org/bukkit/craftbukkit/command/ConsoleCommandCompleter.java
|
||||
index 0b4c62387c1093652ac15b64a8703249de4cf088..b996fde481cebbbcce80a6c267591136db7cc0bc 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/command/ConsoleCommandCompleter.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/command/ConsoleCommandCompleter.java
|
||||
@@ -4,50 +4,73 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.logging.Level;
|
||||
-import jline.console.completer.Completer;
|
||||
+import net.minecraft.server.dedicated.DedicatedServer;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.craftbukkit.util.Waitable;
|
||||
+
|
||||
+// Paper start - JLine update
|
||||
+import org.jline.reader.Candidate;
|
||||
+import org.jline.reader.Completer;
|
||||
+import org.jline.reader.LineReader;
|
||||
+import org.jline.reader.ParsedLine;
|
||||
+// Paper end
|
||||
import org.bukkit.event.server.TabCompleteEvent;
|
||||
|
||||
public class ConsoleCommandCompleter implements Completer {
|
||||
- private final CraftServer server;
|
||||
+ private final DedicatedServer server; // Paper - CraftServer -> DedicatedServer
|
||||
|
||||
- public ConsoleCommandCompleter(CraftServer server) {
|
||||
+ public ConsoleCommandCompleter(DedicatedServer server) { // Paper - CraftServer -> DedicatedServer
|
||||
this.server = server;
|
||||
}
|
||||
|
||||
+ // Paper start - Change method signature for JLine update
|
||||
@Override
|
||||
- public int complete(final String buffer, final int cursor, final List<CharSequence> candidates) {
|
||||
+ public void complete(LineReader reader, ParsedLine line, List<Candidate> candidates) {
|
||||
+ final CraftServer server = this.server.server;
|
||||
+ final String buffer = line.line();
|
||||
+ // Paper end
|
||||
Waitable<List<String>> waitable = new Waitable<List<String>>() {
|
||||
@Override
|
||||
protected List<String> evaluate() {
|
||||
- List<String> offers = ConsoleCommandCompleter.this.server.getCommandMap().tabComplete(ConsoleCommandCompleter.this.server.getConsoleSender(), buffer);
|
||||
+ List<String> offers = server.getCommandMap().tabComplete(server.getConsoleSender(), buffer); // Paper - fix remap
|
||||
|
||||
- TabCompleteEvent tabEvent = new TabCompleteEvent(ConsoleCommandCompleter.this.server.getConsoleSender(), buffer, (offers == null) ? Collections.EMPTY_LIST : offers);
|
||||
- ConsoleCommandCompleter.this.server.getPluginManager().callEvent(tabEvent);
|
||||
+ TabCompleteEvent tabEvent = new TabCompleteEvent(server.getConsoleSender(), buffer, (offers == null) ? Collections.EMPTY_LIST : offers); // Paper - fix remap
|
||||
+ server.getPluginManager().callEvent(tabEvent); // Paper - fix remap
|
||||
|
||||
return tabEvent.isCancelled() ? Collections.EMPTY_LIST : tabEvent.getCompletions();
|
||||
}
|
||||
};
|
||||
- this.server.getServer().processQueue.add(waitable);
|
||||
+ server.getServer().processQueue.add(waitable); // Paper - Remove "this."
|
||||
try {
|
||||
List<String> offers = waitable.get();
|
||||
if (offers == null) {
|
||||
- return cursor;
|
||||
+ return; // Paper - Method returns void
|
||||
+ }
|
||||
+
|
||||
+ // Paper start - JLine update
|
||||
+ for (String completion : offers) {
|
||||
+ if (completion.isEmpty()) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ candidates.add(new Candidate(completion));
|
||||
}
|
||||
- candidates.addAll(offers);
|
||||
+ // Paper end
|
||||
|
||||
+ // Paper start - JLine handles cursor now
|
||||
+ /*
|
||||
final int lastSpace = buffer.lastIndexOf(' ');
|
||||
if (lastSpace == -1) {
|
||||
return cursor - buffer.length();
|
||||
} else {
|
||||
return cursor - (buffer.length() - lastSpace - 1);
|
||||
}
|
||||
+ */
|
||||
+ // Paper end
|
||||
} catch (ExecutionException e) {
|
||||
- this.server.getLogger().log(Level.WARNING, "Unhandled exception when tab completing", e);
|
||||
+ server.getLogger().log(Level.WARNING, "Unhandled exception when tab completing", e); // Paper - Remove "this."
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
- return cursor;
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/util/ServerShutdownThread.java b/src/main/java/org/bukkit/craftbukkit/util/ServerShutdownThread.java
|
||||
index 6a073a9dc44d93eba296a0e18a9c7be8a7881725..b4a19d80bbf71591f25729fd0e98590350cb31d0 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/util/ServerShutdownThread.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/util/ServerShutdownThread.java
|
||||
@@ -17,7 +17,7 @@ public class ServerShutdownThread extends Thread {
|
||||
this.server.close();
|
||||
} finally {
|
||||
try {
|
||||
- server.reader.getTerminal().restore();
|
||||
+ net.minecrell.terminalconsole.TerminalConsoleAppender.close(); // Paper - Use TerminalConsoleAppender
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/util/TerminalConsoleWriterThread.java b/src/main/java/org/bukkit/craftbukkit/util/TerminalConsoleWriterThread.java
|
||||
index 1d8b279f3cbe6fde6bb1bfc4985c4133b0d4a95d..cdc52bbe5c6ae4688615a7732b10071f7f51718e 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/util/TerminalConsoleWriterThread.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/util/TerminalConsoleWriterThread.java
|
||||
@@ -5,12 +5,12 @@ import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
-import jline.console.ConsoleReader;
|
||||
+//import jline.console.ConsoleReader;
|
||||
import org.bukkit.craftbukkit.Main;
|
||||
-import org.fusesource.jansi.Ansi;
|
||||
-import org.fusesource.jansi.Ansi.Erase;
|
||||
+//import org.fusesource.jansi.Ansi;
|
||||
+//import org.fusesource.jansi.Ansi.Erase;
|
||||
|
||||
-public class TerminalConsoleWriterThread extends Thread {
|
||||
+public class TerminalConsoleWriterThread /*extends Thread*/ {/* // Paper - disable
|
||||
private final ConsoleReader reader;
|
||||
private final OutputStream output;
|
||||
|
||||
@@ -54,5 +54,5 @@ public class TerminalConsoleWriterThread extends Thread {
|
||||
Logger.getLogger(TerminalConsoleWriterThread.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
- }
|
||||
+ }*/
|
||||
}
|
||||
diff --git a/src/main/resources/log4j2.component.properties b/src/main/resources/log4j2.component.properties
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0694b21465fb9e4164e71862ff24b62241b191f2
|
||||
--- /dev/null
|
||||
+++ b/src/main/resources/log4j2.component.properties
|
||||
@@ -0,0 +1 @@
|
||||
+log4j.skipJansi=true
|
||||
diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml
|
||||
index 722ca84968cbbbdeffd09939abff0cccd0a84010..620b9490e5f159080e50289d127404a1b56adbef 100644
|
||||
--- a/src/main/resources/log4j2.xml
|
||||
+++ b/src/main/resources/log4j2.xml
|
||||
@@ -1,17 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Configuration status="WARN" packages="com.mojang.util">
|
||||
<Appenders>
|
||||
- <Console name="SysOut" target="SYSTEM_OUT">
|
||||
- <PatternLayout pattern="[%d{HH:mm:ss}] [%t/%level]: %msg%n" />
|
||||
- </Console>
|
||||
<Queue name="ServerGuiConsole">
|
||||
<PatternLayout pattern="[%d{HH:mm:ss} %level]: %msg%n" />
|
||||
</Queue>
|
||||
- <Queue name="TerminalConsole">
|
||||
- <PatternLayout pattern="[%d{HH:mm:ss}] [%t/%level]: %msg%n" />
|
||||
- </Queue>
|
||||
+ <TerminalConsole name="TerminalConsole">
|
||||
+ <PatternLayout pattern="%highlightError{[%d{HH:mm:ss} %level]: %minecraftFormatting{%msg}%n%xEx}" />
|
||||
+ </TerminalConsole>
|
||||
<RollingRandomAccessFile name="File" fileName="logs/latest.log" filePattern="logs/%d{yyyy-MM-dd}-%i.log.gz">
|
||||
- <PatternLayout pattern="[%d{HH:mm:ss}] [%t/%level]: %msg%n" />
|
||||
+ <PatternLayout pattern="[%d{HH:mm:ss}] [%t/%level]: %minecraftFormatting{%msg}{strip}%n" />
|
||||
<Policies>
|
||||
<TimeBasedTriggeringPolicy />
|
||||
<OnStartupTriggeringPolicy />
|
||||
@@ -24,10 +21,9 @@
|
||||
<filters>
|
||||
<MarkerFilter marker="NETWORK_PACKETS" onMatch="DENY" onMismatch="NEUTRAL" />
|
||||
</filters>
|
||||
- <AppenderRef ref="SysOut" level="info"/>
|
||||
<AppenderRef ref="File"/>
|
||||
- <AppenderRef ref="ServerGuiConsole" level="info"/>
|
||||
<AppenderRef ref="TerminalConsole" level="info"/>
|
||||
+ <AppenderRef ref="ServerGuiConsole" level="info"/>
|
||||
</Root>
|
||||
</Loggers>
|
||||
</Configuration>
|
|
@ -0,0 +1,20 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shane Freeder <theboyetronic@gmail.com>
|
||||
Date: Sun, 11 Jun 2017 21:01:18 +0100
|
||||
Subject: [PATCH] provide a configurable option to disable creeper lingering
|
||||
effect spawns
|
||||
|
||||
|
||||
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 6bd17e28b2f081aa84e4aca138eb56a4c00d57f6..b1e583ff4c1a9019be2f5d037bb04e7ebcbe9ae5 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Creeper.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Creeper.java
|
||||
@@ -285,7 +285,7 @@ public class Creeper extends Monster implements PowerableMob {
|
||||
private void spawnLingeringCloud() {
|
||||
Collection<MobEffectInstance> collection = this.getActiveEffects();
|
||||
|
||||
- if (!collection.isEmpty()) {
|
||||
+ if (!collection.isEmpty() && !this.level().paperConfig().entities.behavior.disableCreeperLingeringEffect) { // Paper
|
||||
AreaEffectCloud entityareaeffectcloud = new AreaEffectCloud(this.level(), this.getX(), this.getY(), this.getZ());
|
||||
|
||||
entityareaeffectcloud.setOwner(this); // CraftBukkit
|
57
patches/server/0134-Item-canEntityPickup.patch
Normal file
57
patches/server/0134-Item-canEntityPickup.patch
Normal file
|
@ -0,0 +1,57 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Fri, 5 May 2017 03:57:17 -0500
|
||||
Subject: [PATCH] Item#canEntityPickup
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java
|
||||
index 2dc21048b968e7aa63b5b28cacdd1ae407c06958..fec33a79fc9681ef51899a92ebb43c27126bd7ac 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Mob.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Mob.java
|
||||
@@ -668,6 +668,11 @@ public abstract class Mob extends LivingEntity implements Targeting {
|
||||
ItemEntity entityitem = (ItemEntity) iterator.next();
|
||||
|
||||
if (!entityitem.isRemoved() && !entityitem.getItem().isEmpty() && !entityitem.hasPickUpDelay() && this.wantsToPickUp(entityitem.getItem())) {
|
||||
+ // Paper Start
|
||||
+ if (!entityitem.canMobPickup) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ // Paper End
|
||||
this.pickUpItem(entityitem);
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java
|
||||
index dbe07ffbc6310828370be69081ac6d6f3085e4ac..1503d143429f0b73935004a7061d0409dcb24c2c 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java
|
||||
@@ -51,6 +51,7 @@ public class ItemEntity extends Entity implements TraceableEntity {
|
||||
public UUID target;
|
||||
public final float bobOffs;
|
||||
private int lastTick = MinecraftServer.currentTick - 1; // CraftBukkit
|
||||
+ public boolean canMobPickup = true; // Paper
|
||||
|
||||
public ItemEntity(EntityType<? extends ItemEntity> type, Level world) {
|
||||
super(type, world);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java
|
||||
index d08869c92f15a63f857d88e506f744f5ff9eb15e..5f36b0fd12ccd0e7ec9a7f61c56f08307844935f 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java
|
||||
@@ -66,6 +66,18 @@ public class CraftItem extends CraftEntity implements Item {
|
||||
}
|
||||
}
|
||||
|
||||
+ // Paper Start
|
||||
+ @Override
|
||||
+ public boolean canMobPickup() {
|
||||
+ return item.canMobPickup;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setCanMobPickup(boolean canMobPickup) {
|
||||
+ item.canMobPickup = canMobPickup;
|
||||
+ }
|
||||
+ // Paper End
|
||||
+
|
||||
@Override
|
||||
public void setOwner(UUID uuid) {
|
||||
this.item.setTarget(uuid);
|
|
@ -0,0 +1,41 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Sun, 7 May 2017 06:26:09 -0500
|
||||
Subject: [PATCH] PlayerPickupItemEvent#setFlyAtPlayer
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java
|
||||
index 1503d143429f0b73935004a7061d0409dcb24c2c..8357ef35c374c6a6602eb96d4281da0210aea757 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java
|
||||
@@ -399,6 +399,7 @@ public class ItemEntity extends Entity implements TraceableEntity {
|
||||
// CraftBukkit start - fire PlayerPickupItemEvent
|
||||
int canHold = player.getInventory().canHold(itemstack);
|
||||
int remaining = i - canHold;
|
||||
+ boolean flyAtPlayer = false; // Paper
|
||||
|
||||
if (this.pickupDelay <= 0 && canHold > 0) {
|
||||
itemstack.setCount(canHold);
|
||||
@@ -406,8 +407,14 @@ public class ItemEntity extends Entity implements TraceableEntity {
|
||||
PlayerPickupItemEvent playerEvent = new PlayerPickupItemEvent((org.bukkit.entity.Player) player.getBukkitEntity(), (org.bukkit.entity.Item) this.getBukkitEntity(), remaining);
|
||||
playerEvent.setCancelled(!playerEvent.getPlayer().getCanPickupItems());
|
||||
this.level().getCraftServer().getPluginManager().callEvent(playerEvent);
|
||||
+ flyAtPlayer = playerEvent.getFlyAtPlayer(); // Paper
|
||||
if (playerEvent.isCancelled()) {
|
||||
itemstack.setCount(i); // SPIGOT-5294 - restore count
|
||||
+ // Paper Start
|
||||
+ if (flyAtPlayer) {
|
||||
+ player.take(this, i);
|
||||
+ }
|
||||
+ // Paper End
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -437,6 +444,7 @@ public class ItemEntity extends Entity implements TraceableEntity {
|
||||
// CraftBukkit end
|
||||
|
||||
if (this.pickupDelay == 0 && (this.target == null || this.target.equals(player.getUUID())) && player.getInventory().add(itemstack)) {
|
||||
+ if (flyAtPlayer) // Paper
|
||||
player.take(this, i);
|
||||
if (itemstack.isEmpty()) {
|
||||
this.discard();
|
41
patches/server/0136-PlayerAttemptPickupItemEvent.patch
Normal file
41
patches/server/0136-PlayerAttemptPickupItemEvent.patch
Normal file
|
@ -0,0 +1,41 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Sun, 11 Jun 2017 16:30:30 -0500
|
||||
Subject: [PATCH] PlayerAttemptPickupItemEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java
|
||||
index 8357ef35c374c6a6602eb96d4281da0210aea757..04b4c7af20d6aa9924fb1d345f11cb51dcadc708 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java
|
||||
@@ -35,6 +35,7 @@ import net.minecraft.stats.Stats;
|
||||
import org.bukkit.event.entity.EntityPickupItemEvent;
|
||||
import org.bukkit.event.player.PlayerPickupItemEvent;
|
||||
// CraftBukkit end
|
||||
+import org.bukkit.event.player.PlayerAttemptPickupItemEvent; // Paper
|
||||
|
||||
public class ItemEntity extends Entity implements TraceableEntity {
|
||||
|
||||
@@ -401,6 +402,22 @@ public class ItemEntity extends Entity implements TraceableEntity {
|
||||
int remaining = i - canHold;
|
||||
boolean flyAtPlayer = false; // Paper
|
||||
|
||||
+ // Paper start
|
||||
+ if (this.pickupDelay <= 0) {
|
||||
+ PlayerAttemptPickupItemEvent attemptEvent = new PlayerAttemptPickupItemEvent((org.bukkit.entity.Player) player.getBukkitEntity(), (org.bukkit.entity.Item) this.getBukkitEntity(), remaining);
|
||||
+ this.level.getCraftServer().getPluginManager().callEvent(attemptEvent);
|
||||
+
|
||||
+ flyAtPlayer = attemptEvent.getFlyAtPlayer();
|
||||
+ if (attemptEvent.isCancelled()) {
|
||||
+ if (flyAtPlayer) {
|
||||
+ player.take(this, i);
|
||||
+ }
|
||||
+
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
if (this.pickupDelay <= 0 && canHold > 0) {
|
||||
itemstack.setCount(canHold);
|
||||
// Call legacy event
|
Loading…
Add table
Add a link
Reference in a new issue