More work
This commit is contained in:
parent
afb9e818fc
commit
08828fde02
281 changed files with 457 additions and 472 deletions
|
@ -1,38 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Fri, 18 Mar 2016 13:17:38 -0400
|
||||
Subject: [PATCH] Default loading permissions.yml before plugins
|
||||
|
||||
Under previous behavior, plugins were not able to check if a player had a permission
|
||||
if it was defined in permissions.yml. there is no clean way for a plugin to fix that either.
|
||||
|
||||
This will change the order so that by default, permissions.yml loads BEFORE plugins instead of after.
|
||||
|
||||
This gives plugins expected permission checks.
|
||||
|
||||
It also helps improve the expected logic, as servers should set the initial defaults, and then let plugins
|
||||
modify that. Under the previous logic, plugins were unable (cleanly) override permissions.yml.
|
||||
|
||||
A config option has been added for those who depend on the previous behavior, but I don't expect that.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index 3dc04ad966c9f44f62af918c50ff1e8ed461fe3b..9f9d2c32d184a9ef7f2fbdef85129654b43cf3ab 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -460,6 +460,7 @@ public final class CraftServer implements Server {
|
||||
if (type == PluginLoadOrder.STARTUP) {
|
||||
this.helpMap.clear();
|
||||
this.helpMap.initializeGeneralTopics();
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().misc.loadPermissionsYmlBeforePlugins) loadCustomPermissions(); // Paper
|
||||
}
|
||||
|
||||
Plugin[] plugins = this.pluginManager.getPlugins();
|
||||
@@ -479,7 +480,7 @@ public final class CraftServer implements Server {
|
||||
this.commandMap.registerServerAliases();
|
||||
DefaultPermissions.registerCorePermissions();
|
||||
CraftDefaultPermissions.registerCorePermissions();
|
||||
- this.loadCustomPermissions();
|
||||
+ if (!io.papermc.paper.configuration.GlobalConfiguration.get().misc.loadPermissionsYmlBeforePlugins) this.loadCustomPermissions(); // Paper
|
||||
this.helpMap.initializeCommands();
|
||||
this.syncCommands();
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: William <admin@domnian.com>
|
||||
Date: Fri, 18 Mar 2016 03:30:17 -0400
|
||||
Subject: [PATCH] Allow Reloading of Custom Permissions
|
||||
|
||||
https://github.com/PaperMC/Paper/issues/49
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index 9f9d2c32d184a9ef7f2fbdef85129654b43cf3ab..bb90cb49fc2b4bb4034d43d16eee61643773ecfa 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -2530,5 +2530,23 @@ public final class CraftServer implements Server {
|
||||
}
|
||||
return this.adventure$audiences;
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public void reloadPermissions() {
|
||||
+ pluginManager.clearPermissions();
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().misc.loadPermissionsYmlBeforePlugins) loadCustomPermissions();
|
||||
+ for (Plugin plugin : pluginManager.getPlugins()) {
|
||||
+ for (Permission perm : plugin.getDescription().getPermissions()) {
|
||||
+ try {
|
||||
+ pluginManager.addPermission(perm);
|
||||
+ } catch (IllegalArgumentException ex) {
|
||||
+ getLogger().log(Level.WARNING, "Plugin " + plugin.getDescription().getFullName() + " tried to register permission '" + perm.getName() + "' but it's already registered", ex);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ if (!io.papermc.paper.configuration.GlobalConfiguration.get().misc.loadPermissionsYmlBeforePlugins) loadCustomPermissions();
|
||||
+ DefaultPermissions.registerCorePermissions();
|
||||
+ CraftDefaultPermissions.registerCorePermissions();
|
||||
+ }
|
||||
// Paper end
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Fri, 18 Mar 2016 13:50:14 -0400
|
||||
Subject: [PATCH] Remove Metadata on reload
|
||||
|
||||
Metadata is not meant to persist reload as things break badly with non primitive types
|
||||
This will remove metadata on reload so it does not crash everything if a plugin uses it.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index bb90cb49fc2b4bb4034d43d16eee61643773ecfa..aa6a40eae3a3897ab3cca93921635e4e3e37db9f 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -948,8 +948,16 @@ public final class CraftServer implements Server {
|
||||
world.spigotConfig.init(); // Spigot
|
||||
}
|
||||
|
||||
+ Plugin[] pluginClone = pluginManager.getPlugins().clone(); // Paper
|
||||
this.pluginManager.clearPlugins();
|
||||
this.commandMap.clearCommands();
|
||||
+ // Paper start
|
||||
+ for (Plugin plugin : pluginClone) {
|
||||
+ entityMetadata.removeAll(plugin);
|
||||
+ worldMetadata.removeAll(plugin);
|
||||
+ playerMetadata.removeAll(plugin);
|
||||
+ }
|
||||
+ // Paper end
|
||||
this.reloadData();
|
||||
org.spigotmc.SpigotConfig.registerCommands(); // Spigot
|
||||
io.papermc.paper.command.PaperCommands.registerCommands(this.console); // Paper
|
|
@ -1,331 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Thu, 28 May 2015 23:00:19 -0400
|
||||
Subject: [PATCH] Handle Item Meta Inconsistencies
|
||||
|
||||
First, Enchantment order would blow away seeing 2 items as the same,
|
||||
however the Client forces enchantment list in a certain order, as well
|
||||
as does the /enchant command. Anvils can insert it into forced order,
|
||||
causing 2 same items to be considered different.
|
||||
|
||||
This change makes unhandled NBT Tags and Enchantments use a sorted tree map,
|
||||
so they will always be in a consistent order.
|
||||
|
||||
Additionally, the old enchantment API was never updated when ItemMeta
|
||||
was added, resulting in 2 different ways to modify an items enchantments.
|
||||
|
||||
For consistency, the old API methods now forward to use the
|
||||
ItemMeta API equivalents, and should deprecate the old API's.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
index 7f778e037c1821cc45236bf2a95c28243d0ec126..758f0a620551838e32d5c68f7ee755f7ea374a46 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
@@ -151,6 +151,23 @@ public final class ItemStack {
|
||||
return this.getItem().getTooltipImage(this);
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ private static final java.util.Comparator<? super CompoundTag> enchantSorter = java.util.Comparator.comparing(o -> o.getString("id"));
|
||||
+ private void processEnchantOrder(@Nullable CompoundTag tag) {
|
||||
+ if (tag == null || !tag.contains("Enchantments", 9)) {
|
||||
+ return;
|
||||
+ }
|
||||
+ ListTag list = tag.getList("Enchantments", 10);
|
||||
+ if (list.size() < 2) {
|
||||
+ return;
|
||||
+ }
|
||||
+ try {
|
||||
+ //noinspection unchecked
|
||||
+ list.sort((java.util.Comparator<? super net.minecraft.nbt.Tag>) enchantSorter); // Paper
|
||||
+ } catch (Exception ignored) {}
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
public ItemStack(ItemLike item) {
|
||||
this(item, 1);
|
||||
}
|
||||
@@ -202,6 +219,7 @@ public final class ItemStack {
|
||||
// CraftBukkit start - make defensive copy as this data may be coming from the save thread
|
||||
this.tag = nbttagcompound.getCompound("tag").copy();
|
||||
// CraftBukkit end
|
||||
+ this.processEnchantOrder(this.tag); // Paper
|
||||
this.getItem().verifyTagAfterLoad(this.tag);
|
||||
}
|
||||
|
||||
@@ -772,6 +790,7 @@ public final class ItemStack {
|
||||
|
||||
public void setTag(@Nullable CompoundTag nbt) {
|
||||
this.tag = nbt;
|
||||
+ this.processEnchantOrder(this.tag); // Paper
|
||||
if (this.getItem().canBeDepleted()) {
|
||||
this.setDamageValue(this.getDamageValue());
|
||||
}
|
||||
@@ -1061,6 +1080,7 @@ public final class ItemStack {
|
||||
ListTag nbttaglist = this.tag.getList("Enchantments", 10);
|
||||
|
||||
nbttaglist.add(EnchantmentHelper.storeEnchantment(EnchantmentHelper.getEnchantmentId(enchantment), (byte) level));
|
||||
+ processEnchantOrder(this.tag); // Paper
|
||||
}
|
||||
|
||||
public boolean isEnchanted() {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
index 4b79b96579efbc4dd9a10e7183ed08b73b488794..3745033afb8923ce06cbf13b55c4e96f2a89573f 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
@@ -6,7 +6,6 @@ import java.util.Map;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import net.minecraft.world.item.Item;
|
||||
-import net.minecraft.world.item.enchantment.EnchantmentHelper;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
@@ -178,28 +177,11 @@ public final class CraftItemStack extends ItemStack {
|
||||
public void addUnsafeEnchantment(Enchantment ench, int level) {
|
||||
Validate.notNull(ench, "Cannot add null enchantment");
|
||||
|
||||
- if (!CraftItemStack.makeTag(this.handle)) {
|
||||
- return;
|
||||
- }
|
||||
- ListTag list = CraftItemStack.getEnchantmentList(this.handle);
|
||||
- if (list == null) {
|
||||
- list = new ListTag();
|
||||
- this.handle.getTag().put(ENCHANTMENTS.NBT, list);
|
||||
- }
|
||||
- int size = list.size();
|
||||
-
|
||||
- for (int i = 0; i < size; i++) {
|
||||
- CompoundTag tag = (CompoundTag) list.get(i);
|
||||
- String id = tag.getString(ENCHANTMENTS_ID.NBT);
|
||||
- if (ench.getKey().equals(NamespacedKey.fromString(id))) {
|
||||
- tag.putShort(ENCHANTMENTS_LVL.NBT, (short) level);
|
||||
- return;
|
||||
- }
|
||||
- }
|
||||
- CompoundTag tag = new CompoundTag();
|
||||
- tag.putString(ENCHANTMENTS_ID.NBT, ench.getKey().toString());
|
||||
- tag.putShort(ENCHANTMENTS_LVL.NBT, (short) level);
|
||||
- list.add(tag);
|
||||
+ // Paper start - Replace whole method
|
||||
+ final ItemMeta itemMeta = this.getItemMeta();
|
||||
+ itemMeta.addEnchant(ench, level, true);
|
||||
+ this.setItemMeta(itemMeta);
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
static boolean makeTag(net.minecraft.world.item.ItemStack item) {
|
||||
@@ -216,66 +198,34 @@ public final class CraftItemStack extends ItemStack {
|
||||
|
||||
@Override
|
||||
public boolean containsEnchantment(Enchantment ench) {
|
||||
- return this.getEnchantmentLevel(ench) > 0;
|
||||
+ return this.hasItemMeta() && this.getItemMeta().hasEnchant(ench); // Paper - use meta
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEnchantmentLevel(Enchantment ench) {
|
||||
- Validate.notNull(ench, "Cannot find null enchantment");
|
||||
- if (this.handle == null) {
|
||||
- return 0;
|
||||
- }
|
||||
- return EnchantmentHelper.getItemEnchantmentLevel(CraftEnchantment.getRaw(ench), handle);
|
||||
+ return this.hasItemMeta() ? this.getItemMeta().getEnchantLevel(ench) : 0; // Paper - replace entire method with meta
|
||||
}
|
||||
|
||||
@Override
|
||||
public int removeEnchantment(Enchantment ench) {
|
||||
Validate.notNull(ench, "Cannot remove null enchantment");
|
||||
|
||||
- ListTag list = CraftItemStack.getEnchantmentList(this.handle), listCopy;
|
||||
- if (list == null) {
|
||||
- return 0;
|
||||
- }
|
||||
- int index = Integer.MIN_VALUE;
|
||||
- int level = Integer.MIN_VALUE;
|
||||
- int size = list.size();
|
||||
-
|
||||
- for (int i = 0; i < size; i++) {
|
||||
- CompoundTag enchantment = (CompoundTag) list.get(i);
|
||||
- String id = enchantment.getString(ENCHANTMENTS_ID.NBT);
|
||||
- if (ench.getKey().equals(NamespacedKey.fromString(id))) {
|
||||
- index = i;
|
||||
- level = 0xffff & enchantment.getShort(ENCHANTMENTS_LVL.NBT);
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- if (index == Integer.MIN_VALUE) {
|
||||
- return 0;
|
||||
- }
|
||||
- if (size == 1) {
|
||||
- this.handle.getTag().remove(ENCHANTMENTS.NBT);
|
||||
- if (this.handle.getTag().isEmpty()) {
|
||||
- this.handle.setTag(null);
|
||||
- }
|
||||
- return level;
|
||||
- }
|
||||
-
|
||||
- // This is workaround for not having an index removal
|
||||
- listCopy = new ListTag();
|
||||
- for (int i = 0; i < size; i++) {
|
||||
- if (i != index) {
|
||||
- listCopy.add(list.get(i));
|
||||
- }
|
||||
+ // Paper start - replace entire method
|
||||
+ final ItemMeta itemMeta = this.getItemMeta();
|
||||
+ if (itemMeta == null) return 0;
|
||||
+ int level = itemMeta.getEnchantLevel(ench);
|
||||
+ if (level > 0) {
|
||||
+ itemMeta.removeEnchant(ench);
|
||||
+ this.setItemMeta(itemMeta);
|
||||
}
|
||||
- this.handle.getTag().put(ENCHANTMENTS.NBT, listCopy);
|
||||
+ // Paper end
|
||||
|
||||
return level;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Enchantment, Integer> getEnchantments() {
|
||||
- return CraftItemStack.getEnchantments(this.handle);
|
||||
+ return this.hasItemMeta() ? this.getItemMeta().getEnchants() : ImmutableMap.<Enchantment, Integer>of(); // Paper - use Item Meta
|
||||
}
|
||||
|
||||
static Map<Enchantment, Integer> getEnchantments(net.minecraft.world.item.ItemStack item) {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
||||
index 0a5f063bc74e1dae67167537437ebd7e4ddf113a..4d687fa31f4d889ac755c178b9afd2b927c78ee2 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
||||
@@ -6,6 +6,7 @@ import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
import com.google.common.collect.LinkedHashMultimap;
|
||||
+import com.google.common.collect.ImmutableSortedMap; // Paper
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.SetMultimap;
|
||||
@@ -23,6 +24,7 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
import java.util.Collection;
|
||||
+import java.util.Comparator; // Paper
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
@@ -33,6 +35,7 @@ import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
+import java.util.TreeMap; // Paper
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.annotation.Nonnull;
|
||||
@@ -272,7 +275,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
|
||||
private List<String> lore; // null and empty are two different states internally
|
||||
private Integer customModelData;
|
||||
private CompoundTag blockData;
|
||||
- private Map<Enchantment, Integer> enchantments;
|
||||
+ private EnchantmentMap enchantments; // Paper
|
||||
private Multimap<Attribute, AttributeModifier> attributeModifiers;
|
||||
private int repairCost;
|
||||
private int hideFlag;
|
||||
@@ -283,7 +286,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
|
||||
private static final CraftPersistentDataTypeRegistry DATA_TYPE_REGISTRY = new CraftPersistentDataTypeRegistry();
|
||||
|
||||
private CompoundTag internalTag;
|
||||
- final Map<String, Tag> unhandledTags = new HashMap<String, Tag>(); // Visible for testing only
|
||||
+ final Map<String, Tag> unhandledTags = new TreeMap<String, Tag>(); // Visible for testing only // Paper
|
||||
private CraftPersistentDataContainer persistentDataContainer = new CraftPersistentDataContainer(CraftMetaItem.DATA_TYPE_REGISTRY);
|
||||
|
||||
private int version = CraftMagicNumbers.INSTANCE.getDataVersion(); // Internal use only
|
||||
@@ -304,7 +307,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
|
||||
this.blockData = meta.blockData;
|
||||
|
||||
if (meta.enchantments != null) { // Spigot
|
||||
- this.enchantments = new LinkedHashMap<Enchantment, Integer>(meta.enchantments);
|
||||
+ this.enchantments = new EnchantmentMap(meta.enchantments); // Paper
|
||||
}
|
||||
|
||||
if (meta.hasAttributeModifiers()) {
|
||||
@@ -387,13 +390,13 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
|
||||
}
|
||||
}
|
||||
|
||||
- static Map<Enchantment, Integer> buildEnchantments(CompoundTag tag, ItemMetaKey key) {
|
||||
+ static EnchantmentMap buildEnchantments(CompoundTag tag, ItemMetaKey key) { // Paper
|
||||
if (!tag.contains(key.NBT)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ListTag ench = tag.getList(key.NBT, CraftMagicNumbers.NBT.TAG_COMPOUND);
|
||||
- Map<Enchantment, Integer> enchantments = new LinkedHashMap<Enchantment, Integer>(ench.size());
|
||||
+ EnchantmentMap enchantments = new EnchantmentMap(); // Paper
|
||||
|
||||
for (int i = 0; i < ench.size(); i++) {
|
||||
String id = ((CompoundTag) ench.get(i)).getString(ENCHANTMENTS_ID.NBT);
|
||||
@@ -546,13 +549,13 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
|
||||
}
|
||||
}
|
||||
|
||||
- static Map<Enchantment, Integer> buildEnchantments(Map<String, Object> map, ItemMetaKey key) {
|
||||
+ static EnchantmentMap buildEnchantments(Map<String, Object> map, ItemMetaKey key) { // Paper
|
||||
Map<?, ?> ench = SerializableMeta.getObject(Map.class, map, key.BUKKIT, true);
|
||||
if (ench == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
- Map<Enchantment, Integer> enchantments = new LinkedHashMap<Enchantment, Integer>(ench.size());
|
||||
+ EnchantmentMap enchantments = new EnchantmentMap(); // Paper
|
||||
for (Map.Entry<?, ?> entry : ench.entrySet()) {
|
||||
// Doctor older enchants
|
||||
String enchantKey = entry.getKey().toString();
|
||||
@@ -828,14 +831,14 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
|
||||
|
||||
@Override
|
||||
public Map<Enchantment, Integer> getEnchants() {
|
||||
- return this.hasEnchants() ? ImmutableMap.copyOf(enchantments) : ImmutableMap.<Enchantment, Integer>of();
|
||||
+ return this.hasEnchants() ? ImmutableSortedMap.copyOfSorted(this.enchantments) : ImmutableMap.<Enchantment, Integer>of(); // Paper
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addEnchant(Enchantment ench, int level, boolean ignoreRestrictions) {
|
||||
Validate.notNull(ench, "Enchantment cannot be null");
|
||||
if (this.enchantments == null) {
|
||||
- this.enchantments = new LinkedHashMap<Enchantment, Integer>(4);
|
||||
+ this.enchantments = new EnchantmentMap(); // Paper
|
||||
}
|
||||
|
||||
if (ignoreRestrictions || level >= ench.getStartLevel() && level <= ench.getMaxLevel()) {
|
||||
@@ -1223,7 +1226,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
|
||||
clone.customModelData = this.customModelData;
|
||||
clone.blockData = this.blockData;
|
||||
if (this.enchantments != null) {
|
||||
- clone.enchantments = new LinkedHashMap<Enchantment, Integer>(this.enchantments);
|
||||
+ clone.enchantments = new EnchantmentMap(this.enchantments); // Paper
|
||||
}
|
||||
if (this.hasAttributeModifiers()) {
|
||||
clone.attributeModifiers = LinkedHashMultimap.create(this.attributeModifiers);
|
||||
@@ -1458,4 +1461,22 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
|
||||
return CraftMetaItem.HANDLED_TAGS;
|
||||
}
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ private static class EnchantmentMap extends TreeMap<Enchantment, Integer> {
|
||||
+ private EnchantmentMap(Map<Enchantment, Integer> enchantments) {
|
||||
+ this();
|
||||
+ putAll(enchantments);
|
||||
+ }
|
||||
+
|
||||
+ private EnchantmentMap() {
|
||||
+ super(Comparator.comparing(o -> o.getKey().toString()));
|
||||
+ }
|
||||
+
|
||||
+ public EnchantmentMap clone() {
|
||||
+ return (EnchantmentMap) super.clone();
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Fri, 18 Mar 2016 15:12:22 -0400
|
||||
Subject: [PATCH] Configurable Non Player Arrow Despawn Rate
|
||||
|
||||
Can set a much shorter despawn rate for arrows that players can not pick up.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
|
||||
index 27c31a9e926f919c7edc8fc0cdd7fba70616d60c..7cd802be238cedf166174a61e816d9d4b29b87d2 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
|
||||
@@ -311,7 +311,7 @@ public abstract class AbstractArrow extends Projectile {
|
||||
|
||||
protected void tickDespawn() {
|
||||
++this.life;
|
||||
- if (this.life >= ((this instanceof ThrownTrident) ? level.spigotConfig.tridentDespawnRate : level.spigotConfig.arrowDespawnRate)) { // Spigot
|
||||
+ if (this.life >= (pickup == Pickup.CREATIVE_ONLY ? level.paperConfig().entities.spawning.creativeArrowDespawnRate.value() : (pickup == Pickup.DISALLOWED ? level.paperConfig().entities.spawning.nonPlayerArrowDespawnRate.value() : ((this instanceof ThrownTrident) ? level.spigotConfig.tridentDespawnRate : level.spigotConfig.arrowDespawnRate)))) { // Spigot // Paper - TODO: Extract this to init?
|
||||
this.discard();
|
||||
}
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Fri, 18 Mar 2016 20:16:03 -0400
|
||||
Subject: [PATCH] Add World Util Methods
|
||||
|
||||
Methods that can be used for other patches to help improve logic.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
index 28d6b8c5bebbbfb15ea76dea9e79e6b95978f15f..e4cf3d46de32ce5982da9c8cce2f1c6f74eddaa7 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -215,7 +215,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
||||
public final LevelStorageSource.LevelStorageAccess convertable;
|
||||
public final UUID uuid;
|
||||
|
||||
- public LevelChunk getChunkIfLoaded(int x, int z) {
|
||||
+ @Override public LevelChunk getChunkIfLoaded(int x, int z) { // Paper - this was added in world too but keeping here for NMS ABI
|
||||
return this.chunkSource.getChunk(x, z, false);
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
|
||||
index ee71a6cc552bd2bb82beda1bd44905ea4cc14604..e89410b00c8f9ef94cd2baf621802fa847bd6456 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/Level.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
||||
@@ -333,6 +333,22 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
return chunk == null ? null : chunk.getFluidState(blockposition);
|
||||
}
|
||||
|
||||
+ public final boolean isLoadedAndInBounds(BlockPos blockposition) { // Paper - final for inline
|
||||
+ return getWorldBorder().isWithinBounds(blockposition) && getChunkIfLoadedImmediately(blockposition.getX() >> 4, blockposition.getZ() >> 4) != null;
|
||||
+ }
|
||||
+
|
||||
+ public @Nullable LevelChunk getChunkIfLoaded(int x, int z) { // Overridden in WorldServer for ABI compat which has final
|
||||
+ return ((ServerLevel) this).getChunkSource().getChunkAtIfLoadedImmediately(x, z);
|
||||
+ }
|
||||
+ public final @Nullable LevelChunk getChunkIfLoaded(BlockPos blockposition) {
|
||||
+ return ((ServerLevel) this).getChunkSource().getChunkAtIfLoadedImmediately(blockposition.getX() >> 4, blockposition.getZ() >> 4);
|
||||
+ }
|
||||
+
|
||||
+ // reduces need to do isLoaded before getType
|
||||
+ public final @Nullable BlockState getBlockStateIfLoadedAndInBounds(BlockPos blockposition) {
|
||||
+ return getWorldBorder().isWithinBounds(blockposition) ? getBlockStateIfLoaded(blockposition) : null;
|
||||
+ }
|
||||
+
|
||||
@Override
|
||||
public final ChunkAccess getChunk(int chunkX, int chunkZ, ChunkStatus leastStatus, boolean create) { // Paper - final for inline
|
||||
// Paper end
|
|
@ -1,48 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jedediah Smith <jedediah@silencegreys.com>
|
||||
Date: Sun, 21 Jun 2015 15:07:20 -0400
|
||||
Subject: [PATCH] Custom replacement for eaten items
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
index 30198bf3d05da6e05cca08a8e5f39edc964cb356..55c18329f20e3f95f51119fbde1a6f3863129a8d 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -3586,9 +3586,10 @@ public abstract class LivingEntity extends Entity {
|
||||
this.triggerItemUseEffects(this.useItem, 16);
|
||||
// CraftBukkit start - fire PlayerItemConsumeEvent
|
||||
ItemStack itemstack;
|
||||
+ PlayerItemConsumeEvent event = null; // Paper
|
||||
if (this instanceof ServerPlayer) {
|
||||
org.bukkit.inventory.ItemStack craftItem = CraftItemStack.asBukkitCopy(this.useItem);
|
||||
- PlayerItemConsumeEvent event = new PlayerItemConsumeEvent((Player) this.getBukkitEntity(), craftItem);
|
||||
+ event = new PlayerItemConsumeEvent((Player) this.getBukkitEntity(), craftItem); // Paper
|
||||
level.getCraftServer().getPluginManager().callEvent(event);
|
||||
|
||||
if (event.isCancelled()) {
|
||||
@@ -3602,6 +3603,13 @@ public abstract class LivingEntity extends Entity {
|
||||
} else {
|
||||
itemstack = this.useItem.finishUsingItem(this.level, this);
|
||||
}
|
||||
+
|
||||
+ // Paper start - save the default replacement item and change it if necessary
|
||||
+ final ItemStack defaultReplacement = itemstack;
|
||||
+ if (event != null && event.getReplacement() != null) {
|
||||
+ itemstack = CraftItemStack.asNMSCopy(event.getReplacement());
|
||||
+ }
|
||||
+ // Paper end
|
||||
// CraftBukkit end
|
||||
|
||||
if (itemstack != this.useItem) {
|
||||
@@ -3609,6 +3617,11 @@ public abstract class LivingEntity extends Entity {
|
||||
}
|
||||
|
||||
this.stopUsingItem();
|
||||
+ // Paper start - if the replacement is anything but the default, update the client inventory
|
||||
+ if (this instanceof ServerPlayer && !com.google.common.base.Objects.equal(defaultReplacement, itemstack)) {
|
||||
+ ((ServerPlayer) this).getBukkitEntity().updateInventory();
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sun, 27 Sep 2015 01:18:02 -0400
|
||||
Subject: [PATCH] handle NaN health/absorb values and repair bad data
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
index 55c18329f20e3f95f51119fbde1a6f3863129a8d..315ad337bddf3c6c95e829d3598d7d4ed87231b8 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -784,7 +784,13 @@ public abstract class LivingEntity extends Entity {
|
||||
|
||||
@Override
|
||||
public void readAdditionalSaveData(CompoundTag nbt) {
|
||||
- this.setAbsorptionAmount(nbt.getFloat("AbsorptionAmount"));
|
||||
+ // Paper start - jvm keeps optimizing the setter
|
||||
+ float absorptionAmount = nbt.getFloat("AbsorptionAmount");
|
||||
+ if (Float.isNaN(absorptionAmount)) {
|
||||
+ absorptionAmount = 0;
|
||||
+ }
|
||||
+ this.setAbsorptionAmount(absorptionAmount);
|
||||
+ // Paper end
|
||||
if (nbt.contains("Attributes", 9) && this.level != null && !this.level.isClientSide) {
|
||||
this.getAttributes().load(nbt.getList("Attributes", 10));
|
||||
}
|
||||
@@ -1271,6 +1277,10 @@ public abstract class LivingEntity extends Entity {
|
||||
}
|
||||
|
||||
public void setHealth(float health) {
|
||||
+ // Paper start
|
||||
+ if (Float.isNaN(health)) { health = getMaxHealth(); if (this.valid) {
|
||||
+ System.err.println("[NAN-HEALTH] " + getScoreboardName() + " had NaN health set");
|
||||
+ } } // Paper end
|
||||
// CraftBukkit start - Handle scaled health
|
||||
if (this instanceof ServerPlayer) {
|
||||
org.bukkit.craftbukkit.entity.CraftPlayer player = ((ServerPlayer) this).getBukkitEntity();
|
||||
@@ -3419,7 +3429,7 @@ public abstract class LivingEntity extends Entity {
|
||||
}
|
||||
|
||||
public void setAbsorptionAmount(float amount) {
|
||||
- if (amount < 0.0F) {
|
||||
+ if (amount < 0.0F || Float.isNaN(amount)) { // Paper
|
||||
amount = 0.0F;
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
index 8ad19c44e4cfa39f81f8fc5e6a13e2649b6b0a3c..c8d63359c77ce11711df3ebed295fdd989d601a5 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
@@ -1920,6 +1920,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
}
|
||||
|
||||
public void setRealHealth(double health) {
|
||||
+ if (Double.isNaN(health)) {return;} // Paper
|
||||
this.health = health;
|
||||
}
|
||||
|
|
@ -1,113 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 22 Mar 2016 00:33:47 -0400
|
||||
Subject: [PATCH] Use a Shared Random for Entities
|
||||
|
||||
Reduces memory usage and provides ensures more randomness, Especially since a lot of garbage entity objects get created.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
index 380b7a31bae4d63248f8473dcbb602f4abbd4dd8..4e5dbb2414c76181053db13b13082154366f581a 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -159,6 +159,79 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
|
||||
return tag.contains("Bukkit.updateLevel") && tag.getInt("Bukkit.updateLevel") >= level;
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ public static RandomSource SHARED_RANDOM = new RandomRandomSource();
|
||||
+ private static final class RandomRandomSource extends java.util.Random implements net.minecraft.world.level.levelgen.BitRandomSource {
|
||||
+ private boolean locked = false;
|
||||
+
|
||||
+ @Override
|
||||
+ public synchronized void setSeed(long seed) {
|
||||
+ if (locked) {
|
||||
+ LOGGER.error("Ignoring setSeed on Entity.SHARED_RANDOM", new Throwable());
|
||||
+ } else {
|
||||
+ super.setSeed(seed);
|
||||
+ locked = true;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public RandomSource fork() {
|
||||
+ return new net.minecraft.world.level.levelgen.LegacyRandomSource(this.nextLong());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public net.minecraft.world.level.levelgen.PositionalRandomFactory forkPositional() {
|
||||
+ return new net.minecraft.world.level.levelgen.LegacyRandomSource.LegacyPositionalRandomFactory(this.nextLong());
|
||||
+ }
|
||||
+
|
||||
+ // these below are added to fix reobf issues that I don't wanna deal with right now
|
||||
+ @Override
|
||||
+ public int next(int bits) {
|
||||
+ return super.next(bits);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int nextInt(int origin, int bound) {
|
||||
+ return net.minecraft.world.level.levelgen.BitRandomSource.super.nextInt(origin, bound);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public long nextLong() {
|
||||
+ return net.minecraft.world.level.levelgen.BitRandomSource.super.nextLong();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int nextInt() {
|
||||
+ return net.minecraft.world.level.levelgen.BitRandomSource.super.nextInt();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int nextInt(int bound) {
|
||||
+ return net.minecraft.world.level.levelgen.BitRandomSource.super.nextInt(bound);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean nextBoolean() {
|
||||
+ return net.minecraft.world.level.levelgen.BitRandomSource.super.nextBoolean();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public float nextFloat() {
|
||||
+ return net.minecraft.world.level.levelgen.BitRandomSource.super.nextFloat();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public double nextDouble() {
|
||||
+ return net.minecraft.world.level.levelgen.BitRandomSource.super.nextDouble();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public double nextGaussian() {
|
||||
+ return super.nextGaussian();
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
private CraftEntity bukkitEntity;
|
||||
|
||||
public CraftEntity getBukkitEntity() {
|
||||
@@ -346,7 +419,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
|
||||
this.bb = Entity.INITIAL_AABB;
|
||||
this.stuckSpeedMultiplier = Vec3.ZERO;
|
||||
this.nextStep = 1.0F;
|
||||
- this.random = RandomSource.create();
|
||||
+ this.random = SHARED_RANDOM; // Paper
|
||||
this.remainingFireTicks = -this.getFireImmuneTicks();
|
||||
this.fluidHeight = new Object2DoubleArrayMap(2);
|
||||
this.fluidOnEyes = new HashSet();
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/Squid.java b/src/main/java/net/minecraft/world/entity/animal/Squid.java
|
||||
index 8e63ab510e4c2e458da726ca67be4d3b5274e7b7..a51424d29ac353cf1bec4d1484db0acb63bebba5 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/Squid.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/Squid.java
|
||||
@@ -46,7 +46,7 @@ public class Squid extends WaterAnimal {
|
||||
|
||||
public Squid(EntityType<? extends Squid> type, Level world) {
|
||||
super(type, world);
|
||||
- this.random.setSeed((long) this.getId());
|
||||
+ //this.random.setSeed((long) this.getId()); // Paper - we set the random to shared, do not clobber the seed
|
||||
this.tentacleSpeed = 1.0F / (this.random.nextFloat() + 1.0F) * 0.2F;
|
||||
}
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <zach.brown@destroystokyo.com>
|
||||
Date: Tue, 22 Mar 2016 12:04:28 -0500
|
||||
Subject: [PATCH] Configurable spawn chances for skeleton horses
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
index e4cf3d46de32ce5982da9c8cce2f1c6f74eddaa7..27186bffd00b9a7b23b6abc053362f3f70a9d481 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -586,7 +586,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
||||
blockposition = this.findLightningTargetAround(this.getBlockRandomPos(j, 0, k, 15));
|
||||
if (this.isRainingAt(blockposition)) {
|
||||
DifficultyInstance difficultydamagescaler = this.getCurrentDifficultyAt(blockposition);
|
||||
- boolean flag1 = this.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && this.random.nextDouble() < (double) difficultydamagescaler.getEffectiveDifficulty() * 0.01D && !this.getBlockState(blockposition.below()).is(Blocks.LIGHTNING_ROD);
|
||||
+ boolean flag1 = this.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && this.random.nextDouble() < (double) difficultydamagescaler.getEffectiveDifficulty() * this.paperConfig().entities.spawning.skeletonHorseThunderSpawnChance.or(0.01D) && !this.getBlockState(blockposition.below()).is(Blocks.LIGHTNING_ROD); // Paper
|
||||
|
||||
if (flag1) {
|
||||
SkeletonHorse entityhorseskeleton = (SkeletonHorse) EntityType.SKELETON_HORSE.create(this);
|
|
@ -1,166 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Thu, 3 Mar 2016 02:07:55 -0600
|
||||
Subject: [PATCH] Optimize isInWorldBounds and getBlockState for inlining
|
||||
|
||||
Hot methods, so reduce # of instructions for the method.
|
||||
|
||||
Move is valid location test to the BlockPosition class so that it can access local variables.
|
||||
|
||||
Replace all calls to the new place to the unnecessary forward.
|
||||
|
||||
Optimize getType and getBlockData to manually inline and optimize the calls
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/core/Vec3i.java b/src/main/java/net/minecraft/core/Vec3i.java
|
||||
index 4587a3668b6be9222cdd74a38229f89f611d1af6..9f32861d791f7e4cb39d2ad01f48e1916fc2b4b1 100644
|
||||
--- a/src/main/java/net/minecraft/core/Vec3i.java
|
||||
+++ b/src/main/java/net/minecraft/core/Vec3i.java
|
||||
@@ -33,6 +33,12 @@ public class Vec3i implements Comparable<Vec3i> {
|
||||
return CODEC.flatXmap(checkOffsetAxes(maxAbsValue), checkOffsetAxes(maxAbsValue));
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ public final boolean isInsideBuildHeightAndWorldBoundsHorizontal(net.minecraft.world.level.LevelHeightAccessor levelHeightAccessor) {
|
||||
+ return getX() >= -30000000 && getZ() >= -30000000 && getX() < 30000000 && getZ() < 30000000 && !levelHeightAccessor.isOutsideBuildHeight(getY());
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
public Vec3i(int x, int y, int z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
|
||||
index e89410b00c8f9ef94cd2baf621802fa847bd6456..d3277e8aa7244ab490a6b354d863d4a9f3c60fec 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/Level.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
||||
@@ -276,7 +276,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
}
|
||||
|
||||
public boolean isInWorldBounds(BlockPos pos) {
|
||||
- return !this.isOutsideBuildHeight(pos) && Level.isInWorldBoundsHorizontal(pos);
|
||||
+ return pos.isInsideBuildHeightAndWorldBoundsHorizontal(this); // Paper - use better/optimized check
|
||||
}
|
||||
|
||||
public static boolean isInSpawnableBounds(BlockPos pos) {
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java b/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java
|
||||
index 91d2939bde77c52c25d2633dacc461d7284ef2d3..0d815a39d50bb8c06f81e3386764db6a00d84985 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java
|
||||
@@ -119,6 +119,7 @@ public abstract class ChunkAccess implements BlockGetter, BiomeManager.NoiseBiom
|
||||
return GameEventDispatcher.NOOP;
|
||||
}
|
||||
|
||||
+ public abstract BlockState getBlockState(final int x, final int y, final int z); // Paper
|
||||
@Nullable
|
||||
public abstract BlockState setBlockState(BlockPos pos, BlockState state, boolean moved);
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/EmptyLevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/EmptyLevelChunk.java
|
||||
index 80e383e9a2d12f9f1b0b0d9ae71a0add9b51c9d4..a9c65c8d36e5c7080133706df1363b3ce52e3370 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/EmptyLevelChunk.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/EmptyLevelChunk.java
|
||||
@@ -21,6 +21,12 @@ public class EmptyLevelChunk extends LevelChunk {
|
||||
this.biome = holder;
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public BlockState getBlockState(int x, int y, int z) {
|
||||
+ return Blocks.VOID_AIR.defaultBlockState();
|
||||
+ }
|
||||
+ // Paper end
|
||||
@Override
|
||||
public BlockState getBlockState(BlockPos pos) {
|
||||
return Blocks.VOID_AIR.defaultBlockState();
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/ImposterProtoChunk.java b/src/main/java/net/minecraft/world/level/chunk/ImposterProtoChunk.java
|
||||
index 475663848a612f356a8e01330b03efb33e98fcec..ca46ed27fdc1eef979829d19b9e90db6d5c59e09 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/ImposterProtoChunk.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/ImposterProtoChunk.java
|
||||
@@ -47,6 +47,12 @@ public class ImposterProtoChunk extends ProtoChunk {
|
||||
public BlockState getBlockState(BlockPos pos) {
|
||||
return this.wrapped.getBlockState(pos);
|
||||
}
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public final BlockState getBlockState(final int x, final int y, final int z) {
|
||||
+ return this.wrapped.getBlockStateFinal(x, y, z);
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
@Override
|
||||
public FluidState getFluidState(BlockPos pos) {
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
index 2704a05766d42b0277fa6308820b88371db00ace..a508b7c6dbf9f7acdca77c219d7dd2492cd7c6b8 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
@@ -296,12 +296,29 @@ public class LevelChunk extends ChunkAccess {
|
||||
}
|
||||
}
|
||||
|
||||
+ // Paper start - Optimize getBlockData to reduce instructions
|
||||
@Override
|
||||
public BlockState getBlockState(BlockPos pos) {
|
||||
- int i = pos.getX();
|
||||
- int j = pos.getY();
|
||||
- int k = pos.getZ();
|
||||
+ return this.getBlockStateFinal(pos.getX(), pos.getY(), pos.getZ());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public BlockState getBlockState(final int x, final int y, final int z) {
|
||||
+ return this.getBlockStateFinal(x, y, z);
|
||||
+ }
|
||||
+ public final BlockState getBlockStateFinal(final int x, final int y, final int z) {
|
||||
+ // Method body / logic copied from below
|
||||
+ final int i = this.getSectionIndex(y);
|
||||
+ if (i < 0 || i >= this.sections.length || this.sections[i].nonEmptyBlockCount == 0 || this.sections[i].hasOnlyAir()) {
|
||||
+ return Blocks.AIR.defaultBlockState();
|
||||
+ }
|
||||
+ // Inlined ChunkSection.getType() and DataPaletteBlock.a(int,int,int)
|
||||
+ return this.sections[i].states.get((y & 15) << 8 | (z & 15) << 4 | x & 15);
|
||||
|
||||
+ }
|
||||
+
|
||||
+ public BlockState getBlockState_unused(int i, int j, int k) {
|
||||
+ // Paper end
|
||||
if (this.level.isDebug()) {
|
||||
BlockState iblockdata = null;
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java
|
||||
index dddae1e226d8f58cdcfc597e25d4228cd3245cb4..ae37e97e52557b48f129cc02eeea395378a48444 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java
|
||||
@@ -21,7 +21,7 @@ public class LevelChunkSection {
|
||||
public static final int SECTION_SIZE = 4096;
|
||||
public static final int BIOME_CONTAINER_BITS = 2;
|
||||
private final int bottomBlockY;
|
||||
- private short nonEmptyBlockCount;
|
||||
+ short nonEmptyBlockCount; // Paper - package-private
|
||||
private short tickingBlockCount;
|
||||
private short tickingFluidCount;
|
||||
public final PalettedContainer<BlockState> states;
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java b/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java
|
||||
index 3b11824a1b85da437eec108f631eacfb5192459e..5ce6a2b83546f4dbc3183a386f51b4bacc173744 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java
|
||||
@@ -88,14 +88,18 @@ public class ProtoChunk extends ChunkAccess {
|
||||
|
||||
@Override
|
||||
public BlockState getBlockState(BlockPos pos) {
|
||||
- int i = pos.getY();
|
||||
- if (this.isOutsideBuildHeight(i)) {
|
||||
+ // Paper start
|
||||
+ return getBlockState(pos.getX(), pos.getY(), pos.getZ());
|
||||
+ }
|
||||
+ public BlockState getBlockState(final int x, final int y, final int z) {
|
||||
+ if (this.isOutsideBuildHeight(y)) {
|
||||
return Blocks.VOID_AIR.defaultBlockState();
|
||||
} else {
|
||||
- LevelChunkSection levelChunkSection = this.getSection(this.getSectionIndex(i));
|
||||
- return levelChunkSection.hasOnlyAir() ? Blocks.AIR.defaultBlockState() : levelChunkSection.getBlockState(pos.getX() & 15, i & 15, pos.getZ() & 15);
|
||||
+ LevelChunkSection levelChunkSection = this.getSections()[this.getSectionIndex(y)];
|
||||
+ return levelChunkSection.hasOnlyAir() ? Blocks.AIR.defaultBlockState() : levelChunkSection.getBlockState(x & 15, y & 15, z & 15);
|
||||
}
|
||||
}
|
||||
+ // Paper end
|
||||
|
||||
@Override
|
||||
public FluidState getFluidState(BlockPos pos) {
|
|
@ -1,70 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 28 Mar 2016 19:55:45 -0400
|
||||
Subject: [PATCH] Only process BlockPhysicsEvent if a plugin has a listener
|
||||
|
||||
Saves on some object allocation and processing when no plugin listens to this
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index cc6699b9806bfaeca7d6e3564974bdbd532e06bc..170e3d9257f98af7ba1a95d0bf084b11258ea02b 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -1356,6 +1356,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
ServerLevel worldserver = (ServerLevel) iterator.next();
|
||||
+ worldserver.hasPhysicsEvent = org.bukkit.event.block.BlockPhysicsEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper
|
||||
|
||||
this.profiler.push(() -> {
|
||||
return worldserver + " " + worldserver.dimension().location();
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
index 27186bffd00b9a7b23b6abc053362f3f70a9d481..dc4788765bbbe15c477c2e975129d63923d3f31f 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -214,6 +214,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
||||
// CraftBukkit start
|
||||
public final LevelStorageSource.LevelStorageAccess convertable;
|
||||
public final UUID uuid;
|
||||
+ public boolean hasPhysicsEvent = true; // Paper
|
||||
|
||||
@Override public LevelChunk getChunkIfLoaded(int x, int z) { // Paper - this was added in world too but keeping here for NMS ABI
|
||||
return this.chunkSource.getChunk(x, z, false);
|
||||
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
|
||||
index d3277e8aa7244ab490a6b354d863d4a9f3c60fec..8359cc9cde98ffe11f2d9ede4350a404bc5086be 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/Level.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
||||
@@ -488,7 +488,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
// CraftBukkit start
|
||||
iblockdata1.updateIndirectNeighbourShapes(this, blockposition, k, j - 1); // Don't call an event for the old block to limit event spam
|
||||
CraftWorld world = ((ServerLevel) this).getWorld();
|
||||
- if (world != null) {
|
||||
+ if (world != null && ((ServerLevel)this).hasPhysicsEvent) { // Paper
|
||||
BlockPhysicsEvent event = new BlockPhysicsEvent(world.getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()), CraftBlockData.fromData(iblockdata));
|
||||
this.getCraftServer().getPluginManager().callEvent(event);
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/BushBlock.java b/src/main/java/net/minecraft/world/level/block/BushBlock.java
|
||||
index d40e791529911ca81398ac267a819415da91502a..03fde6e47c4a347c62fe9b4a3351769aedf874f6 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/BushBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/BushBlock.java
|
||||
@@ -24,7 +24,7 @@ public class BushBlock extends Block {
|
||||
public BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) {
|
||||
// CraftBukkit start
|
||||
if (!state.canSurvive(world, pos)) {
|
||||
- if (!org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPhysicsEvent(world, pos).isCancelled()) {
|
||||
+ if (!(world instanceof net.minecraft.server.level.ServerLevel && ((net.minecraft.server.level.ServerLevel) world).hasPhysicsEvent) || !org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPhysicsEvent(world, pos).isCancelled()) { // Paper
|
||||
return Blocks.AIR.defaultBlockState();
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/DoublePlantBlock.java b/src/main/java/net/minecraft/world/level/block/DoublePlantBlock.java
|
||||
index a90f6cc0d8c0f6d115e59d07b1b4c9b45fe0ad1e..fa97966d39f01301a8ba976c02dc697e0a74bfb1 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/DoublePlantBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/DoublePlantBlock.java
|
||||
@@ -93,7 +93,7 @@ public class DoublePlantBlock extends BushBlock {
|
||||
|
||||
protected static void preventCreativeDropFromBottomPart(Level world, BlockPos pos, BlockState state, Player player) {
|
||||
// CraftBukkit start
|
||||
- if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPhysicsEvent(world, pos).isCancelled()) {
|
||||
+ if (((net.minecraft.server.level.ServerLevel)world).hasPhysicsEvent && org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPhysicsEvent(world, pos).isCancelled()) { // Paper
|
||||
return;
|
||||
}
|
||||
// CraftBukkit end
|
|
@ -1,26 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 28 Mar 2016 20:32:58 -0400
|
||||
Subject: [PATCH] Entity AddTo/RemoveFrom World Events
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
index dc4788765bbbe15c477c2e975129d63923d3f31f..68a6f4e63bcaff52d69c3532ffa3da15e883a6e4 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -2118,6 +2118,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
||||
entity.setOrigin(entity.getOriginVector().toLocation(getWorld()));
|
||||
}
|
||||
// Paper end
|
||||
+ new com.destroystokyo.paper.event.entity.EntityAddToWorldEvent(entity.getBukkitEntity()).callEvent(); // Paper - fire while valid
|
||||
}
|
||||
|
||||
public void onTrackingEnd(Entity entity) {
|
||||
@@ -2193,6 +2194,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
||||
}
|
||||
}
|
||||
// CraftBukkit end
|
||||
+ new com.destroystokyo.paper.event.entity.EntityRemoveFromWorldEvent(entity.getBukkitEntity()).callEvent(); // Paper - fire while valid
|
||||
}
|
||||
|
||||
public void onSectionChange(Entity entity) {
|
|
@ -1,30 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 28 Mar 2016 20:46:14 -0400
|
||||
Subject: [PATCH] Configurable Chunk Inhabited Time
|
||||
|
||||
Vanilla stores how long a chunk has been active on a server, and dynamically scales some
|
||||
aspects of vanilla gameplay to this factor.
|
||||
|
||||
For people who want all chunks to be treated equally, you can chose a fixed value.
|
||||
|
||||
This allows to fine-tune vanilla gameplay.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
index a508b7c6dbf9f7acdca77c219d7dd2492cd7c6b8..e9fae214f60fe682087d41cfaa55a1b25e5f4331 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
@@ -281,6 +281,13 @@ public class LevelChunk extends ChunkAccess {
|
||||
return new ChunkAccess.TicksToSave(this.blockTicks, this.fluidTicks);
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public long getInhabitedTime() {
|
||||
+ return this.level.paperConfig().chunks.fixedChunkInhabitedTime < 0 ? super.getInhabitedTime() : this.level.paperConfig().chunks.fixedChunkInhabitedTime;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public GameEventDispatcher getEventDispatcher(int ySectionCoord) {
|
||||
Level world = this.level;
|
|
@ -1,110 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 28 Mar 2016 21:22:26 -0400
|
||||
Subject: [PATCH] EntityPathfindEvent
|
||||
|
||||
Fires when an Entity decides to start moving to a location.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/ai/navigation/FlyingPathNavigation.java b/src/main/java/net/minecraft/world/entity/ai/navigation/FlyingPathNavigation.java
|
||||
index 0b2e10a0f508448d9e7d003e6c822f0a56d4022f..27cd393e81f6ef9b5690c051624d8d2af50acd34 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ai/navigation/FlyingPathNavigation.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ai/navigation/FlyingPathNavigation.java
|
||||
@@ -35,7 +35,7 @@ public class FlyingPathNavigation extends PathNavigation {
|
||||
|
||||
@Override
|
||||
public Path createPath(Entity entity, int distance) {
|
||||
- return this.createPath(entity.blockPosition(), distance);
|
||||
+ return this.createPath(entity.blockPosition(), entity, distance); // Paper - Forward target entity
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/ai/navigation/GroundPathNavigation.java b/src/main/java/net/minecraft/world/entity/ai/navigation/GroundPathNavigation.java
|
||||
index 27b072943328aca4489a9565bda700e7e7dcbb6a..f610c06d7bb51ec2c63863dd46711712986a106a 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ai/navigation/GroundPathNavigation.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ai/navigation/GroundPathNavigation.java
|
||||
@@ -69,7 +69,7 @@ public class GroundPathNavigation extends PathNavigation {
|
||||
|
||||
@Override
|
||||
public Path createPath(Entity entity, int distance) {
|
||||
- return this.createPath(entity.blockPosition(), distance);
|
||||
+ return this.createPath(entity.blockPosition(), entity, distance); // Paper - Forward target entity
|
||||
}
|
||||
|
||||
private int getSurfaceY() {
|
||||
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 eaf1653b14e5fdacae38abe75260a64d0ffbfc1d..ff1e04e5e3b8099b0b71eda1c0de864c809c5029 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
|
||||
@@ -10,6 +10,7 @@ import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Vec3i;
|
||||
import net.minecraft.network.protocol.game.DebugPackets;
|
||||
import net.minecraft.tags.BlockTags;
|
||||
+import net.minecraft.server.MCUtil;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.Mob;
|
||||
@@ -108,7 +109,13 @@ public abstract class PathNavigation {
|
||||
|
||||
@Nullable
|
||||
public Path createPath(BlockPos target, int distance) {
|
||||
- return this.createPath(ImmutableSet.of(target), 8, false, distance);
|
||||
+ // Paper start - add target entity parameter
|
||||
+ return this.createPath(target, null, distance);
|
||||
+ }
|
||||
+ @Nullable
|
||||
+ public Path createPath(BlockPos target, Entity entity, int distance) {
|
||||
+ return this.createPath(ImmutableSet.of(target), entity, 8, false, distance);
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -118,7 +125,7 @@ public abstract class PathNavigation {
|
||||
|
||||
@Nullable
|
||||
public Path createPath(Entity entity, int distance) {
|
||||
- return this.createPath(ImmutableSet.of(entity.blockPosition()), 16, true, distance);
|
||||
+ return this.createPath(ImmutableSet.of(entity.blockPosition()), entity, 16, true, distance); // Paper
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -128,6 +135,16 @@ public abstract class PathNavigation {
|
||||
|
||||
@Nullable
|
||||
protected Path createPath(Set<BlockPos> positions, int range, boolean useHeadPos, int distance, float followRange) {
|
||||
+ return this.createPath(positions, null, range, useHeadPos, distance, (float) this.mob.getAttributeValue(Attributes.FOLLOW_RANGE));
|
||||
+ }
|
||||
+
|
||||
+ @Nullable
|
||||
+ protected Path createPath(Set<BlockPos> positions, Entity target, int range, boolean useHeadPos, int distance) {
|
||||
+ return this.createPath(positions, target, range, useHeadPos, distance, (float) this.mob.getAttributeValue(Attributes.FOLLOW_RANGE));
|
||||
+ }
|
||||
+
|
||||
+ @Nullable protected Path createPath(Set<BlockPos> positions, Entity target, int range, boolean useHeadPos, int distance, float followRange) {
|
||||
+ // Paper end
|
||||
if (positions.isEmpty()) {
|
||||
return null;
|
||||
} else if (this.mob.getY() < (double)this.level.getMinBuildHeight()) {
|
||||
@@ -137,6 +154,23 @@ public abstract class PathNavigation {
|
||||
} else if (this.path != null && !this.path.isDone() && positions.contains(this.targetPos)) {
|
||||
return this.path;
|
||||
} else {
|
||||
+ // Paper start - Pathfind event
|
||||
+ boolean copiedSet = false;
|
||||
+ for (BlockPos possibleTarget : positions) {
|
||||
+ if (!new com.destroystokyo.paper.event.entity.EntityPathfindEvent(this.mob.getBukkitEntity(),
|
||||
+ MCUtil.toLocation(this.mob.level, possibleTarget), target == null ? null : target.getBukkitEntity()).callEvent()) {
|
||||
+ if (!copiedSet) {
|
||||
+ copiedSet = true;
|
||||
+ positions = new java.util.HashSet<>(positions);
|
||||
+ }
|
||||
+ // note: since we copy the set this remove call is safe, since we're iterating over the old copy
|
||||
+ positions.remove(possibleTarget);
|
||||
+ if (positions.isEmpty()) {
|
||||
+ return null;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
this.level.getProfiler().push("pathfind");
|
||||
BlockPos blockPos = useHeadPos ? this.mob.blockPosition().above() : this.mob.blockPosition();
|
||||
int i = (int)(followRange + (float)range);
|
|
@ -1,25 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Antony Riley <antony@cyberiantiger.org>
|
||||
Date: Tue, 29 Mar 2016 08:22:55 +0300
|
||||
Subject: [PATCH] Sanitise RegionFileCache and make configurable.
|
||||
|
||||
RegionFileCache prior to this patch would close every single open region
|
||||
file upon reaching a size of 256.
|
||||
This patch modifies that behaviour so it closes the the least recently
|
||||
used RegionFile.
|
||||
The implementation uses a LinkedHashMap as an LRU cache (modified from HashMap).
|
||||
The maximum size of the RegionFileCache is also made configurable.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
|
||||
index eaf22cec54b512e0f57606f50627d5fe9b39bd5c..5a35e5040726a981ae91f018f05b91c178a54ba0 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
|
||||
@@ -36,7 +36,7 @@ public class RegionFileStorage implements AutoCloseable {
|
||||
if (regionfile != null) {
|
||||
return regionfile;
|
||||
} else {
|
||||
- if (this.regionCache.size() >= 256) {
|
||||
+ if (this.regionCache.size() >= io.papermc.paper.configuration.GlobalConfiguration.get().misc.regionFileCacheSize) { // Paper - configurable
|
||||
((RegionFile) this.regionCache.removeLast()).close();
|
||||
}
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Thu, 31 Mar 2016 19:17:58 -0400
|
||||
Subject: [PATCH] Do not load chunks for Pathfinding
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/pathfinder/WalkNodeEvaluator.java b/src/main/java/net/minecraft/world/level/pathfinder/WalkNodeEvaluator.java
|
||||
index 235b01e23a8997d0d65de3655b3b3ff50a204c06..c48e097464977dbec22d1370c3393ba1fe105137 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/pathfinder/WalkNodeEvaluator.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/pathfinder/WalkNodeEvaluator.java
|
||||
@@ -477,7 +477,12 @@ public class WalkNodeEvaluator extends NodeEvaluator {
|
||||
for(int n = -1; n <= 1; ++n) {
|
||||
if (l != 0 || n != 0) {
|
||||
pos.set(i + l, j + m, k + n);
|
||||
- BlockState blockState = world.getBlockState(pos);
|
||||
+ // Paper start
|
||||
+ BlockState blockState = world.getBlockStateIfLoaded(pos);
|
||||
+ if (blockState == null) {
|
||||
+ return BlockPathTypes.BLOCKED;
|
||||
+ } else {
|
||||
+ // Paper end
|
||||
if (blockState.is(Blocks.CACTUS)) {
|
||||
return BlockPathTypes.DANGER_CACTUS;
|
||||
}
|
||||
@@ -493,6 +498,7 @@ public class WalkNodeEvaluator extends NodeEvaluator {
|
||||
if (world.getFluidState(pos).is(FluidTags.WATER)) {
|
||||
return BlockPathTypes.WATER_BORDER;
|
||||
}
|
||||
+ } // Paper
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -502,7 +508,8 @@ public class WalkNodeEvaluator extends NodeEvaluator {
|
||||
}
|
||||
|
||||
protected static BlockPathTypes getBlockPathTypeRaw(BlockGetter world, BlockPos pos) {
|
||||
- BlockState blockState = world.getBlockState(pos);
|
||||
+ BlockState blockState = world.getBlockStateIfLoaded(pos); // Paper
|
||||
+ if (blockState == null) return BlockPathTypes.BLOCKED; // Paper
|
||||
Block block = blockState.getBlock();
|
||||
Material material = blockState.getMaterial();
|
||||
if (blockState.isAir()) {
|
|
@ -1,63 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jedediah Smith <jedediah@silencegreys.com>
|
||||
Date: Sat, 2 Apr 2016 05:09:16 -0400
|
||||
Subject: [PATCH] Add PlayerUseUnknownEntityEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/network/protocol/game/ServerboundInteractPacket.java b/src/main/java/net/minecraft/network/protocol/game/ServerboundInteractPacket.java
|
||||
index 8834ed411a7db86b4d2b88183a1315317107d719..c45b5ab6776f3ac79f856c3a6467c510e20db25a 100644
|
||||
--- a/src/main/java/net/minecraft/network/protocol/game/ServerboundInteractPacket.java
|
||||
+++ b/src/main/java/net/minecraft/network/protocol/game/ServerboundInteractPacket.java
|
||||
@@ -10,8 +10,8 @@ import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public class ServerboundInteractPacket implements Packet<ServerGamePacketListener> {
|
||||
- private final int entityId;
|
||||
- private final ServerboundInteractPacket.Action action;
|
||||
+ private final int entityId; public final int getEntityId() { return this.entityId; } // Paper - add accessor
|
||||
+ private final ServerboundInteractPacket.Action action; public final ServerboundInteractPacket.ActionType getActionType() { return this.action.getType(); } // Paper - add accessor
|
||||
private final boolean usingSecondaryAction;
|
||||
static final ServerboundInteractPacket.Action ATTACK_ACTION = new ServerboundInteractPacket.Action() {
|
||||
@Override
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 2266ddf2ed66dfc9f82facddcbe6fcc89e1c0267..a33a142ba55be937fb19f70239f8327f8b7f236e 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -2411,8 +2411,37 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
|
||||
});
|
||||
}
|
||||
}
|
||||
+ // Paper start - fire event
|
||||
+ else {
|
||||
+ packet.dispatch(new net.minecraft.network.protocol.game.ServerboundInteractPacket.Handler() {
|
||||
+ @Override
|
||||
+ public void onInteraction(net.minecraft.world.InteractionHand hand) {
|
||||
+ ServerGamePacketListenerImpl.this.callPlayerUseUnknownEntityEvent(packet, hand);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void onInteraction(net.minecraft.world.InteractionHand hand, net.minecraft.world.phys.Vec3 pos) {
|
||||
+ ServerGamePacketListenerImpl.this.callPlayerUseUnknownEntityEvent(packet, hand);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void onAttack() {
|
||||
+ ServerGamePacketListenerImpl.this.callPlayerUseUnknownEntityEvent(packet, net.minecraft.world.InteractionHand.MAIN_HAND);
|
||||
+ }
|
||||
+ });
|
||||
+ }
|
||||
+
|
||||
+ }
|
||||
|
||||
+ private void callPlayerUseUnknownEntityEvent(ServerboundInteractPacket packet, InteractionHand hand) {
|
||||
+ this.cserver.getPluginManager().callEvent(new com.destroystokyo.paper.event.player.PlayerUseUnknownEntityEvent(
|
||||
+ this.getCraftPlayer(),
|
||||
+ packet.getEntityId(),
|
||||
+ packet.getActionType() == ServerboundInteractPacket.ActionType.ATTACK,
|
||||
+ hand == InteractionHand.MAIN_HAND ? EquipmentSlot.HAND : EquipmentSlot.OFF_HAND
|
||||
+ ));
|
||||
}
|
||||
+ // Paper end
|
||||
|
||||
@Override
|
||||
public void handleClientCommand(ServerboundClientCommandPacket packet) {
|
|
@ -1,26 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sun, 3 Apr 2016 16:28:17 -0400
|
||||
Subject: [PATCH] Configurable Grass Spread Tick Rate
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/SpreadingSnowyDirtBlock.java b/src/main/java/net/minecraft/world/level/block/SpreadingSnowyDirtBlock.java
|
||||
index bd5a45765b53bf4f2f9aaea4769c71ffb008741d..61783f17b655cbb6430d22fb3a81931ab3ea130c 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/SpreadingSnowyDirtBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/SpreadingSnowyDirtBlock.java
|
||||
@@ -2,6 +2,7 @@ package net.minecraft.world.level.block;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
+import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.tags.FluidTags;
|
||||
import net.minecraft.util.RandomSource;
|
||||
@@ -39,6 +40,7 @@ public abstract class SpreadingSnowyDirtBlock extends SnowyDirtBlock {
|
||||
|
||||
@Override
|
||||
public void randomTick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) {
|
||||
+ if (this instanceof GrassBlock && world.paperConfig().tickRates.grassSpread != 1 && (world.paperConfig().tickRates.grassSpread < 1 || (MinecraftServer.currentTick + pos.hashCode()) % world.paperConfig().tickRates.grassSpread != 0)) { return; } // Paper
|
||||
if (!SpreadingSnowyDirtBlock.canBeGrass(state, world, pos)) {
|
||||
// CraftBukkit start
|
||||
if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(world, pos, Blocks.DIRT.defaultBlockState()).isCancelled()) {
|
|
@ -1,18 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sun, 3 Apr 2016 17:48:50 -0400
|
||||
Subject: [PATCH] Fix Cancelling BlockPlaceEvent triggering physics
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
index 68a6f4e63bcaff52d69c3532ffa3da15e883a6e4..106bdc4ca666fc4db03a2ec4885add5a4d1bb059 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -1364,6 +1364,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
||||
|
||||
@Override
|
||||
public void updateNeighborsAt(BlockPos pos, Block sourceBlock) {
|
||||
+ if (captureBlockStates) { return; } // Paper - Cancel all physics during placement
|
||||
this.neighborUpdater.updateNeighborsAtExceptFromFacing(pos, sourceBlock, (Direction) null);
|
||||
}
|
||||
|
|
@ -1,118 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 5 Apr 2016 21:38:58 -0400
|
||||
Subject: [PATCH] Optimize DataBits
|
||||
|
||||
Remove Debug checks as these are super hot and causing noticeable hits
|
||||
|
||||
Before: http://i.imgur.com/nQsMzAE.png
|
||||
After: http://i.imgur.com/nJ46crB.png
|
||||
|
||||
Optimize redundant converting of static fields into an unsigned long each call by precomputing it in ctor
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/util/SimpleBitStorage.java b/src/main/java/net/minecraft/util/SimpleBitStorage.java
|
||||
index c8ae9d25eedb7cb2d9f95b799a507727b655f11f..9b81ce9d85cba07e9752c29fb5a842c4b00aa873 100644
|
||||
--- a/src/main/java/net/minecraft/util/SimpleBitStorage.java
|
||||
+++ b/src/main/java/net/minecraft/util/SimpleBitStorage.java
|
||||
@@ -11,8 +11,8 @@ public class SimpleBitStorage implements BitStorage {
|
||||
private final long mask;
|
||||
private final int size;
|
||||
private final int valuesPerLong;
|
||||
- private final int divideMul;
|
||||
- private final int divideAdd;
|
||||
+ private final int divideMul; private final long divideMulUnsigned; // Paper - referenced in b(int) with 2 Integer.toUnsignedLong calls
|
||||
+ private final int divideAdd; private final long divideAddUnsigned; // Paper
|
||||
private final int divideShift;
|
||||
|
||||
public SimpleBitStorage(int elementBits, int size, int[] data) {
|
||||
@@ -56,8 +56,8 @@ public class SimpleBitStorage implements BitStorage {
|
||||
this.mask = (1L << elementBits) - 1L;
|
||||
this.valuesPerLong = (char)(64 / elementBits);
|
||||
int i = 3 * (this.valuesPerLong - 1);
|
||||
- this.divideMul = MAGIC[i + 0];
|
||||
- this.divideAdd = MAGIC[i + 1];
|
||||
+ this.divideMul = MAGIC[i + 0]; this.divideMulUnsigned = Integer.toUnsignedLong(this.divideMul); // Paper
|
||||
+ this.divideAdd = MAGIC[i + 1]; this.divideAddUnsigned = Integer.toUnsignedLong(this.divideAdd); // Paper
|
||||
this.divideShift = MAGIC[i + 2];
|
||||
int j = (size + this.valuesPerLong - 1) / this.valuesPerLong;
|
||||
if (data != null) {
|
||||
@@ -73,15 +73,15 @@ public class SimpleBitStorage implements BitStorage {
|
||||
}
|
||||
|
||||
private int cellIndex(int index) {
|
||||
- long l = Integer.toUnsignedLong(this.divideMul);
|
||||
- long m = Integer.toUnsignedLong(this.divideAdd);
|
||||
- return (int)((long)index * l + m >> 32 >> this.divideShift);
|
||||
+ //long l = Integer.toUnsignedLong(this.divideMul); // Paper
|
||||
+ //long m = Integer.toUnsignedLong(this.divideAdd); // Paper
|
||||
+ return (int) ((long) index * this.divideMulUnsigned + this.divideAddUnsigned >> 32 >> this.divideShift); // Paper
|
||||
}
|
||||
|
||||
@Override
|
||||
- public int getAndSet(int index, int value) {
|
||||
- Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index);
|
||||
- Validate.inclusiveBetween(0L, this.mask, (long)value);
|
||||
+ public final int getAndSet(int index, int value) { // Paper - make final for inline
|
||||
+ //Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index); // Paper
|
||||
+ //Validate.inclusiveBetween(0L, this.mask, (long)value); // Paper
|
||||
int i = this.cellIndex(index);
|
||||
long l = this.data[i];
|
||||
int j = (index - i * this.valuesPerLong) * this.bits;
|
||||
@@ -91,9 +91,9 @@ public class SimpleBitStorage implements BitStorage {
|
||||
}
|
||||
|
||||
@Override
|
||||
- public void set(int index, int value) {
|
||||
- Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index);
|
||||
- Validate.inclusiveBetween(0L, this.mask, (long)value);
|
||||
+ public final void set(int index, int value) { // Paper - make final for inline
|
||||
+ //Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index); // Paper
|
||||
+ //Validate.inclusiveBetween(0L, this.mask, (long)value); // Paper
|
||||
int i = this.cellIndex(index);
|
||||
long l = this.data[i];
|
||||
int j = (index - i * this.valuesPerLong) * this.bits;
|
||||
@@ -101,8 +101,8 @@ public class SimpleBitStorage implements BitStorage {
|
||||
}
|
||||
|
||||
@Override
|
||||
- public int get(int index) {
|
||||
- Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index);
|
||||
+ public final int get(int index) { // Paper - make final for inline
|
||||
+ //Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index);
|
||||
int i = this.cellIndex(index);
|
||||
long l = this.data[i];
|
||||
int j = (index - i * this.valuesPerLong) * this.bits;
|
||||
diff --git a/src/main/java/net/minecraft/util/ZeroBitStorage.java b/src/main/java/net/minecraft/util/ZeroBitStorage.java
|
||||
index 172e7a0761724cc802387e613258830a0defb04a..9686ce7536c9924b1b2aced4f013f46759cbc72e 100644
|
||||
--- a/src/main/java/net/minecraft/util/ZeroBitStorage.java
|
||||
+++ b/src/main/java/net/minecraft/util/ZeroBitStorage.java
|
||||
@@ -13,21 +13,21 @@ public class ZeroBitStorage implements BitStorage {
|
||||
}
|
||||
|
||||
@Override
|
||||
- public int getAndSet(int index, int value) {
|
||||
- Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index);
|
||||
- Validate.inclusiveBetween(0L, 0L, (long)value);
|
||||
+ public final int getAndSet(int index, int value) { // Paper - make final for inline
|
||||
+ //Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index); // Paper
|
||||
+ //Validate.inclusiveBetween(0L, 0L, (long)value); // Paper
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
- public void set(int index, int value) {
|
||||
- Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index);
|
||||
- Validate.inclusiveBetween(0L, 0L, (long)value);
|
||||
+ public final void set(int index, int value) { // Paper - make final for inline
|
||||
+ //Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index); // Paper
|
||||
+ //Validate.inclusiveBetween(0L, 0L, (long)value); // Paper
|
||||
}
|
||||
|
||||
@Override
|
||||
- public int get(int index) {
|
||||
- Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index);
|
||||
+ public final int get(int index) { // Paper - make final for inline
|
||||
+ //Validate.inclusiveBetween(0L, (long)(this.size - 1), (long)index); // Paper
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <zach.brown@destroystokyo.com>
|
||||
Date: Wed, 6 Apr 2016 01:04:23 -0500
|
||||
Subject: [PATCH] Option to use vanilla per-world scoreboard coloring on names
|
||||
|
||||
This change is basically a bandaid to fix CB's complete and utter lack
|
||||
of support for vanilla scoreboard name modifications.
|
||||
|
||||
In the future, finding a way to merge the vanilla expectations in with
|
||||
bukkit's concept of a display name would be preferable. There was a PR
|
||||
for this on CB at one point but I can't find it. We may need to do this
|
||||
ourselves at some point in the future.
|
||||
|
||||
diff --git a/src/main/java/io/papermc/paper/adventure/ChatProcessor.java b/src/main/java/io/papermc/paper/adventure/ChatProcessor.java
|
||||
index 3526bc0b6ad590776124966ea907fe2467cbbf5f..b13d516d91788713768b5c336537ffe31653b074 100644
|
||||
--- a/src/main/java/io/papermc/paper/adventure/ChatProcessor.java
|
||||
+++ b/src/main/java/io/papermc/paper/adventure/ChatProcessor.java
|
||||
@@ -16,6 +16,8 @@ import net.kyori.adventure.text.event.ClickEvent;
|
||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
+import org.bukkit.ChatColor;
|
||||
+import org.bukkit.craftbukkit.CraftWorld;
|
||||
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||
import org.bukkit.craftbukkit.util.LazyPlayerSet;
|
||||
import org.bukkit.craftbukkit.util.Waitable;
|
||||
@@ -154,10 +156,16 @@ public final class ChatProcessor {
|
||||
}
|
||||
|
||||
private static String legacyDisplayName(final CraftPlayer player) {
|
||||
+ if (((org.bukkit.craftbukkit.CraftWorld) player.getWorld()).getHandle().paperConfig().scoreboards.useVanillaWorldScoreboardNameColoring) {
|
||||
+ return LegacyComponentSerializer.legacySection().serialize(player.teamDisplayName()) + ChatColor.RESET;
|
||||
+ }
|
||||
return player.getDisplayName();
|
||||
}
|
||||
|
||||
private static Component displayName(final CraftPlayer player) {
|
||||
+ if (((CraftWorld) player.getWorld()).getHandle().paperConfig().scoreboards.useVanillaWorldScoreboardNameColoring) {
|
||||
+ return player.teamDisplayName();
|
||||
+ }
|
||||
return player.displayName();
|
||||
}
|
||||
|
|
@ -1,109 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Wed, 13 Apr 2016 02:10:49 -0400
|
||||
Subject: [PATCH] Configurable Player Collision
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundSetPlayerTeamPacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundSetPlayerTeamPacket.java
|
||||
index 1294b38262505b0d54089e428df9b363219de1f0..ee37ec0de1ca969144824427ae42b0c81434a1b4 100644
|
||||
--- a/src/main/java/net/minecraft/network/protocol/game/ClientboundSetPlayerTeamPacket.java
|
||||
+++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundSetPlayerTeamPacket.java
|
||||
@@ -193,7 +193,7 @@ public class ClientboundSetPlayerTeamPacket implements Packet<ClientGamePacketLi
|
||||
buf.writeComponent(this.displayName);
|
||||
buf.writeByte(this.options);
|
||||
buf.writeUtf(this.nametagVisibility);
|
||||
- buf.writeUtf(this.collisionRule);
|
||||
+ buf.writeUtf(!io.papermc.paper.configuration.GlobalConfiguration.get().collisions.enablePlayerCollisions ? "never" : this.collisionRule); // Paper
|
||||
buf.writeEnum(this.color);
|
||||
buf.writeComponent(this.playerPrefix);
|
||||
buf.writeComponent(this.playerSuffix);
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index 170e3d9257f98af7ba1a95d0bf084b11258ea02b..2b9199df0b969cce0de3a0dd47da7edccabb97f7 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -578,6 +578,20 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
this.server.getPluginManager().callEvent(new org.bukkit.event.world.WorldLoadEvent(worldserver.getWorld()));
|
||||
}
|
||||
|
||||
+ // Paper start - Handle collideRule team for player collision toggle
|
||||
+ final ServerScoreboard scoreboard = this.getScoreboard();
|
||||
+ final java.util.Collection<String> toRemove = scoreboard.getPlayerTeams().stream().filter(team -> team.getName().startsWith("collideRule_")).map(net.minecraft.world.scores.PlayerTeam::getName).collect(java.util.stream.Collectors.toList());
|
||||
+ for (String teamName : toRemove) {
|
||||
+ scoreboard.removePlayerTeam(scoreboard.getPlayerTeam(teamName)); // Clean up after ourselves
|
||||
+ }
|
||||
+
|
||||
+ if (!io.papermc.paper.configuration.GlobalConfiguration.get().collisions.enablePlayerCollisions) {
|
||||
+ this.getPlayerList().collideRuleTeamName = org.apache.commons.lang3.StringUtils.left("collideRule_" + java.util.concurrent.ThreadLocalRandom.current().nextInt(), 16);
|
||||
+ net.minecraft.world.scores.PlayerTeam collideTeam = scoreboard.addPlayerTeam(this.getPlayerList().collideRuleTeamName);
|
||||
+ collideTeam.setSeeFriendlyInvisibles(false); // Because we want to mimic them not being on a team at all
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
this.server.enablePlugins(org.bukkit.plugin.PluginLoadOrder.POSTWORLD);
|
||||
this.server.getPluginManager().callEvent(new ServerLoadEvent(ServerLoadEvent.LoadType.STARTUP));
|
||||
this.connection.acceptConnections();
|
||||
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
index 16e1d0b62e01551a54d60c81ca12708f51aceef9..3fe3d417b6c1ff49a412c308bfe6a43182d0986e 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
@@ -98,6 +98,7 @@ import net.minecraft.world.level.storage.PlayerDataStorage;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraft.world.scores.Objective;
|
||||
import net.minecraft.world.scores.PlayerTeam;
|
||||
+import net.minecraft.world.scores.Scoreboard; // Paper
|
||||
import net.minecraft.world.scores.Team;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
@@ -154,6 +155,7 @@ public abstract class PlayerList {
|
||||
// CraftBukkit start
|
||||
private CraftServer cserver;
|
||||
private final Map<String,ServerPlayer> playersByName = new java.util.HashMap<>();
|
||||
+ public @Nullable String collideRuleTeamName; // Paper - Team name used for collideRule
|
||||
|
||||
public PlayerList(MinecraftServer server, RegistryAccess.Frozen registryManager, PlayerDataStorage saveHandler, int maxPlayers) {
|
||||
this.cserver = server.server = new CraftServer((DedicatedServer) server, this);
|
||||
@@ -389,6 +391,13 @@ public abstract class PlayerList {
|
||||
|
||||
player.initInventoryMenu();
|
||||
// CraftBukkit - Moved from above, added world
|
||||
+ // Paper start - Add to collideRule team if needed
|
||||
+ final Scoreboard scoreboard = this.getServer().getLevel(Level.OVERWORLD).getScoreboard();
|
||||
+ final PlayerTeam collideRuleTeam = scoreboard.getPlayerTeam(this.collideRuleTeamName);
|
||||
+ if (this.collideRuleTeamName != null && collideRuleTeam != null && player.getTeam() == null) {
|
||||
+ scoreboard.addPlayerToTeam(player.getScoreboardName(), collideRuleTeam);
|
||||
+ }
|
||||
+ // Paper end
|
||||
PlayerList.LOGGER.info("{}[{}] logged in with entity id {} at ([{}]{}, {}, {})", player.getName().getString(), s1, player.getId(), worldserver1.serverLevelData.getLevelName(), player.getX(), player.getY(), player.getZ());
|
||||
}
|
||||
|
||||
@@ -508,6 +517,16 @@ public abstract class PlayerList {
|
||||
entityplayer.doTick(); // SPIGOT-924
|
||||
// CraftBukkit end
|
||||
|
||||
+ // Paper start - Remove from collideRule team if needed
|
||||
+ if (this.collideRuleTeamName != null) {
|
||||
+ final Scoreboard scoreBoard = this.server.getLevel(Level.OVERWORLD).getScoreboard();
|
||||
+ final PlayerTeam team = scoreBoard.getPlayersTeam(this.collideRuleTeamName);
|
||||
+ if (entityplayer.getTeam() == team && team != null) {
|
||||
+ scoreBoard.removePlayerFromTeam(entityplayer.getScoreboardName(), team);
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
this.save(entityplayer);
|
||||
if (entityplayer.isPassenger()) {
|
||||
Entity entity = entityplayer.getRootVehicle();
|
||||
@@ -1136,6 +1155,13 @@ public abstract class PlayerList {
|
||||
}
|
||||
// CraftBukkit end
|
||||
|
||||
+ // Paper start - Remove collideRule team if it exists
|
||||
+ if (this.collideRuleTeamName != null) {
|
||||
+ final Scoreboard scoreboard = this.getServer().getLevel(Level.OVERWORLD).getScoreboard();
|
||||
+ final PlayerTeam team = scoreboard.getPlayersTeam(this.collideRuleTeamName);
|
||||
+ if (team != null) scoreboard.removePlayerTeam(team);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
// CraftBukkit start
|
|
@ -1,49 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: kashike <kashike@vq.lc>
|
||||
Date: Wed, 13 Apr 2016 20:21:38 -0700
|
||||
Subject: [PATCH] Add handshake event to allow plugins to handle client
|
||||
handshaking logic themselves
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java
|
||||
index eb94a7a156df1616f8093bf2f082de3754917086..9016aced079108aeae09f030a672467a953ef93f 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java
|
||||
@@ -87,9 +87,36 @@ public class ServerHandshakePacketListenerImpl implements ServerHandshakePacketL
|
||||
this.connection.disconnect(ichatmutablecomponent);
|
||||
} else {
|
||||
this.connection.setListener(new ServerLoginPacketListenerImpl(this.server, this.connection));
|
||||
+ // Paper start - handshake event
|
||||
+ boolean proxyLogicEnabled = org.spigotmc.SpigotConfig.bungee;
|
||||
+ boolean handledByEvent = false;
|
||||
+ // Try and handle the handshake through the event
|
||||
+ if (com.destroystokyo.paper.event.player.PlayerHandshakeEvent.getHandlerList().getRegisteredListeners().length != 0) { // Hello? Can you hear me?
|
||||
+ java.net.SocketAddress socketAddress = this.connection.address;
|
||||
+ String hostnameOfRemote = socketAddress instanceof java.net.InetSocketAddress ? ((java.net.InetSocketAddress) socketAddress).getHostString() : InetAddress.getLoopbackAddress().getHostAddress();
|
||||
+ com.destroystokyo.paper.event.player.PlayerHandshakeEvent event = new com.destroystokyo.paper.event.player.PlayerHandshakeEvent(packet.hostName, hostnameOfRemote, !proxyLogicEnabled);
|
||||
+ if (event.callEvent()) {
|
||||
+ // If we've failed somehow, let the client know so and go no further.
|
||||
+ if (event.isFailed()) {
|
||||
+ Component component = io.papermc.paper.adventure.PaperAdventure.asVanilla(event.failMessage());
|
||||
+ this.connection.send(new ClientboundLoginDisconnectPacket(component));
|
||||
+ this.connection.disconnect(component);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (event.getServerHostname() != null) packet.hostName = event.getServerHostname();
|
||||
+ if (event.getSocketAddressHostname() != null) this.connection.address = new java.net.InetSocketAddress(event.getSocketAddressHostname(), socketAddress instanceof java.net.InetSocketAddress ? ((java.net.InetSocketAddress) socketAddress).getPort() : 0);
|
||||
+ this.connection.spoofedUUID = event.getUniqueId();
|
||||
+ this.connection.spoofedProfile = gson.fromJson(event.getPropertiesJson(), com.mojang.authlib.properties.Property[].class);
|
||||
+ handledByEvent = true; // Hooray, we did it!
|
||||
+ }
|
||||
+ }
|
||||
// Spigot Start
|
||||
String[] split = packet.hostName.split("\00");
|
||||
- if (org.spigotmc.SpigotConfig.bungee) {
|
||||
+ // Don't try and handle default logic if it's been handled by the event.
|
||||
+ if (!handledByEvent && proxyLogicEnabled) {
|
||||
+ // Paper end
|
||||
+ // if (org.spigotmc.SpigotConfig.bungee) { // Paper - comment out, we check above!
|
||||
if ( ( split.length == 3 || split.length == 4 ) && ( ServerHandshakePacketListenerImpl.HOST_PATTERN.matcher( split[1] ).matches() ) ) {
|
||||
packet.hostName = split[0];
|
||||
connection.address = new java.net.InetSocketAddress(split[1], ((java.net.InetSocketAddress) this.connection.getRemoteAddress()).getPort());
|
|
@ -1,44 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sat, 16 Apr 2016 00:39:33 -0400
|
||||
Subject: [PATCH] Configurable RCON IP address
|
||||
|
||||
For servers with multiple IP's, ability to bind to a specific interface.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java
|
||||
index cfff4a6711b2acd4b40ec80544c169a46ded3f79..cc92e2c5e6b62c6a67d0a6534b078e3a6029daf5 100644
|
||||
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java
|
||||
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java
|
||||
@@ -100,6 +100,8 @@ public class DedicatedServerProperties extends Settings<DedicatedServerPropertie
|
||||
@Nullable
|
||||
private WorldGenSettings worldGenSettings;
|
||||
|
||||
+ public final String rconIp; // Paper - Add rcon ip
|
||||
+
|
||||
// CraftBukkit start
|
||||
public DedicatedServerProperties(Properties properties, OptionSet optionset) {
|
||||
super(properties, optionset);
|
||||
@@ -152,6 +154,10 @@ public class DedicatedServerProperties extends Settings<DedicatedServerPropertie
|
||||
return s.toLowerCase(Locale.ROOT);
|
||||
}, WorldPresets.NORMAL.location().toString()));
|
||||
this.serverResourcePackInfo = DedicatedServerProperties.getServerPackInfo(this.get("resource-pack", ""), this.get("resource-pack-sha1", ""), this.getLegacyString("resource-pack-hash"), this.get("require-resource-pack", false), this.get("resource-pack-prompt", ""));
|
||||
+ // Paper start - Configurable rcon ip
|
||||
+ final String rconIp = this.getStringRaw("rcon.ip");
|
||||
+ this.rconIp = rconIp == null ? this.serverIp : rconIp;
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
// CraftBukkit start
|
||||
diff --git a/src/main/java/net/minecraft/server/rcon/thread/RconThread.java b/src/main/java/net/minecraft/server/rcon/thread/RconThread.java
|
||||
index cb61eaf8447c8340c4b4e1079c0a6aecd41a6116..3bf60f640aa9fa4cabd2b3e5d3931e8467b9df24 100644
|
||||
--- a/src/main/java/net/minecraft/server/rcon/thread/RconThread.java
|
||||
+++ b/src/main/java/net/minecraft/server/rcon/thread/RconThread.java
|
||||
@@ -60,7 +60,7 @@ public class RconThread extends GenericThread {
|
||||
@Nullable
|
||||
public static RconThread create(ServerInterface server) {
|
||||
DedicatedServerProperties dedicatedServerProperties = server.getProperties();
|
||||
- String string = server.getServerIp();
|
||||
+ String string = dedicatedServerProperties.rconIp; // Paper - Configurable rcon ip
|
||||
if (string.isEmpty()) {
|
||||
string = "0.0.0.0";
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <zach.brown@destroystokyo.com>
|
||||
Date: Fri, 22 Apr 2016 01:43:11 -0500
|
||||
Subject: [PATCH] EntityRegainHealthEvent isFastRegen API
|
||||
|
||||
Don't even get me started
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
index 315ad337bddf3c6c95e829d3598d7d4ed87231b8..292f5dddd644880fc759fa8634d633ad40f3bf4f 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -1250,10 +1250,16 @@ public abstract class LivingEntity extends Entity {
|
||||
}
|
||||
|
||||
public void heal(float f, EntityRegainHealthEvent.RegainReason regainReason) {
|
||||
+ // Paper start - Forward
|
||||
+ heal(f, regainReason, false);
|
||||
+ }
|
||||
+
|
||||
+ public void heal(float f, EntityRegainHealthEvent.RegainReason regainReason, boolean isFastRegen) {
|
||||
+ // Paper end
|
||||
float f1 = this.getHealth();
|
||||
|
||||
if (f1 > 0.0F) {
|
||||
- EntityRegainHealthEvent event = new EntityRegainHealthEvent(this.getBukkitEntity(), f, regainReason);
|
||||
+ EntityRegainHealthEvent event = new EntityRegainHealthEvent(this.getBukkitEntity(), f, regainReason, isFastRegen); // Paper
|
||||
// Suppress during worldgen
|
||||
if (this.valid) {
|
||||
this.level.getCraftServer().getPluginManager().callEvent(event);
|
||||
diff --git a/src/main/java/net/minecraft/world/food/FoodData.java b/src/main/java/net/minecraft/world/food/FoodData.java
|
||||
index ae323c786b5a0d61d9292469baa50a3ad8e4ccff..2934b6de1f1fb914a532ee20184df99d1acd8e65 100644
|
||||
--- a/src/main/java/net/minecraft/world/food/FoodData.java
|
||||
+++ b/src/main/java/net/minecraft/world/food/FoodData.java
|
||||
@@ -84,7 +84,7 @@ public class FoodData {
|
||||
if (this.tickTimer >= this.saturatedRegenRate) { // CraftBukkit
|
||||
float f = Math.min(this.saturationLevel, 6.0F);
|
||||
|
||||
- player.heal(f / 6.0F, org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason.SATIATED); // CraftBukkit - added RegainReason
|
||||
+ player.heal(f / 6.0F, org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason.SATIATED, true); // CraftBukkit - added RegainReason // Paper - This is fast regen
|
||||
// this.addExhaustion(f); CraftBukkit - EntityExhaustionEvent
|
||||
player.causeFoodExhaustion(f, org.bukkit.event.entity.EntityExhaustionEvent.ExhaustionReason.REGEN); // CraftBukkit - EntityExhaustionEvent
|
||||
this.tickTimer = 0;
|
|
@ -1,33 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: kashike <kashike@vq.lc>
|
||||
Date: Thu, 21 Apr 2016 23:51:55 -0700
|
||||
Subject: [PATCH] Add ability to configure frosted_ice properties
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/FrostedIceBlock.java b/src/main/java/net/minecraft/world/level/block/FrostedIceBlock.java
|
||||
index e1916fe8a7aa736d9266efde954bbfbda38a3a65..331b642c36af97f7f05bd63f96d42d1af443e5a3 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/FrostedIceBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/FrostedIceBlock.java
|
||||
@@ -32,6 +32,7 @@ public class FrostedIceBlock extends IceBlock {
|
||||
|
||||
@Override
|
||||
public void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) {
|
||||
+ if (!world.paperConfig().environment.frostedIce.enabled) return; // Paper - add ability to disable frosted ice
|
||||
if ((random.nextInt(3) == 0 || this.fewerNeigboursThan(world, pos, 4)) && world.getMaxLocalRawBrightness(pos) > 11 - state.getValue(AGE) - state.getLightBlock(world, pos) && this.slightlyMelt(state, world, pos)) {
|
||||
BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos();
|
||||
|
||||
@@ -39,12 +40,12 @@ public class FrostedIceBlock extends IceBlock {
|
||||
mutableBlockPos.setWithOffset(pos, direction);
|
||||
BlockState blockState = world.getBlockState(mutableBlockPos);
|
||||
if (blockState.is(this) && !this.slightlyMelt(blockState, world, mutableBlockPos)) {
|
||||
- world.scheduleTick(mutableBlockPos, this, Mth.nextInt(random, 20, 40));
|
||||
+ world.scheduleTick(mutableBlockPos, this, Mth.nextInt(random, world.paperConfig().environment.frostedIce.delay.min, world.paperConfig().environment.frostedIce.delay.max)); // Paper - use configurable min/max delay
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
- world.scheduleTick(pos, this, Mth.nextInt(random, 20, 40));
|
||||
+ world.scheduleTick(pos, this, Mth.nextInt(random, world.paperConfig().environment.frostedIce.delay.min, world.paperConfig().environment.frostedIce.delay.max)); // Paper - use configurable min/max delay
|
||||
}
|
||||
}
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Thu, 28 Apr 2016 00:57:27 -0400
|
||||
Subject: [PATCH] remove null possibility for getServer singleton
|
||||
|
||||
to stop IDE complaining about potential NPE
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index 2b9199df0b969cce0de3a0dd47da7edccabb97f7..b40c2ccdc87208b5fc1962ad06ce961e51186f3e 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -179,6 +179,7 @@ import co.aikar.timings.MinecraftTimings; // Paper
|
||||
|
||||
public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTask> implements CommandSource, AutoCloseable {
|
||||
|
||||
+ private static MinecraftServer SERVER; // Paper
|
||||
public static final Logger LOGGER = LogUtils.getLogger();
|
||||
public static final String VANILLA_BRAND = "vanilla";
|
||||
private static final float AVERAGE_TICK_TIME_SMOOTHING = 0.8F;
|
||||
@@ -305,6 +306,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
|
||||
public MinecraftServer(OptionSet options, DataPackConfig datapackconfiguration, DynamicOps<Tag> registryreadops, Thread thread, LevelStorageSource.LevelStorageAccess convertable_conversionsession, PackRepository resourcepackrepository, WorldStem worldstem, Proxy proxy, DataFixer datafixer, Services services, ChunkProgressListenerFactory worldloadlistenerfactory) {
|
||||
super("Server");
|
||||
+ SERVER = this; // Paper - better singleton
|
||||
this.metricsRecorder = InactiveMetricsRecorder.INSTANCE;
|
||||
this.profiler = this.metricsRecorder.getProfiler();
|
||||
this.onMetricsRecordingStopped = (methodprofilerresults) -> {
|
||||
@@ -2281,9 +2283,8 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
return false;
|
||||
}
|
||||
|
||||
- @Deprecated
|
||||
public static MinecraftServer getServer() {
|
||||
- return (Bukkit.getServer() instanceof CraftServer) ? ((CraftServer) Bukkit.getServer()).getServer() : null;
|
||||
+ return SERVER; // Paper
|
||||
}
|
||||
// CraftBukkit end
|
||||
|
|
@ -1,128 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Fri, 29 Apr 2016 20:02:00 -0400
|
||||
Subject: [PATCH] Improve Maps (in item frames) performance and bug fixes
|
||||
|
||||
Maps used a modified version of rendering to support plugin controlled
|
||||
imaging on maps. The Craft Map Renderer is much slower than Vanilla,
|
||||
causing maps in item frames to cause a noticeable hit on server performance.
|
||||
|
||||
This updates the map system to not use the Craft system if we detect that no
|
||||
custom renderers are in use, defaulting to the much simpler Vanilla system.
|
||||
|
||||
Additionally, numerous issues to player position tracking on maps has been fixed.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
index 106bdc4ca666fc4db03a2ec4885add5a4d1bb059..ddd956828996c9d7a86aa89a01cc5a2ee4606c30 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -2139,6 +2139,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
||||
{
|
||||
if ( iter.next().player == entity )
|
||||
{
|
||||
+ map.decorations.remove(entity.getName().getString()); // Paper
|
||||
iter.remove();
|
||||
}
|
||||
}
|
||||
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 24456bbf2cd9f1878cf545e8d164ff524c321a4c..fdda98cb38ec96d0189931c41257cc01966373d5 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
@@ -762,6 +762,14 @@ public abstract class Player extends LivingEntity {
|
||||
return null;
|
||||
}
|
||||
// CraftBukkit end
|
||||
+ // Paper start - remove player from map on drop
|
||||
+ if (itemstack.getItem() == Items.FILLED_MAP) {
|
||||
+ net.minecraft.world.level.saveddata.maps.MapItemSavedData worldmap = net.minecraft.world.item.MapItem.getSavedData(itemstack, this.level);
|
||||
+ if (worldmap != null) {
|
||||
+ worldmap.tickCarriedBy(this, itemstack);
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
return entityitem;
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java b/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java
|
||||
index 3527d40102d512d0e276edc969ea3c189aa34ec2..913fabc7f42c05ccec6501247a5e8d1d481756ee 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java
|
||||
@@ -63,6 +63,7 @@ public class MapItemSavedData extends SavedData {
|
||||
public final Map<String, MapDecoration> decorations = Maps.newLinkedHashMap();
|
||||
private final Map<String, MapFrame> frameMarkers = Maps.newHashMap();
|
||||
private int trackedDecorationCount;
|
||||
+ private org.bukkit.craftbukkit.map.RenderData vanillaRender = new org.bukkit.craftbukkit.map.RenderData(); // Paper
|
||||
|
||||
// CraftBukkit start
|
||||
public final CraftMapView mapView;
|
||||
@@ -83,6 +84,7 @@ public class MapItemSavedData extends SavedData {
|
||||
// CraftBukkit start
|
||||
this.mapView = new CraftMapView(this);
|
||||
this.server = (CraftServer) org.bukkit.Bukkit.getServer();
|
||||
+ this.vanillaRender.buffer = colors; // Paper
|
||||
// CraftBukkit end
|
||||
}
|
||||
|
||||
@@ -138,6 +140,7 @@ public class MapItemSavedData extends SavedData {
|
||||
if (abyte.length == 16384) {
|
||||
worldmap.colors = abyte;
|
||||
}
|
||||
+ worldmap.vanillaRender.buffer = abyte; // Paper
|
||||
|
||||
ListTag nbttaglist = nbt.getList("banners", 10);
|
||||
|
||||
@@ -548,6 +551,21 @@ public class MapItemSavedData extends SavedData {
|
||||
|
||||
public class HoldingPlayer {
|
||||
|
||||
+ // Paper start
|
||||
+ private void addSeenPlayers(java.util.Collection<MapDecoration> icons) {
|
||||
+ org.bukkit.entity.Player player = (org.bukkit.entity.Player) this.player.getBukkitEntity();
|
||||
+ MapItemSavedData.this.decorations.forEach((name, mapIcon) -> {
|
||||
+ // If this cursor is for a player check visibility with vanish system
|
||||
+ org.bukkit.entity.Player other = org.bukkit.Bukkit.getPlayerExact(name); // Spigot
|
||||
+ if (other == null || player.canSee(other)) {
|
||||
+ icons.add(mapIcon);
|
||||
+ }
|
||||
+ });
|
||||
+ }
|
||||
+ private boolean shouldUseVanillaMap() {
|
||||
+ return mapView.getRenderers().size() == 1 && mapView.getRenderers().get(0).getClass() == org.bukkit.craftbukkit.map.CraftMapRenderer.class;
|
||||
+ }
|
||||
+ // Paper end
|
||||
public final Player player;
|
||||
private boolean dirtyData = true;
|
||||
private int minDirtyX;
|
||||
@@ -581,7 +599,9 @@ public class MapItemSavedData extends SavedData {
|
||||
@Nullable
|
||||
Packet<?> nextUpdatePacket(int mapId) {
|
||||
MapItemSavedData.MapPatch worldmap_b;
|
||||
- org.bukkit.craftbukkit.map.RenderData render = MapItemSavedData.this.mapView.render((org.bukkit.craftbukkit.entity.CraftPlayer) this.player.getBukkitEntity()); // CraftBukkit
|
||||
+ if (!this.dirtyData && this.tick % 5 != 0) { this.tick++; return null; } // Paper - this won't end up sending, so don't render it!
|
||||
+ boolean vanillaMaps = shouldUseVanillaMap(); // Paper
|
||||
+ org.bukkit.craftbukkit.map.RenderData render = !vanillaMaps ? MapItemSavedData.this.mapView.render((org.bukkit.craftbukkit.entity.CraftPlayer) this.player.getBukkitEntity()) : MapItemSavedData.this.vanillaRender; // CraftBukkit // Paper
|
||||
|
||||
if (this.dirtyData) {
|
||||
this.dirtyData = false;
|
||||
@@ -597,6 +617,8 @@ public class MapItemSavedData extends SavedData {
|
||||
// CraftBukkit start
|
||||
java.util.Collection<MapDecoration> icons = new java.util.ArrayList<MapDecoration>();
|
||||
|
||||
+ if (vanillaMaps) addSeenPlayers(icons); // Paper
|
||||
+
|
||||
for (org.bukkit.map.MapCursor cursor : render.cursors) {
|
||||
if (cursor.isVisible()) {
|
||||
icons.add(new MapDecoration(MapDecoration.Type.byIcon(cursor.getRawType()), cursor.getX(), cursor.getY(), cursor.getDirection(), PaperAdventure.asVanilla(cursor.caption()))); // Paper - Adventure
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/map/RenderData.java b/src/main/java/org/bukkit/craftbukkit/map/RenderData.java
|
||||
index 256a131781721c86dd6cdbc329335964570cbe8c..5768cd512ec166f1e8d1f4a28792015347297c3f 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/map/RenderData.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/map/RenderData.java
|
||||
@@ -5,7 +5,7 @@ import org.bukkit.map.MapCursor;
|
||||
|
||||
public class RenderData {
|
||||
|
||||
- public final byte[] buffer;
|
||||
+ public byte[] buffer; // Paper
|
||||
public final ArrayList<MapCursor> cursors;
|
||||
|
||||
public RenderData() {
|
|
@ -1,747 +0,0 @@
|
|||
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"
|
||||
|
||||
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..70ca5625ff5d13a8e9cd64953066a7e1547ff223
|
||||
--- /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 getTileEntity().getLevel();
|
||||
+ }
|
||||
+
|
||||
+ default Block getBlock() {
|
||||
+ final BlockPos position = getTileEntity().getBlockPos();
|
||||
+ final Chunk bukkitChunk = getTileEntity().getLevel().getChunkAt(position).bukkitChunk;
|
||||
+ return bukkitChunk.getBlock(position.getX(), position.getY(), position.getZ());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ default PaperLootableInventoryData getLootableData() {
|
||||
+ return 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..3377b86c337d0234bbb9b0349e4034a7cd450a97
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/loottable/PaperTileEntityLootableInventory.java
|
||||
@@ -0,0 +1,65 @@
|
||||
+package com.destroystokyo.paper.loottable;
|
||||
+
|
||||
+import net.minecraft.server.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 4e5dbb2414c76181053db13b13082154366f581a..a96d50b68d6ce6fe9b36de5af132b2fa6d08961c 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -232,6 +232,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 9347faecdaa3ef8c375fe8b0a89fc3385b6823bd..b8fb7b5a347298ada16bc8b818edf1863e3f6040 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.loadNbt(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 abb35b675fc075c1004a85cd8f0c6f65d290a809..ba14657c6911bfd54da6ee9e248b3a050455d68a 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.loadNbt(nbt); // Paper
|
||||
this.addChestVehicleSaveData(nbt);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void readAdditionalSaveData(CompoundTag nbt) {
|
||||
super.readAdditionalSaveData(nbt);
|
||||
+ this.lootableData.loadNbt(nbt); // Paper
|
||||
this.readChestVehicleSaveData(nbt);
|
||||
}
|
||||
|
||||
@@ -223,6 +225,20 @@ public class ChestBoat extends Boat implements HasCustomInventoryScreen, Contain
|
||||
this.itemStacks = NonNullList.withSize(this.getContainerSize(), ItemStack.EMPTY);
|
||||
}
|
||||
|
||||
+ // 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 e2a9782e0ae60eb5557dce0831084c5722687df6..9c15af9b622716ba8b21b8b1138ad1cd85430f96 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/vehicle/ContainerEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/vehicle/ContainerEntity.java
|
||||
@@ -61,7 +61,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());
|
||||
}
|
||||
|
||||
@@ -72,7 +72,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());
|
||||
}
|
||||
|
||||
@@ -184,4 +184,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 216fc20326d71121098430dc1b9f7477265a91b7..e3bee2df77d87630e96621470e940d9d9e152e7f 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
|
||||
@@ -28,6 +28,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);
|
||||
@@ -42,16 +43,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 {
|
||||
@@ -60,18 +64,19 @@ 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().getLootTables().get(this.lootTable);
|
||||
if (player instanceof ServerPlayer) {
|
||||
CriteriaTriggers.GENERATE_LOOT.trigger((ServerPlayer)player, this.lootTable);
|
||||
}
|
||||
|
||||
- this.lootTable = null;
|
||||
+ //this.lootTable = null; // Paper
|
||||
+ this.lootableData.processRefill(player); // Paper
|
||||
LootContext.Builder builder = (new LootContext.Builder((ServerLevel)this.level)).withParameter(LootContextParams.ORIGIN, Vec3.atCenterOf(this.worldPosition)).withOptionalRandomSeed(this.lootTableSeed);
|
||||
if (player != null) {
|
||||
builder.withLuck(player.getLuck()).withParameter(LootContextParams.THIS_ENTITY, player);
|
||||
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) {
|
|
@ -1,18 +0,0 @@
|
|||
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()));
|
|
@ -1,19 +0,0 @@
|
|||
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, "------------------------------" );
|
|
@ -1,86 +0,0 @@
|
|||
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 b40c2ccdc87208b5fc1962ad06ce961e51186f3e..c7b740087003113a00c5eccc9b0405b62b9da2b7 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -943,7 +943,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 2f2e07094a362ea1f459da85eb9ef84945a6e206..ee509d7b06a9785a39b59329a19531047953831b 100644
|
||||
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
@@ -247,7 +247,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 fb110ecb7fa8d0de7d8ce8e239d1db341a333203..717a0d1c1f4df7ebd5f4cdd5e24cabe3fb66bf06 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) {
|
||||
+ net.minecraft.server.MCUtil.scheduleAsyncTask(save);
|
||||
+ } else {
|
||||
+ save.run();
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
}
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
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 8b3ca38f029b8918f02c51995e4359cbbf741c76..d6f34adbdf45bbef4a39e629dd7cb6d7fcb5db0f 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerEntity.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerEntity.java
|
||||
@@ -65,7 +65,7 @@ public class ServerEntity {
|
||||
private boolean wasRiding;
|
||||
private boolean wasOnGround;
|
||||
// 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 10f8b5ff56e4c1d8300835e045abdce719a99343..8101f358975b35b5a2dafbade3d14a910e408fa2 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java
|
||||
@@ -97,6 +97,27 @@ public class PrimedTnt extends Entity {
|
||||
}
|
||||
}
|
||||
|
||||
+ // 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() {
|
||||
@@ -152,4 +173,11 @@ public class PrimedTnt extends Entity {
|
||||
public Packet<?> getAddEntityPacket() {
|
||||
return new ClientboundAddEntityPacket(this);
|
||||
}
|
||||
+
|
||||
+ // Paper start - Optional prevent TNT from moving in water
|
||||
+ @Override
|
||||
+ public boolean isPushedByFluid() {
|
||||
+ return !level.paperConfig().fixes.preventTntFromMovingInWater && super.isPushedByFluid();
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
|
@ -1,81 +0,0 @@
|
|||
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 8359cc9cde98ffe11f2d9ede4350a404bc5086be..aa2098d3af5cc03f3ff3ad663683c5edbe473756 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/Level.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
||||
@@ -167,6 +167,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) {
|
|
@ -1,25 +0,0 @@
|
|||
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 8962c8669802dabd6a7bc5b6e506f5d921becea2..d7766aaaaa9fd69aae162046cbd2410f8bfeb14c 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/Main.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/Main.java
|
||||
@@ -154,6 +154,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
|
||||
}
|
||||
};
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
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 Dragon/Wither Death sounds to same world
|
||||
|
||||
Also fix view distance lookup
|
||||
|
||||
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 dd1d606543da93e6068b8fa4239d369a4b648523..0dff7a47ecac1916ad23739fbb06ddd0f0052a65 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
|
||||
@@ -653,8 +653,9 @@ public class EnderDragon extends Mob implements Enemy {
|
||||
if (this.dragonDeathTime == 1 && !this.isSilent()) {
|
||||
// CraftBukkit start - Use relative location for far away sounds
|
||||
// this.world.b(1028, this.getChunkCoordinates(), 0);
|
||||
- int viewDistance = ((ServerLevel) this.level).getCraftServer().getViewDistance() * 16;
|
||||
- for (net.minecraft.server.level.ServerPlayer player : this.level.getServer().getPlayerList().players) {
|
||||
+ //int viewDistance = ((WorldServer) this.world).getServer().getViewDistance() * 16; // Paper - updated to use worlds actual view distance incase we have to uncomment this due to removal of player view distance API
|
||||
+ for (net.minecraft.server.level.ServerPlayer player : (List<net.minecraft.server.level.ServerPlayer>) ((ServerLevel)level).players()) {
|
||||
+ final int viewDistance = player.getViewDistance(); // TODO apply view distance api patch
|
||||
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 78bffaddbc9e478fb53639396e9c4970e9961b21..32b302aad0319ce3ee412912425c1c8db9979f8a 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,8 +271,9 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob
|
||||
if (!this.isSilent()) {
|
||||
// CraftBukkit start - Use relative location for far away sounds
|
||||
// this.world.globalLevelEvent(1023, new BlockPosition(this), 0);
|
||||
- int viewDistance = ((ServerLevel) this.level).getCraftServer().getViewDistance() * 16;
|
||||
- for (ServerPlayer player : (List<ServerPlayer>) MinecraftServer.getServer().getPlayerList().players) {
|
||||
+ //int viewDistance = ((ServerLevel) this.level).getCraftServer().getViewDistance() * 16; // Paper - updated to use worlds actual view distance incase we have to uncomment this due to removal of player view distance API
|
||||
+ for (ServerPlayer player : (List<ServerPlayer>)this.level.players()) { // Paper
|
||||
+ final int viewDistance = player.getViewDistance(); // TODO apply view distance api patch
|
||||
double deltaX = this.getX() - player.getX();
|
||||
double deltaZ = this.getZ() - player.getZ();
|
||||
double distanceSquared = deltaX * deltaX + deltaZ * deltaZ;
|
|
@ -1,49 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Fri, 17 Jun 2016 20:50:11 -0400
|
||||
Subject: [PATCH] Fix Old Sign Conversion
|
||||
|
||||
1) Sign loading code was trying to parse the JSON before the check for oldSign.
|
||||
That code could then skip the old sign converting code if it triggers a JSON parse exception.
|
||||
2) New Mojang Schematic system has Tile Entities in the new converted format, but missing the Bukkit.isConverted flag
|
||||
This causes Igloos and such to render broken signs. We fix this by ignoring sign conversion for Defined Structures
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java
|
||||
index c518704386f14cd033307dd976455c35760d7236..148e79ae4e24fe16dbbb17550c3f258d4362c266 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java
|
||||
@@ -32,6 +32,7 @@ public abstract class BlockEntity {
|
||||
private static final CraftPersistentDataTypeRegistry DATA_TYPE_REGISTRY = new CraftPersistentDataTypeRegistry();
|
||||
public CraftPersistentDataContainer persistentDataContainer;
|
||||
// CraftBukkit end
|
||||
+ public boolean isLoadingStructure = false; // Paper
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private final BlockEntityType<?> type;
|
||||
@Nullable
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java
|
||||
index 715873e52708762b25c29caf6d41d7cb8f79ce57..39bd98b9496e4a27fd69a2de7c83c40689017ebc 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java
|
||||
@@ -93,7 +93,7 @@ public class SignBlockEntity extends BlockEntity implements CommandSource { // C
|
||||
s = "\"\"";
|
||||
}
|
||||
|
||||
- if (oldSign) {
|
||||
+ if (oldSign && !this.isLoadingStructure) { // Paper - saved structures will be in the new format, but will not have isConverted
|
||||
this.messages[i] = org.bukkit.craftbukkit.util.CraftChatMessage.fromString(s)[0];
|
||||
continue;
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java b/src/main/java/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java
|
||||
index 71206f52a234a17db13062d975cbf66d1ffebc9a..f3fcd345178efd4917ef79cb141275a987f99e58 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java
|
||||
@@ -284,7 +284,9 @@ public class StructureTemplate {
|
||||
definedstructure_blockinfo.nbt.putLong("LootTableSeed", random.nextLong());
|
||||
}
|
||||
|
||||
+ tileentity.isLoadingStructure = true; // Paper
|
||||
tileentity.load(definedstructure_blockinfo.nbt);
|
||||
+ tileentity.isLoadingStructure = false; // Paper
|
||||
}
|
||||
}
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
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 0b657174309b6eaee0c8a2d6c17dd467d278739c..5e1a6f2cd2d0d9c6b17c446fa782e4089cc138d5 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerConnectionListener.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerConnectionListener.java
|
||||
@@ -62,6 +62,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();
|
||||
Object object = j > 0 ? new RateKickingConnection(j) : new Connection(PacketFlow.SERVERBOUND);
|
||||
|
||||
- ServerConnectionListener.this.connections.add((Connection) object); // CraftBukkit - decompile error
|
||||
+ // ServerConnectionListener.this.connections.add((Connection) object); // CraftBukkit - decompile error
|
||||
+ pending.add((Connection) object); // Paper
|
||||
channel.pipeline().addLast("packet_handler", (ChannelHandler) object);
|
||||
((Connection) object).setListener(new ServerHandshakePacketListenerImpl(ServerConnectionListener.this.server, (Connection) object));
|
||||
}
|
||||
@@ -156,6 +166,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 )
|
||||
{
|
|
@ -1,18 +0,0 @@
|
|||
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 717a0d1c1f4df7ebd5f4cdd5e24cabe3fb66bf06..d00e8486c145200b2431cf92d7049a6d87d55227 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();
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
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 d00e8486c145200b2431cf92d7049a6d87d55227..c7edbd12361cfd3dcf1359917d579fae4c3cc8a7 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 aa6a40eae3a3897ab3cca93921635e4e3e37db9f..34d4157d187ff8485d860eb4f75b898aee06863c 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -1704,7 +1704,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);
|
||||
}
|
|
@ -1,72 +0,0 @@
|
|||
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 5a973c1536291e79aa8377ca5bda8ef84127e20a..a37424bbc6bee02354abaa793aa0865c556c6bbe 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
|
||||
@@ -68,14 +68,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
|
|
@ -1,27 +0,0 @@
|
|||
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 a33a142ba55be937fb19f70239f8327f8b7f236e..299dc4ff01642a5d7229a1e0540c3154e42e25a7 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -1535,13 +1535,14 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
|
||||
// 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;
|
|
@ -1,28 +0,0 @@
|
|||
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 299dc4ff01642a5d7229a1e0540c3154e42e25a7..6aac105a9717b02af648be82fe8e1b2b30bef8a6 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -327,7 +327,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
|
||||
if (this.clientIsFloating && !this.player.isSleeping() && !this.player.isPassenger()) {
|
||||
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 {
|
||||
@@ -346,7 +346,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
|
||||
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 {
|
|
@ -1,48 +0,0 @@
|
|||
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 2a7c82be934a965ba26dc7bf1f60689360bda487..33d1a6b31afec4dbeb00dcabf50c5840852102d6 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/npc/Villager.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java
|
||||
@@ -836,9 +836,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);
|
||||
|
||||
+ // Paper start
|
||||
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityZapEvent(this, lightning, entitywitch).isCancelled()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
+ if (org.spigotmc.SpigotConfig.logVillagerDeaths) Villager.LOGGER.info("Villager {} was struck by lightning {}.", this, lightning); // Paper - move log down, event can cancel
|
||||
+
|
||||
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 97a614e2367439dbface4a258f966c0440ef965d..a2e289ac5e3d0d04b65ec3bf03bebbaad585cc24 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
@@ -1153,6 +1153,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);
|
|
@ -1,29 +0,0 @@
|
|||
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 data from ArmorStand and SpawnEgg items
|
||||
|
||||
|
||||
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 6c4be7da19d0d61f35942558d438587853231aaa..18d81e8e8f387a7fb531652cb78c61a9bd5ae600 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java
|
||||
@@ -316,6 +316,18 @@ public class FallingBlockEntity extends Entity {
|
||||
@Override
|
||||
protected void readAdditionalSaveData(CompoundTag nbt) {
|
||||
this.blockState = NbtUtils.readBlockState(nbt.getCompound("BlockState"));
|
||||
+ // Paper start - Block FallingBlocks with Command Blocks
|
||||
+ final Block b = this.blockState.getBlock();
|
||||
+ if (this.level.paperConfig().entities.spawning.filterNbtDataFromSpawnEggsAndRelated
|
||||
+ && (b == Blocks.COMMAND_BLOCK
|
||||
+ || b == Blocks.REPEATING_COMMAND_BLOCK
|
||||
+ || b == Blocks.CHAIN_COMMAND_BLOCK
|
||||
+ || b == Blocks.JIGSAW
|
||||
+ || b == Blocks.STRUCTURE_BLOCK
|
||||
+ || b instanceof net.minecraft.world.level.block.GameMasterBlock)) {
|
||||
+ this.blockState = Blocks.STONE.defaultBlockState();
|
||||
+ }
|
||||
+ // Paper end
|
||||
this.time = nbt.getInt("Time");
|
||||
if (nbt.contains("HurtEntities", 99)) {
|
||||
this.hurtEntities = nbt.getBoolean("HurtEntities");
|
|
@ -1,73 +0,0 @@
|
|||
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 ff8773f3671970bd759303f7a4bbc17d4df5a1de..13f8f3a2a6382ef51567cc6f46b573d971f700f6 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
@@ -120,6 +120,18 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener
|
||||
|
||||
}
|
||||
|
||||
+ // Paper start - Cache authenticator threads
|
||||
+ private static final AtomicInteger threadId = new AtomicInteger(0);
|
||||
+ private static final java.util.concurrent.ExecutorService authenticatorPool = java.util.concurrent.Executors.newCachedThreadPool(
|
||||
+ r -> {
|
||||
+ Thread ret = new Thread(r, "User Authenticator #" + threadId.incrementAndGet());
|
||||
+
|
||||
+ ret.setUncaughtExceptionHandler(new DefaultUncaughtExceptionHandler(LOGGER));
|
||||
+
|
||||
+ return ret;
|
||||
+ }
|
||||
+ );
|
||||
+ // Paper end
|
||||
// Spigot start
|
||||
public void initUUID()
|
||||
{
|
||||
@@ -258,8 +270,8 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener
|
||||
this.connection.send(new ClientboundHelloPacket("", this.server.getKeyPair().getPublic().getEncoded(), this.nonce));
|
||||
} 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 {
|
||||
@@ -270,7 +282,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
|
||||
}
|
||||
|
||||
@@ -311,7 +324,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;
|
||||
|
||||
@@ -356,10 +370,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
|
|
@ -1,36 +0,0 @@
|
|||
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 34d4157d187ff8485d860eb4f75b898aee06863c..8c041ca80cb20800178f8d4a5584e1b26bf3cb15 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -2556,5 +2556,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
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
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 dba0bc7dc8fd1993f45716a398b1ccf52d3d868b..b3433ce9c722bdab81848a6c2d121ca510c48509 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ExperienceOrb.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ExperienceOrb.java
|
||||
@@ -247,7 +247,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 a2e289ac5e3d0d04b65ec3bf03bebbaad585cc24..09a5c7a95f87e35c43d07974f5884e28833f9777 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
@@ -1112,6 +1112,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);
|
||||
}
|
|
@ -1,109 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Techcable <Techcable@outlook.com>
|
||||
Date: Fri, 16 Dec 2016 21:25:39 -0600
|
||||
Subject: [PATCH] Add ProjectileCollideEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
|
||||
index 7cd802be238cedf166174a61e816d9d4b29b87d2..7f1f4813ac007fbf79e8ba254075c015fe15e3a1 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
|
||||
@@ -226,6 +226,17 @@ public abstract class AbstractArrow extends Projectile {
|
||||
}
|
||||
}
|
||||
|
||||
+ // Paper start - Call ProjectileCollideEvent
|
||||
+ // TODO: flag - noclip - call cancelled?
|
||||
+ if (object instanceof EntityHitResult) {
|
||||
+ com.destroystokyo.paper.event.entity.ProjectileCollideEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callProjectileCollideEvent(this, (EntityHitResult)object);
|
||||
+ if (event.isCancelled()) {
|
||||
+ object = null;
|
||||
+ movingobjectpositionentity = null;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
if (object != null && !flag) {
|
||||
this.preOnHit((HitResult) object); // CraftBukkit - projectile hit event
|
||||
this.hasImpulse = true;
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/projectile/AbstractHurtingProjectile.java b/src/main/java/net/minecraft/world/entity/projectile/AbstractHurtingProjectile.java
|
||||
index 867e50769af3c5bdbed15cfd637e429dcfcb6920..d71dc286673fa7ed708be5bec4c5a6868874c090 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/AbstractHurtingProjectile.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/AbstractHurtingProjectile.java
|
||||
@@ -11,6 +11,7 @@ import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.level.Level;
|
||||
+import net.minecraft.world.phys.EntityHitResult;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit
|
||||
@@ -82,7 +83,16 @@ public abstract class AbstractHurtingProjectile extends Projectile {
|
||||
|
||||
HitResult movingobjectposition = ProjectileUtil.getHitResult(this, this::canHitEntity);
|
||||
|
||||
- if (movingobjectposition.getType() != HitResult.Type.MISS) {
|
||||
+ // Paper start - Call ProjectileCollideEvent
|
||||
+ if (movingobjectposition instanceof EntityHitResult) {
|
||||
+ com.destroystokyo.paper.event.entity.ProjectileCollideEvent event = CraftEventFactory.callProjectileCollideEvent(this, (EntityHitResult)movingobjectposition);
|
||||
+ if (event.isCancelled()) {
|
||||
+ movingobjectposition = null;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
+ if (movingobjectposition != null && movingobjectposition.getType() != HitResult.Type.MISS) { // Paper - add null check in case cancelled
|
||||
this.preOnHit(movingobjectposition); // CraftBukkit - projectile hit event
|
||||
|
||||
// CraftBukkit start - Fire ProjectileHitEvent
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/projectile/ThrowableProjectile.java b/src/main/java/net/minecraft/world/entity/projectile/ThrowableProjectile.java
|
||||
index 88181c59e604ba3b132b9e695cef5eaf5b836029..94d09b05737679b133ec462815b010b19c01b4fa 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/ThrowableProjectile.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/ThrowableProjectile.java
|
||||
@@ -10,6 +10,7 @@ import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.TheEndGatewayBlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
+import net.minecraft.world.phys.EntityHitResult;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
@@ -66,7 +67,17 @@ public abstract class ThrowableProjectile extends Projectile {
|
||||
}
|
||||
|
||||
if (movingobjectposition.getType() != HitResult.Type.MISS && !flag) {
|
||||
+ // Paper start - Call ProjectileCollideEvent
|
||||
+ if (movingobjectposition instanceof EntityHitResult) {
|
||||
+ com.destroystokyo.paper.event.entity.ProjectileCollideEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callProjectileCollideEvent(this, (EntityHitResult)movingobjectposition);
|
||||
+ if (event.isCancelled()) {
|
||||
+ movingobjectposition = null;
|
||||
+ }
|
||||
+ }
|
||||
+ if (movingobjectposition != null) {
|
||||
+ // Paper end
|
||||
this.preOnHit(movingobjectposition); // CraftBukkit - projectile hit event
|
||||
+ } // Paper
|
||||
}
|
||||
|
||||
this.checkInsideBlocks();
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
index 09a5c7a95f87e35c43d07974f5884e28833f9777..e00f87e4a9384c60e5fe4c33a9f27541366ae81b 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
@@ -1256,6 +1256,16 @@ public class CraftEventFactory {
|
||||
return CraftItemStack.asNMSCopy(bitem);
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ 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);
|
|
@ -1,27 +0,0 @@
|
|||
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 ff1e04e5e3b8099b0b71eda1c0de864c809c5029..649c2fdba307d986d13916bf90e311c862ccefc1 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
|
||||
@@ -157,7 +157,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
|
||||
MCUtil.toLocation(this.mob.level, possibleTarget), target == null ? null : target.getBukkitEntity()).callEvent()) {
|
||||
if (!copiedSet) {
|
||||
copiedSet = true;
|
|
@ -1,23 +0,0 @@
|
|||
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 aa2098d3af5cc03f3ff3ad663683c5edbe473756..c8350eae421f5655de490c420dcb284c78f58f62 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/Level.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
||||
@@ -334,6 +334,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;
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
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 6ec5a1525d0b8ced8fe78d3eab29c5eb82996844..2442c287a7f26cfee10a19e9015558cdebdcf3ac 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 91666d0c8116353b80d49941f17a3a8405eb50a7..0f92f2906195f5b2b70ca02a46fa111a46f8f18f 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java
|
||||
@@ -387,6 +387,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);
|
|
@ -1,46 +0,0 @@
|
|||
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 f95999daa1955dd4d919d0e668fe099901a0481c..770a91fcc351a2d1de4762c0fd9bae2b49c363b5 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 321384730cacbdc22eedc53651e4d24f06c73b99..b734c0f9b831c20a239b5341ff3a0b4d6a6c102c 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, new BlockPos(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, new BlockPos(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);
|
|
@ -1,20 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Wed, 21 Dec 2016 03:48:29 -0500
|
||||
Subject: [PATCH] Optimize ItemStack.isEmpty()
|
||||
|
||||
Remove hashMap lookup every check, simplify code to remove ternary
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
index 758f0a620551838e32d5c68f7ee755f7ea374a46..e7dbcacff58ce4b48f315eae80878c136b740416 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
@@ -245,7 +245,7 @@ public final class ItemStack {
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
- return this == ItemStack.EMPTY ? true : (this.getItem() != null && !this.is(Items.AIR) ? this.count <= 0 : true);
|
||||
+ return this == ItemStack.EMPTY || this.item == null || this.item == Items.AIR || this.count <= 0; // Paper
|
||||
}
|
||||
|
||||
public ItemStack split(int amount) {
|
|
@ -1,52 +0,0 @@
|
|||
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 bd0f3295932220e88dfd72b1719651b132a325f9..def35ca400cb315a9eea035026412b69ec51b1a8 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
@@ -91,6 +91,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);
|
||||
@@ -925,4 +926,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
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
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 c8d63359c77ce11711df3ebed295fdd989d601a5..7f4ed398c48534eec4303a394f360f476b7757ad 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
@@ -274,6 +274,26 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
}
|
||||
|
||||
// Paper start
|
||||
+ @Override
|
||||
+ 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
|
||||
+ 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
|
||||
+ 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) {
|
|
@ -1,33 +0,0 @@
|
|||
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 02dd7ca5f7845803623488d7c7e84a2eb22b2d90..5cd7e7eb7c1288cf4c1f13f63b3ea0cc34d6beb8 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -2200,7 +2200,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 6aac105a9717b02af648be82fe8e1b2b30bef8a6..aafeb6643bcc08ae1d88ba2a68f1f6a29c8ce2b7 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -3037,7 +3037,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
|
||||
}
|
||||
|
||||
public final boolean isDisconnected() {
|
||||
- return !this.player.joining && !this.connection.isConnected();
|
||||
+ return (!this.player.joining && !this.connection.isConnected()) || this.processedDisconnect; // Paper
|
||||
}
|
||||
// CraftBukkit end
|
||||
|
|
@ -1,97 +0,0 @@
|
|||
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
|
||||
|
||||
|
||||
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 4abcdc515411372006ff5d33510bdd64092c186a..5406925cd66f46ab8744123c670d72cea7bfc3a1 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/FireworkRocketEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/FireworkRocketEntity.java
|
||||
@@ -39,6 +39,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);
|
||||
@@ -318,6 +319,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
|
||||
@@ -334,7 +340,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 17b797a036ac0f58b58f627dc61ac503c8f321db..d86ec8c4c1c3e7974463a545d80ed9744de0fbbb 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/CrossbowItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/CrossbowItem.java
|
||||
@@ -220,6 +220,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 cdf35c5873f68245891241c0efa3bcf5658c3f6d..766af1f45b14654d3655a06ae0bfb0d4cfbdff7a 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/FireworkRocketItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/FireworkRocketItem.java
|
||||
@@ -44,6 +44,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);
|
||||
}
|
||||
@@ -57,6 +58,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 3a1c3d20ecc3612421e346edbbb74ab47f16a137..be86114eac3975b82ca74d4d6ed3f0402a642e8a 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java
|
||||
@@ -78,4 +78,17 @@ 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;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public org.bukkit.entity.LivingEntity getBoostedEntity() {
|
||||
+ net.minecraft.world.entity.LivingEntity boostedEntity = getHandle().attachedToEntity;
|
||||
+ return boostedEntity != null ? (org.bukkit.entity.LivingEntity) boostedEntity.getBukkitEntity() : null;
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
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 0a792513ac71df24aa8ea4e5d47caad07c22c65e..8a65d379a67630967d07d97fdc528838453763a9 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
|
||||
@@ -11,6 +11,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 net.minecraft.server.MCUtil;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.util.Mth;
|
||||
@@ -210,7 +211,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;
|
|
@ -1,83 +0,0 @@
|
|||
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 c8350eae421f5655de490c420dcb284c78f58f62..4e843d9e28f7775faba3e47ca5a725f7921490e6 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/Level.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
||||
@@ -112,7 +112,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 40d6b00fb40db167c6c80b6a3f79eb82d08cdfb9..40dd3913ac630899206a506ea9dfc58de634f391 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
@@ -152,6 +152,57 @@ 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
|
||||
+ Long2ObjectLinkedOpenHashMap<ChunkHolder> chunks = world.getChunkSource().chunkMap.visibleChunkMap;
|
||||
+ int size = 0;
|
||||
+ for (ChunkHolder playerchunk : chunks.values()) {
|
||||
+ 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 : world.getChunkSource().chunkMap.visibleChunkMap.values()) {
|
||||
+ 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) {
|
|
@ -1,27 +0,0 @@
|
|||
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 3fe3d417b6c1ff49a412c308bfe6a43182d0986e..6c86e18cb59a4e9a906269d570d228f05c700a48 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
@@ -1040,11 +1040,13 @@ public abstract class PlayerList {
|
||||
}
|
||||
|
||||
public void saveAll() {
|
||||
+ net.minecraft.server.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() {
|
|
@ -1,18 +0,0 @@
|
|||
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 a96d50b68d6ce6fe9b36de5af132b2fa6d08961c..9d854cb4722ccd3a665fd29aff8bf368163c30e4 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -2322,6 +2322,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 {
|
|
@ -1,353 +0,0 @@
|
|||
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 cd3b4c97374d44f5a0e710e03f4ac38938757e25..b18bb06caf5f034dffbb72120c8f21da482ae3df 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
|
||||
@@ -419,7 +419,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 b3433ce9c722bdab81848a6c2d121ca510c48509..16a1a005f2dda30cf804bf51638383ef3bfeb43e 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ExperienceOrb.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ExperienceOrb.java
|
||||
@@ -37,13 +37,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) {
|
||||
@@ -153,12 +205,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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,6 +288,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
|
||||
@@ -236,6 +297,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 292f5dddd644880fc759fa8634d633ad40f3bf4f..8c5e4958f087a3f688261a44377dde39bc134b80 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -1723,7 +1723,8 @@ public abstract class LivingEntity extends Entity {
|
||||
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 3cdd7180a41b87caa942d2b3436ba90726686ecb..6216513805add7c8f52e1ed6c77e2d26786b3ab5 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/Animal.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/Animal.java
|
||||
@@ -262,7 +262,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, entityplayer, entityageable)); // Paper
|
||||
}
|
||||
// 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 113b31a5a0247abc436d04ba2fe03cb41ca86f15..fb3b42611d8386b110ea079094d5d50fefceac1a 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/Fox.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/Fox.java
|
||||
@@ -892,7 +892,7 @@ public class Fox extends Animal {
|
||||
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 7c90063be2a7eb66b7f0981059018f20413256c6..37125ffe47fcd5fe93ab62ad8a46e8188f362436 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/Turtle.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/Turtle.java
|
||||
@@ -448,7 +448,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/animal/frog/Frog.java b/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java
|
||||
index fe660bbaa4113fb2ffa1ea2f10e4e1e674fbb86d..bb6063ae7f4438916306ce876057f7488537b444 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java
|
||||
@@ -274,7 +274,7 @@ public class Frog extends Animal {
|
||||
this.getBrain().setMemory(MemoryModuleType.IS_PREGNANT, Unit.INSTANCE);
|
||||
world.broadcastEntityEvent(this, (byte)18);
|
||||
if (world.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) {
|
||||
- world.addFreshEntity(new ExperienceOrb(world, this.getX(), this.getY(), this.getZ(), this.getRandom().nextInt(7) + 1));
|
||||
+ world.addFreshEntity(new ExperienceOrb(world, this.getX(), this.getY(), this.getZ(), this.getRandom().nextInt(7) + 1, org.bukkit.entity.ExperienceOrb.SpawnReason.BREED, serverPlayer)); // 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 0dff7a47ecac1916ad23739fbb06ddd0f0052a65..d0ebcc23d863be630b55245aa2604c108ee6c93a 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
|
||||
@@ -647,7 +647,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()) {
|
||||
@@ -678,7 +678,7 @@ public class EnderDragon extends Mob implements Enemy {
|
||||
this.yBodyRot = this.getYRot();
|
||||
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 33d1a6b31afec4dbeb00dcabf50c5840852102d6..25cd8a4101cf44955d95924c9794c238ddde2901 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/npc/Villager.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java
|
||||
@@ -624,7 +624,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 b9a0fc52460ce0c50deea25112dee20c977e99c5..d7cb3d8b37f225ee4796246aa907da1092fa9a0d 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 00fe96650e4d973e97b46968297f55f4c3674629..11ac510ad4095438d4904d521bfb18aa5f743faf 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java
|
||||
@@ -513,7 +513,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 db6b1a9804a6d75dce22b780044beb04ca69cc94..dcbbff3a8dfcac869f07025e0e8e3d9c47956093 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 dbdba510d8ff3c622ed928151cf525cfd1d1b1b5..aa0ba9c7dcb0ee81c9081031c447eeab61d92a10 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 60c5d4c97a340120f49f51b3d1dc7e6f2a19a936..0422e389e5b9577417d09490a15584ed5b885209 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/Block.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/Block.java
|
||||
@@ -376,8 +376,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 e90fa66b4716f55844818a2770d9e02d68658e46..bbccb2f97ee88fe43af4eec30fbb2ecea1ebb1b4 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
|
||||
@@ -642,7 +642,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 e1f478359d959157f60b866ab59bba3b5b16521c..c4f8d2c090e3cde562a2ab6103da53ded666599b 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java
|
||||
@@ -909,7 +909,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;
|
|
@ -1,42 +0,0 @@
|
|||
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 9d854cb4722ccd3a665fd29aff8bf368163c30e4..1daffb325617f8e9f3218aa879eb7d8467d69447 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -379,6 +379,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 8c5e4958f087a3f688261a44377dde39bc134b80..20bc6684b0394fe08aa35c371bf668d8ebcf98b1 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -3261,8 +3261,11 @@ public abstract class LivingEntity extends Entity {
|
||||
}
|
||||
}
|
||||
|
||||
- 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);
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
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
|
|
@ -1,23 +0,0 @@
|
|||
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 def35ca400cb315a9eea035026412b69ec51b1a8..ed698f3e3f9ed6003fe621c5f6f7e3a151a1a559 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
@@ -934,5 +934,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
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Brokkonaut <hannos17@gmx.de>
|
||||
Date: Tue, 7 Feb 2017 16:55:35 -0600
|
||||
Subject: [PATCH] Make targetSize more aggressive in the chunk unload queue
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
index e1200e903e39c3e5cb023e1bd4fe104907c0c6eb..702d885b6a5caf8cabc40934893a081b01906781 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -232,7 +232,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
this.entityMap = new Int2ObjectOpenHashMap();
|
||||
this.chunkTypeCache = new Long2ByteOpenHashMap();
|
||||
this.chunkSaveCooldowns = new Long2LongOpenHashMap();
|
||||
- this.unloadQueue = Queues.newConcurrentLinkedQueue();
|
||||
+ this.unloadQueue = new com.destroystokyo.paper.utils.CachedSizeConcurrentLinkedQueue<>(); // Paper - need constant-time size()
|
||||
this.structureTemplateManager = structureTemplateManager;
|
||||
Path path = session.getDimensionPath(world.dimension());
|
||||
|
||||
@@ -587,7 +587,6 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
|
||||
private void processUnloads(BooleanSupplier shouldKeepTicking) {
|
||||
LongIterator longiterator = this.toDrop.iterator();
|
||||
-
|
||||
for (int i = 0; longiterator.hasNext() && (shouldKeepTicking.getAsBoolean() || i < 200 || this.toDrop.size() > 2000); longiterator.remove()) {
|
||||
long j = longiterator.nextLong();
|
||||
ChunkHolder playerchunk = (ChunkHolder) this.updatingChunkMap.remove(j);
|
||||
@@ -600,7 +599,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
}
|
||||
}
|
||||
|
||||
- int k = Math.max(0, this.unloadQueue.size() - 2000);
|
||||
+ int k = Math.max(100, this.unloadQueue.size() - 2000); // Paper - Unload more than just up to queue size 2000
|
||||
|
||||
Runnable runnable;
|
||||
|
|
@ -1,290 +0,0 @@
|
|||
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 c7b740087003113a00c5eccc9b0405b62b9da2b7..ff7cc68eeb1aa61c06d50ed47211009d51b2b234 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -219,6 +219,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
public final 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;
|
||||
@@ -882,7 +883,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
|
||||
}
|
||||
|
||||
@@ -962,6 +963,12 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
}
|
||||
|
||||
public void halt(boolean flag) {
|
||||
+ // Paper start - allow passing of the intent to restart
|
||||
+ this.safeShutdown(flag, false);
|
||||
+ }
|
||||
+ public void safeShutdown(boolean flag, boolean isRestarting) {
|
||||
+ this.isRestarting = isRestarting;
|
||||
+ // Paper end
|
||||
this.running = false;
|
||||
if (flag) {
|
||||
try {
|
||||
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
index 6c86e18cb59a4e9a906269d570d228f05c700a48..b28bb51e5476b250d9de91f2e380dd8ed2aa7041 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
@@ -1151,8 +1151,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
|
||||
+
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
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?
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index aafeb6643bcc08ae1d88ba2a68f1f6a29c8ce2b7..61752ae5602e901ed03037cb2dee29f461b68cac 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -2259,6 +2259,13 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
|
||||
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 fdda98cb38ec96d0189931c41257cc01966373d5..9aa134e56d661d033bb7229e6ab662534bf9cba9 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
@@ -587,7 +587,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) {
|
||||
- this.removeEntitiesOnShoulder();
|
||||
+ if (!this.level.paperConfig().entities.behavior.parrotsAreUnaffectedByPlayerMovement) this.removeEntitiesOnShoulder(); // Paper - Hang on!
|
||||
}
|
||||
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
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 8c041ca80cb20800178f8d4a5584e1b26bf3cb15..be392b054d3fe86118265cbe65067e83b37f36e8 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -2575,5 +2575,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
|
||||
}
|
|
@ -1,518 +0,0 @@
|
|||
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 cfdb20447e6ad3efcdee8889712f77931773beaf..d4141a24cb5ba20e8c53c85206b32120ff18eb48 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.17.1") // Paper
|
||||
implementation("org.ow2.asm:asm:9.3")
|
||||
implementation("org.ow2.asm:asm-commons:9.3") // 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 ff7cc68eeb1aa61c06d50ed47211009d51b2b234..a4d14a12a5ede30f1e124bfaa5552e70f590dd09 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -157,7 +157,7 @@ import org.slf4j.Logger;
|
||||
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.server.bossevents.CustomBossEvents;
|
||||
import net.minecraft.server.dedicated.DedicatedServer;
|
||||
@@ -269,7 +269,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;
|
||||
@@ -353,7 +353,9 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
this.datapackconfiguration = datapackconfiguration;
|
||||
this.registryreadops = registryreadops;
|
||||
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;
|
||||
@@ -374,6 +376,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
|
||||
}
|
||||
@@ -1140,7 +1144,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
|
||||
@@ -1554,7 +1558,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 ee509d7b06a9785a39b59329a19531047953831b..b248c0f481436b1b101dc1f75eaaf8023f4ba0ea 100644
|
||||
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
@@ -103,6 +103,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
|
||||
@@ -134,7 +137,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
|
||||
}
|
||||
@@ -142,6 +145,8 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
|
||||
DedicatedServer.LOGGER.error("Exception handling console input", ioexception);
|
||||
}
|
||||
|
||||
+ */
|
||||
+ // Paper end
|
||||
}
|
||||
};
|
||||
|
||||
@@ -153,6 +158,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) {
|
||||
@@ -161,6 +169,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 b28bb51e5476b250d9de91f2e380dd8ed2aa7041..9cb9e0a4d1467cb5c23dfd38e83d495a3907d984 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
@@ -159,8 +159,7 @@ public abstract class PlayerList {
|
||||
|
||||
public PlayerList(MinecraftServer server, RegistryAccess.Frozen 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 be392b054d3fe86118265cbe65067e83b37f36e8..ad469e105871105a3918f9213bc9f27263955063 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -45,7 +45,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;
|
||||
@@ -1274,9 +1273,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 d7766aaaaa9fd69aae162046cbd2410f8bfeb14c..c59c72e36db34820ddaf881086a65ec36d79f58d 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/Main.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/Main.java
|
||||
@@ -12,7 +12,7 @@ import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import joptsimple.OptionParser;
|
||||
import joptsimple.OptionSet;
|
||||
-import org.fusesource.jansi.AnsiConsole;
|
||||
+import net.minecrell.terminalconsole.TerminalConsoleAppender; // Paper
|
||||
|
||||
public class Main {
|
||||
public static boolean useJline = true;
|
||||
@@ -200,6 +200,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'});
|
||||
@@ -217,9 +219,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(TerminalConsoleAppender.JLINE_OVERRIDE_PROPERTY, "false");
|
||||
+ useJline = false;
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
if (options.has("noconsole")) {
|
||||
Main.useConsole = false;
|
||||
+ useJline = false; // Paper
|
||||
+ System.setProperty(TerminalConsoleAppender.JLINE_OVERRIDE_PROPERTY, "false"); // Paper
|
||||
}
|
||||
|
||||
if (false && Main.class.getPackage().getImplementationVendor() != null && System.getProperty("IReallyKnowWhatIAmDoingISwear") == null) {
|
||||
@@ -247,7 +258,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>
|
|
@ -1,20 +0,0 @@
|
|||
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 7a5eea3a2eaff5e08589fc240307da2beb44c307..441eee3d3a639b8eccc4369de0d9e3e7d28bac27 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Creeper.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Creeper.java
|
||||
@@ -281,7 +281,7 @@ public class Creeper extends Monster implements PowerableMob {
|
||||
private void spawnLingeringCloud() {
|
||||
Collection<MobEffectInstance> collection = this.getActiveEffects();
|
||||
|
||||
- if (!collection.isEmpty()) {
|
||||
+ if (!collection.isEmpty() && !level.paperConfig().entities.behavior.disableCreeperLingeringEffect) { // Paper
|
||||
AreaEffectCloud entityareaeffectcloud = new AreaEffectCloud(this.level, this.getX(), this.getY(), this.getZ());
|
||||
|
||||
entityareaeffectcloud.setOwner(this); // CraftBukkit
|
|
@ -1,57 +0,0 @@
|
|||
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 c09f1ac470c4055897f8d6c6201bd8dc421cdbfe..049a9c4547428d7306d82ed35bcd470ae6f3efc3 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Mob.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Mob.java
|
||||
@@ -629,6 +629,11 @@ public abstract class Mob extends LivingEntity {
|
||||
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 5a3b0ceb77d6a4c7d8da5ab93ddb1b3b4452027f..ab34a42c33a828d610a5732381487a6a1a64f801 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java
|
||||
@@ -52,6 +52,7 @@ public class ItemEntity extends Entity {
|
||||
private UUID owner;
|
||||
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 4ca76a7530f8679567d887cdf1491d110e7465ec..30c954efba587d69ff55df509339f03e7d5a476e 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.setOwner(uuid);
|
|
@ -1,46 +0,0 @@
|
|||
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 ab34a42c33a828d610a5732381487a6a1a64f801..c9aa79cd6846ea8b04ad0c77fbf5aff3ce216505 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java
|
||||
@@ -390,6 +390,7 @@ public class ItemEntity extends Entity {
|
||||
// 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);
|
||||
@@ -397,8 +398,14 @@ public class ItemEntity extends Entity {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -428,7 +435,11 @@ public class ItemEntity extends Entity {
|
||||
// CraftBukkit end
|
||||
|
||||
if (this.pickupDelay == 0 && (this.owner == null || this.owner.equals(player.getUUID())) && player.getInventory().add(itemstack)) {
|
||||
- player.take(this, i);
|
||||
+ // Paper Start
|
||||
+ if (flyAtPlayer) {
|
||||
+ player.take(this, i);
|
||||
+ }
|
||||
+ // Paper End
|
||||
if (itemstack.isEmpty()) {
|
||||
this.discard();
|
||||
itemstack.setCount(i);
|
|
@ -1,41 +0,0 @@
|
|||
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 c9aa79cd6846ea8b04ad0c77fbf5aff3ce216505..a0b27bdeabcabd0bd07b1b495105f9b6af998092 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java
|
||||
@@ -36,6 +36,7 @@ import net.minecraft.util.Mth;
|
||||
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 {
|
||||
|
||||
@@ -392,6 +393,22 @@ public class ItemEntity extends Entity {
|
||||
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
|
|
@ -1,77 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
Date: Sun, 8 Aug 2021 16:26:46 -0700
|
||||
Subject: [PATCH] Do not submit profile lookups to worldgen threads
|
||||
|
||||
They block. On network I/O.
|
||||
|
||||
If enough tasks are submitted the server will eventually stall
|
||||
out due to a sync load, as the worldgen threads will be
|
||||
stalling on profile lookups.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/Util.java b/src/main/java/net/minecraft/Util.java
|
||||
index d7e22ddf89619b58516ccef1d75a4c33df61b73c..33ec7786cdf8c32e905d192fc8364418e47404d5 100644
|
||||
--- a/src/main/java/net/minecraft/Util.java
|
||||
+++ b/src/main/java/net/minecraft/Util.java
|
||||
@@ -80,6 +80,22 @@ public class Util {
|
||||
private static final AtomicInteger WORKER_COUNT = new AtomicInteger(1);
|
||||
private static final ExecutorService BOOTSTRAP_EXECUTOR = makeExecutor("Bootstrap");
|
||||
private static final ExecutorService BACKGROUND_EXECUTOR = makeExecutor("Main");
|
||||
+ // Paper start - don't submit BLOCKING PROFILE LOOKUPS to the world gen thread
|
||||
+ public static final ExecutorService PROFILE_EXECUTOR = Executors.newFixedThreadPool(2, new java.util.concurrent.ThreadFactory() {
|
||||
+
|
||||
+ private final AtomicInteger count = new AtomicInteger();
|
||||
+
|
||||
+ @Override
|
||||
+ public Thread newThread(Runnable run) {
|
||||
+ Thread ret = new Thread(run);
|
||||
+ ret.setName("Profile Lookup Executor #" + this.count.getAndIncrement());
|
||||
+ ret.setUncaughtExceptionHandler((Thread thread, Throwable throwable) -> {
|
||||
+ LOGGER.error("Uncaught exception in thread " + thread.getName(), throwable);
|
||||
+ });
|
||||
+ return ret;
|
||||
+ }
|
||||
+ });
|
||||
+ // Paper end - don't submit BLOCKING PROFILE LOOKUPS to the world gen thread
|
||||
private static final ExecutorService IO_POOL = makeIoExecutor();
|
||||
public static LongSupplier timeSource = System::nanoTime;
|
||||
public static final Ticker TICKER = new Ticker() {
|
||||
diff --git a/src/main/java/net/minecraft/server/players/GameProfileCache.java b/src/main/java/net/minecraft/server/players/GameProfileCache.java
|
||||
index c7edbd12361cfd3dcf1359917d579fae4c3cc8a7..6c8a1d9c7696fa55dae6ba5e4ea50a0ffc7ea543 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/GameProfileCache.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/GameProfileCache.java
|
||||
@@ -181,7 +181,7 @@ public class GameProfileCache {
|
||||
} else {
|
||||
this.requests.put(username, CompletableFuture.supplyAsync(() -> {
|
||||
return this.get(username);
|
||||
- }, Util.backgroundExecutor()).whenCompleteAsync((optional, throwable) -> {
|
||||
+ }, Util.PROFILE_EXECUTOR).whenCompleteAsync((optional, throwable) -> { // Paper - not a good idea to use BLOCKING OPERATIONS on the worldgen executor
|
||||
this.requests.remove(username);
|
||||
}, this.executor).whenCompleteAsync((optional, throwable) -> {
|
||||
consumer.accept(optional);
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java
|
||||
index 0c7e29b589ab106013d979a20edc415b4b32a677..c5d5d90d10b30f30d1262367b3d75df43fbdb231 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java
|
||||
@@ -120,7 +120,7 @@ public class SkullBlockEntity extends BlockEntity {
|
||||
public static void updateGameprofile(@Nullable GameProfile owner, Consumer<GameProfile> callback) {
|
||||
if (owner != null && !StringUtil.isNullOrEmpty(owner.getName()) && (!owner.isComplete() || !owner.getProperties().containsKey("textures")) && profileCache != null && sessionService != null) {
|
||||
profileCache.getAsync(owner.getName(), (profile) -> {
|
||||
- Util.backgroundExecutor().execute(() -> {
|
||||
+ Util.PROFILE_EXECUTOR.execute(() -> { // Paper - not a good idea to use BLOCKING OPERATIONS on the worldgen executor
|
||||
Util.ifElse(profile, (profilex) -> {
|
||||
Property property = Iterables.getFirst(profilex.getProperties().get("textures"), (Property)null);
|
||||
if (property == null) {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/profile/CraftPlayerProfile.java b/src/main/java/org/bukkit/craftbukkit/profile/CraftPlayerProfile.java
|
||||
index 2d49bd6f3f017d43dfaa23cedf35040b64bcdcf8..9edc5e73819e0b55372f77c5e292eece74d837c7 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/profile/CraftPlayerProfile.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/profile/CraftPlayerProfile.java
|
||||
@@ -121,7 +121,7 @@ public final class CraftPlayerProfile implements PlayerProfile {
|
||||
|
||||
@Override
|
||||
public CompletableFuture<PlayerProfile> update() {
|
||||
- return CompletableFuture.supplyAsync(this::getUpdatedProfile, Util.backgroundExecutor());
|
||||
+ return CompletableFuture.supplyAsync(this::getUpdatedProfile, Util.PROFILE_EXECUTOR); // Paper - not a good idea to use BLOCKING OPERATIONS on the worldgen executor
|
||||
}
|
||||
|
||||
private CraftPlayerProfile getUpdatedProfile() {
|
|
@ -1,25 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Sweepyoface <github@sweepy.pw>
|
||||
Date: Sat, 17 Jun 2017 18:48:21 -0400
|
||||
Subject: [PATCH] Add UnknownCommandEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index ad469e105871105a3918f9213bc9f27263955063..6d9ec963c1f0c5ee477ee4d84862a3c699eeba46 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -890,7 +890,13 @@ public final class CraftServer implements Server {
|
||||
|
||||
// Spigot start
|
||||
if (!org.spigotmc.SpigotConfig.unknownCommandMessage.isEmpty()) {
|
||||
- sender.sendMessage(org.spigotmc.SpigotConfig.unknownCommandMessage);
|
||||
+ // Paper start
|
||||
+ org.bukkit.event.command.UnknownCommandEvent event = new org.bukkit.event.command.UnknownCommandEvent(sender, commandLine, org.spigotmc.SpigotConfig.unknownCommandMessage);
|
||||
+ Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
+ if (event.message() != null) {
|
||||
+ sender.sendMessage(event.message());
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
// Spigot end
|
||||
|
|
@ -1,760 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 15 Jan 2018 22:11:48 -0500
|
||||
Subject: [PATCH] Basic PlayerProfile API
|
||||
|
||||
Establishes base extension of profile systems for future edits too
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/profile/CraftPlayerProfile.java b/src/main/java/com/destroystokyo/paper/profile/CraftPlayerProfile.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..3ff790cec1ad89caec4be64421dd7d51652be598
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/profile/CraftPlayerProfile.java
|
||||
@@ -0,0 +1,399 @@
|
||||
+package com.destroystokyo.paper.profile;
|
||||
+
|
||||
+import io.papermc.paper.configuration.GlobalConfiguration;
|
||||
+import com.google.common.base.Charsets;
|
||||
+import com.google.common.collect.Iterables;
|
||||
+import com.mojang.authlib.GameProfile;
|
||||
+import com.mojang.authlib.properties.Property;
|
||||
+import com.mojang.authlib.properties.PropertyMap;
|
||||
+import net.minecraft.Util;
|
||||
+import net.minecraft.server.MinecraftServer;
|
||||
+import net.minecraft.server.players.GameProfileCache;
|
||||
+import org.apache.commons.lang3.Validate;
|
||||
+import org.bukkit.configuration.serialization.SerializableAs;
|
||||
+import org.bukkit.craftbukkit.configuration.ConfigSerializationUtil;
|
||||
+import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||
+import org.bukkit.craftbukkit.profile.CraftPlayerTextures;
|
||||
+import org.bukkit.craftbukkit.profile.CraftProfileProperty;
|
||||
+import org.bukkit.profile.PlayerTextures;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+import javax.annotation.Nonnull;
|
||||
+import javax.annotation.Nullable;
|
||||
+import java.util.*;
|
||||
+import java.util.concurrent.CompletableFuture;
|
||||
+
|
||||
+@SerializableAs("PlayerProfile")
|
||||
+public class CraftPlayerProfile implements PlayerProfile, SharedPlayerProfile {
|
||||
+
|
||||
+ private GameProfile profile;
|
||||
+ private final PropertySet properties = new PropertySet();
|
||||
+
|
||||
+ public CraftPlayerProfile(CraftPlayer player) {
|
||||
+ this.profile = player.getHandle().getGameProfile();
|
||||
+ }
|
||||
+
|
||||
+ public CraftPlayerProfile(UUID id, String name) {
|
||||
+ this.profile = new GameProfile(id, name);
|
||||
+ }
|
||||
+
|
||||
+ public CraftPlayerProfile(GameProfile profile) {
|
||||
+ Validate.notNull(profile, "GameProfile cannot be null!");
|
||||
+ this.profile = profile;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean hasProperty(String property) {
|
||||
+ return profile.getProperties().containsKey(property);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setProperty(ProfileProperty property) {
|
||||
+ String name = property.getName();
|
||||
+ PropertyMap properties = profile.getProperties();
|
||||
+ properties.removeAll(name);
|
||||
+ properties.put(name, new Property(name, property.getValue(), property.getSignature()));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public CraftPlayerTextures getTextures() {
|
||||
+ return new CraftPlayerTextures(this);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setTextures(@Nullable PlayerTextures textures) {
|
||||
+ if (textures == null) {
|
||||
+ this.removeProperty("textures");
|
||||
+ } else {
|
||||
+ CraftPlayerTextures craftPlayerTextures = new CraftPlayerTextures(this);
|
||||
+ craftPlayerTextures.copyFrom(textures);
|
||||
+ craftPlayerTextures.rebuildPropertyIfDirty();
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public GameProfile getGameProfile() {
|
||||
+ return profile;
|
||||
+ }
|
||||
+
|
||||
+ @Nullable
|
||||
+ @Override
|
||||
+ public UUID getId() {
|
||||
+ return profile.getId();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ @Deprecated(forRemoval = true)
|
||||
+ public UUID setId(@Nullable UUID uuid) {
|
||||
+ GameProfile prev = this.profile;
|
||||
+ this.profile = new GameProfile(uuid, prev.getName());
|
||||
+ copyProfileProperties(prev, this.profile);
|
||||
+ return prev.getId();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public UUID getUniqueId() {
|
||||
+ return getId();
|
||||
+ }
|
||||
+
|
||||
+ @Nullable
|
||||
+ @Override
|
||||
+ public String getName() {
|
||||
+ return profile.getName();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ @Deprecated(forRemoval = true)
|
||||
+ public String setName(@Nullable String name) {
|
||||
+ GameProfile prev = this.profile;
|
||||
+ this.profile = new GameProfile(prev.getId(), name);
|
||||
+ copyProfileProperties(prev, this.profile);
|
||||
+ return prev.getName();
|
||||
+ }
|
||||
+
|
||||
+ @Nonnull
|
||||
+ @Override
|
||||
+ public Set<ProfileProperty> getProperties() {
|
||||
+ return properties;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setProperties(Collection<ProfileProperty> properties) {
|
||||
+ properties.forEach(this::setProperty);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void clearProperties() {
|
||||
+ profile.getProperties().clear();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean removeProperty(String property) {
|
||||
+ return !profile.getProperties().removeAll(property).isEmpty();
|
||||
+ }
|
||||
+
|
||||
+ @Nullable
|
||||
+ @Override
|
||||
+ public Property getProperty(String property) {
|
||||
+ return Iterables.getFirst(this.profile.getProperties().get(property), null);
|
||||
+ }
|
||||
+
|
||||
+ @Nullable
|
||||
+ @Override
|
||||
+ public void setProperty(@NotNull String propertyName, @Nullable Property property) {
|
||||
+ PropertyMap properties = profile.getProperties();
|
||||
+ properties.removeAll(propertyName);
|
||||
+ if (property != null) {
|
||||
+ properties.put(propertyName, property);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public @NotNull GameProfile buildGameProfile() {
|
||||
+ GameProfile profile = new GameProfile(this.profile.getId(), this.profile.getName());
|
||||
+ profile.getProperties().putAll(this.profile.getProperties());
|
||||
+ return profile;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public CraftPlayerProfile clone() {
|
||||
+ CraftPlayerProfile clone = new CraftPlayerProfile(this.getId(), this.getName());
|
||||
+ clone.setProperties(getProperties());
|
||||
+ return clone;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isComplete() {
|
||||
+ return profile.isComplete();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public @NotNull CompletableFuture<PlayerProfile> update() {
|
||||
+ return CompletableFuture.supplyAsync(() -> {
|
||||
+ final CraftPlayerProfile clone = clone();
|
||||
+ clone.complete(true);
|
||||
+ return clone;
|
||||
+ }, Util.PROFILE_EXECUTOR);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean completeFromCache() {
|
||||
+ return completeFromCache(false, GlobalConfiguration.get().proxies.isProxyOnlineMode());
|
||||
+ }
|
||||
+
|
||||
+ public boolean completeFromCache(boolean onlineMode) {
|
||||
+ return completeFromCache(false, onlineMode);
|
||||
+ }
|
||||
+
|
||||
+ public boolean completeFromCache(boolean lookupUUID, boolean onlineMode) {
|
||||
+ MinecraftServer server = MinecraftServer.getServer();
|
||||
+ String name = profile.getName();
|
||||
+ GameProfileCache userCache = server.getProfileCache();
|
||||
+ if (profile.getId() == null) {
|
||||
+ final GameProfile profile;
|
||||
+ if (onlineMode) {
|
||||
+ profile = lookupUUID ? userCache.get(name).orElse(null) : userCache.getProfileIfCached(name);
|
||||
+ } else {
|
||||
+ // Make an OfflinePlayer using an offline mode UUID since the name has no profile
|
||||
+ profile = new GameProfile(UUID.nameUUIDFromBytes(("OfflinePlayer:" + name).getBytes(Charsets.UTF_8)), name);
|
||||
+ }
|
||||
+ if (profile != null) {
|
||||
+ // if old has it, assume its newer, so overwrite, else use cached if it was set and ours wasn't
|
||||
+ copyProfileProperties(this.profile, profile);
|
||||
+ this.profile = profile;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if ((profile.getName() == null || !hasTextures()) && profile.getId() != null) {
|
||||
+ Optional<GameProfile> optProfile = userCache.get(this.profile.getId());
|
||||
+ if (optProfile.isPresent()) {
|
||||
+ GameProfile profile = optProfile.get();
|
||||
+ if (this.profile.getName() == null) {
|
||||
+ // if old has it, assume its newer, so overwrite, else use cached if it was set and ours wasn't
|
||||
+ copyProfileProperties(this.profile, profile);
|
||||
+ this.profile = profile;
|
||||
+ } else {
|
||||
+ copyProfileProperties(profile, this.profile);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ return this.profile.isComplete();
|
||||
+ }
|
||||
+
|
||||
+ public boolean complete(boolean textures) {
|
||||
+ return complete(textures, GlobalConfiguration.get().proxies.isProxyOnlineMode());
|
||||
+ }
|
||||
+ public boolean complete(boolean textures, boolean onlineMode) {
|
||||
+ MinecraftServer server = MinecraftServer.getServer();
|
||||
+ boolean isCompleteFromCache = this.completeFromCache(true, onlineMode);
|
||||
+ if (onlineMode && (!isCompleteFromCache || textures && !hasTextures())) {
|
||||
+ GameProfile result = server.getSessionService().fillProfileProperties(profile, true);
|
||||
+ if (result != null) {
|
||||
+ copyProfileProperties(result, this.profile, true);
|
||||
+ }
|
||||
+ if (this.profile.isComplete()) {
|
||||
+ server.getProfileCache().add(this.profile);
|
||||
+ }
|
||||
+ }
|
||||
+ return profile.isComplete() && (!onlineMode || !textures || hasTextures());
|
||||
+ }
|
||||
+
|
||||
+ private static void copyProfileProperties(GameProfile source, GameProfile target) {
|
||||
+ copyProfileProperties(source, target, false);
|
||||
+ }
|
||||
+
|
||||
+ private static void copyProfileProperties(GameProfile source, GameProfile target, boolean clearTarget) {
|
||||
+ PropertyMap sourceProperties = source.getProperties();
|
||||
+ PropertyMap targetProperties = target.getProperties();
|
||||
+ if (clearTarget) targetProperties.clear();
|
||||
+ if (sourceProperties.isEmpty()) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ for (Property property : sourceProperties.values()) {
|
||||
+ targetProperties.removeAll(property.getName());
|
||||
+ targetProperties.put(property.getName(), property);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private static ProfileProperty toBukkit(Property property) {
|
||||
+ return new ProfileProperty(property.getName(), property.getValue(), property.getSignature());
|
||||
+ }
|
||||
+
|
||||
+ public static PlayerProfile asBukkitCopy(GameProfile gameProfile) {
|
||||
+ CraftPlayerProfile profile = new CraftPlayerProfile(gameProfile.getId(), gameProfile.getName());
|
||||
+ copyProfileProperties(gameProfile, profile.profile);
|
||||
+ return profile;
|
||||
+ }
|
||||
+
|
||||
+ public static PlayerProfile asBukkitMirror(GameProfile profile) {
|
||||
+ return new CraftPlayerProfile(profile);
|
||||
+ }
|
||||
+
|
||||
+ public static Property asAuthlib(ProfileProperty property) {
|
||||
+ return new Property(property.getName(), property.getValue(), property.getSignature());
|
||||
+ }
|
||||
+
|
||||
+ public static GameProfile asAuthlibCopy(PlayerProfile profile) {
|
||||
+ CraftPlayerProfile craft = ((CraftPlayerProfile) profile);
|
||||
+ return asAuthlib(craft.clone());
|
||||
+ }
|
||||
+
|
||||
+ public static GameProfile asAuthlib(PlayerProfile profile) {
|
||||
+ CraftPlayerProfile craft = ((CraftPlayerProfile) profile);
|
||||
+ return craft.getGameProfile();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public @NotNull Map<String, Object> serialize() {
|
||||
+ Map<String, Object> map = new LinkedHashMap<>();
|
||||
+ if (this.getId() != null) {
|
||||
+ map.put("uniqueId", this.getId().toString());
|
||||
+ }
|
||||
+ if (this.getName() != null) {
|
||||
+ map.put("name", getName());
|
||||
+ }
|
||||
+ if (!this.properties.isEmpty()) {
|
||||
+ List<Object> propertiesData = new ArrayList<>();
|
||||
+ for (ProfileProperty property : properties) {
|
||||
+ propertiesData.add(CraftProfileProperty.serialize(new Property(property.getName(), property.getValue(), property.getSignature())));
|
||||
+ }
|
||||
+ map.put("properties", propertiesData);
|
||||
+ }
|
||||
+ return map;
|
||||
+ }
|
||||
+
|
||||
+ public static CraftPlayerProfile deserialize(Map<String, Object> map) {
|
||||
+ UUID uniqueId = ConfigSerializationUtil.getUuid(map, "uniqueId", true);
|
||||
+ String name = ConfigSerializationUtil.getString(map, "name", true);
|
||||
+
|
||||
+ // This also validates the deserialized unique id and name (ensures that not both are null):
|
||||
+ CraftPlayerProfile profile = new CraftPlayerProfile(uniqueId, name);
|
||||
+
|
||||
+ if (map.containsKey("properties")) {
|
||||
+ for (Object propertyData : (List<?>) map.get("properties")) {
|
||||
+ if (!(propertyData instanceof Map)) {
|
||||
+ throw new IllegalArgumentException("Property data (" + propertyData + ") is not a valid Map");
|
||||
+ }
|
||||
+ Property property = CraftProfileProperty.deserialize((Map<?, ?>) propertyData);
|
||||
+ profile.profile.getProperties().put(property.getName(), property);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return profile;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean equals(Object obj) {
|
||||
+ if (this == obj) return true;
|
||||
+ if (!(obj instanceof CraftPlayerProfile otherProfile)) return false;
|
||||
+ return Objects.equals(this.profile, otherProfile.profile);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public String toString() {
|
||||
+ return "CraftPlayerProfile [uniqueId=" + getId() +
|
||||
+ ", name=" + getName() +
|
||||
+ ", properties=" + org.bukkit.craftbukkit.profile.CraftPlayerProfile.toString(this.profile.getProperties()) +
|
||||
+ "]";
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int hashCode() {
|
||||
+ return this.profile.hashCode();
|
||||
+ }
|
||||
+
|
||||
+ private class PropertySet extends AbstractSet<ProfileProperty> {
|
||||
+
|
||||
+ @Override
|
||||
+ @Nonnull
|
||||
+ public Iterator<ProfileProperty> iterator() {
|
||||
+ return new ProfilePropertyIterator(profile.getProperties().values().iterator());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int size() {
|
||||
+ return profile.getProperties().size();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean add(ProfileProperty property) {
|
||||
+ setProperty(property);
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean addAll(Collection<? extends ProfileProperty> c) {
|
||||
+ //noinspection unchecked
|
||||
+ setProperties((Collection<ProfileProperty>) c);
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean contains(Object o) {
|
||||
+ return o instanceof ProfileProperty && profile.getProperties().containsKey(((ProfileProperty) o).getName());
|
||||
+ }
|
||||
+
|
||||
+ private class ProfilePropertyIterator implements Iterator<ProfileProperty> {
|
||||
+ private final Iterator<Property> iterator;
|
||||
+
|
||||
+ ProfilePropertyIterator(Iterator<Property> iterator) {
|
||||
+ this.iterator = iterator;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean hasNext() {
|
||||
+ return iterator.hasNext();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public ProfileProperty next() {
|
||||
+ return toBukkit(iterator.next());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void remove() {
|
||||
+ iterator.remove();
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/profile/PaperAuthenticationService.java b/src/main/java/com/destroystokyo/paper/profile/PaperAuthenticationService.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..1459a1f99fe614d072a087cda18788cf13102645
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/profile/PaperAuthenticationService.java
|
||||
@@ -0,0 +1,31 @@
|
||||
+package com.destroystokyo.paper.profile;
|
||||
+
|
||||
+import com.mojang.authlib.*;
|
||||
+import com.mojang.authlib.minecraft.MinecraftSessionService;
|
||||
+import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService;
|
||||
+import com.mojang.authlib.yggdrasil.YggdrasilEnvironment;
|
||||
+
|
||||
+import java.net.Proxy;
|
||||
+
|
||||
+public class PaperAuthenticationService extends YggdrasilAuthenticationService {
|
||||
+ private final Environment environment;
|
||||
+ public PaperAuthenticationService(Proxy proxy) {
|
||||
+ super(proxy);
|
||||
+ this.environment = EnvironmentParser.getEnvironmentFromProperties().orElse(YggdrasilEnvironment.PROD.getEnvironment());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public UserAuthentication createUserAuthentication(Agent agent) {
|
||||
+ return new PaperUserAuthentication(this, agent);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public MinecraftSessionService createMinecraftSessionService() {
|
||||
+ return new PaperMinecraftSessionService(this, this.environment);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public GameProfileRepository createProfileRepository() {
|
||||
+ return new PaperGameProfileRepository(this, this.environment);
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/profile/PaperGameProfileRepository.java b/src/main/java/com/destroystokyo/paper/profile/PaperGameProfileRepository.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..582c169c85ac66f1f9430f79042e4655f776c157
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/profile/PaperGameProfileRepository.java
|
||||
@@ -0,0 +1,18 @@
|
||||
+package com.destroystokyo.paper.profile;
|
||||
+
|
||||
+import com.mojang.authlib.Agent;
|
||||
+import com.mojang.authlib.Environment;
|
||||
+import com.mojang.authlib.ProfileLookupCallback;
|
||||
+import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService;
|
||||
+import com.mojang.authlib.yggdrasil.YggdrasilGameProfileRepository;
|
||||
+
|
||||
+public class PaperGameProfileRepository extends YggdrasilGameProfileRepository {
|
||||
+ public PaperGameProfileRepository(YggdrasilAuthenticationService authenticationService, Environment environment) {
|
||||
+ super(authenticationService, environment);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void findProfilesByNames(String[] names, Agent agent, ProfileLookupCallback callback) {
|
||||
+ super.findProfilesByNames(names, agent, callback);
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/profile/PaperMinecraftSessionService.java b/src/main/java/com/destroystokyo/paper/profile/PaperMinecraftSessionService.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..93d73c27340645c7502acafdc0b2cfbc1a759dd8
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/profile/PaperMinecraftSessionService.java
|
||||
@@ -0,0 +1,30 @@
|
||||
+package com.destroystokyo.paper.profile;
|
||||
+
|
||||
+import com.mojang.authlib.Environment;
|
||||
+import com.mojang.authlib.GameProfile;
|
||||
+import com.mojang.authlib.minecraft.MinecraftProfileTexture;
|
||||
+import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService;
|
||||
+import com.mojang.authlib.yggdrasil.YggdrasilMinecraftSessionService;
|
||||
+
|
||||
+import java.util.Map;
|
||||
+
|
||||
+public class PaperMinecraftSessionService extends YggdrasilMinecraftSessionService {
|
||||
+ protected PaperMinecraftSessionService(YggdrasilAuthenticationService authenticationService, Environment environment) {
|
||||
+ super(authenticationService, environment);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public Map<MinecraftProfileTexture.Type, MinecraftProfileTexture> getTextures(GameProfile profile, boolean requireSecure) {
|
||||
+ return super.getTextures(profile, requireSecure);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public GameProfile fillProfileProperties(GameProfile profile, boolean requireSecure) {
|
||||
+ return super.fillProfileProperties(profile, requireSecure);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ protected GameProfile fillGameProfile(GameProfile profile, boolean requireSecure) {
|
||||
+ return super.fillGameProfile(profile, requireSecure);
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/profile/PaperUserAuthentication.java b/src/main/java/com/destroystokyo/paper/profile/PaperUserAuthentication.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..3cdd06d3af7ff94f1fe1a11b9a9275e17c695a38
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/profile/PaperUserAuthentication.java
|
||||
@@ -0,0 +1,12 @@
|
||||
+package com.destroystokyo.paper.profile;
|
||||
+
|
||||
+import com.mojang.authlib.Agent;
|
||||
+import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService;
|
||||
+import com.mojang.authlib.yggdrasil.YggdrasilUserAuthentication;
|
||||
+import java.util.UUID;
|
||||
+
|
||||
+public class PaperUserAuthentication extends YggdrasilUserAuthentication {
|
||||
+ public PaperUserAuthentication(YggdrasilAuthenticationService authenticationService, Agent agent) {
|
||||
+ super(authenticationService, UUID.randomUUID().toString(), agent);
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/profile/SharedPlayerProfile.java b/src/main/java/com/destroystokyo/paper/profile/SharedPlayerProfile.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..7ac27392a8647ef7d0dc78efe78703e993885017
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/profile/SharedPlayerProfile.java
|
||||
@@ -0,0 +1,23 @@
|
||||
+package com.destroystokyo.paper.profile;
|
||||
+
|
||||
+import com.mojang.authlib.GameProfile;
|
||||
+import com.mojang.authlib.properties.Property;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+import org.jetbrains.annotations.Nullable;
|
||||
+
|
||||
+import java.util.UUID;
|
||||
+
|
||||
+public interface SharedPlayerProfile {
|
||||
+
|
||||
+ @Nullable UUID getUniqueId();
|
||||
+
|
||||
+ @Nullable String getName();
|
||||
+
|
||||
+ boolean removeProperty(@NotNull String property);
|
||||
+
|
||||
+ @Nullable Property getProperty(@NotNull String propertyName);
|
||||
+
|
||||
+ @Nullable void setProperty(@NotNull String propertyName, @Nullable Property property);
|
||||
+
|
||||
+ @NotNull GameProfile buildGameProfile();
|
||||
+}
|
||||
diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java
|
||||
index 9f292deee1b793d52b5774304318e940128d1e26..0cf818fceddd76e7704fdc6625456787856b2815 100644
|
||||
--- a/src/main/java/net/minecraft/server/MCUtil.java
|
||||
+++ b/src/main/java/net/minecraft/server/MCUtil.java
|
||||
@@ -1,5 +1,7 @@
|
||||
package net.minecraft.server;
|
||||
|
||||
+import com.destroystokyo.paper.profile.CraftPlayerProfile;
|
||||
+import com.destroystokyo.paper.profile.PlayerProfile;
|
||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectRBTreeSet;
|
||||
import java.lang.ref.Cleaner;
|
||||
@@ -11,6 +13,7 @@ import net.minecraft.world.level.ChunkPos;
|
||||
import net.minecraft.world.level.ClipContext;
|
||||
import net.minecraft.world.level.Level;
|
||||
import org.apache.commons.lang.exception.ExceptionUtils;
|
||||
+import com.mojang.authlib.GameProfile;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.craftbukkit.CraftWorld;
|
||||
@@ -355,6 +358,10 @@ public final class MCUtil {
|
||||
return run.get();
|
||||
}
|
||||
|
||||
+ public static PlayerProfile toBukkit(GameProfile profile) {
|
||||
+ return CraftPlayerProfile.asBukkitMirror(profile);
|
||||
+ }
|
||||
+
|
||||
/**
|
||||
* Calculates distance between 2 entities
|
||||
* @param e1
|
||||
diff --git a/src/main/java/net/minecraft/server/Main.java b/src/main/java/net/minecraft/server/Main.java
|
||||
index a48a12a31a3d09a9373b688dcc093035f8f8a300..97b29bcb20e199c2d02457f8025e67e2d4a925fc 100644
|
||||
--- a/src/main/java/net/minecraft/server/Main.java
|
||||
+++ b/src/main/java/net/minecraft/server/Main.java
|
||||
@@ -138,7 +138,7 @@ public class Main {
|
||||
}
|
||||
|
||||
File file = (File) optionset.valueOf("universe"); // CraftBukkit
|
||||
- Services services = Services.create(new YggdrasilAuthenticationService(Proxy.NO_PROXY), file, optionset); // Paper
|
||||
+ Services services = Services.create(new com.destroystokyo.paper.profile.PaperAuthenticationService(Proxy.NO_PROXY), file, optionset); // Paper
|
||||
// CraftBukkit start
|
||||
String s = (String) Optional.ofNullable((String) optionset.valueOf("world")).orElse(dedicatedserversettings.getProperties().levelName);
|
||||
LevelStorageSource convertable = LevelStorageSource.createDefault(file.toPath());
|
||||
diff --git a/src/main/java/net/minecraft/server/players/GameProfileCache.java b/src/main/java/net/minecraft/server/players/GameProfileCache.java
|
||||
index 6c8a1d9c7696fa55dae6ba5e4ea50a0ffc7ea543..2347c7b44793aabe431b57bb1b44935fefbda6fe 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/GameProfileCache.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/GameProfileCache.java
|
||||
@@ -136,6 +136,17 @@ public class GameProfileCache {
|
||||
return this.operationCount.incrementAndGet();
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ public @Nullable GameProfile getProfileIfCached(String name) {
|
||||
+ GameProfileCache.GameProfileInfo entry = this.profilesByName.get(name.toLowerCase(Locale.ROOT));
|
||||
+ if (entry == null) {
|
||||
+ return null;
|
||||
+ }
|
||||
+ entry.setLastAccess(this.getNextOperation());
|
||||
+ return entry.getProfile();
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
public Optional<GameProfile> get(String name) {
|
||||
String s1 = name.toLowerCase(Locale.ROOT);
|
||||
GameProfileCache.GameProfileInfo usercache_usercacheentry = (GameProfileCache.GameProfileInfo) this.profilesByName.get(s1);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index 6d9ec963c1f0c5ee477ee4d84862a3c699eeba46..733423010e7941d160b838d614c732980111fb55 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -242,6 +242,9 @@ import org.yaml.snakeyaml.error.MarkedYAMLException;
|
||||
|
||||
import net.md_5.bungee.api.chat.BaseComponent; // Spigot
|
||||
|
||||
+import javax.annotation.Nullable; // Paper
|
||||
+import javax.annotation.Nonnull; // Paper
|
||||
+
|
||||
public final class CraftServer implements Server {
|
||||
private final String serverName = "Paper"; // Paper
|
||||
private final String serverVersion;
|
||||
@@ -282,6 +285,7 @@ public final class CraftServer implements Server {
|
||||
static {
|
||||
ConfigurationSerialization.registerClass(CraftOfflinePlayer.class);
|
||||
ConfigurationSerialization.registerClass(CraftPlayerProfile.class);
|
||||
+ ConfigurationSerialization.registerClass(com.destroystokyo.paper.profile.CraftPlayerProfile.class); // Paper
|
||||
CraftItemFactory.instance();
|
||||
}
|
||||
|
||||
@@ -2589,5 +2593,37 @@ public final class CraftServer implements Server {
|
||||
public boolean suggestPlayerNamesWhenNullTabCompletions() {
|
||||
return io.papermc.paper.configuration.GlobalConfiguration.get().commands.suggestPlayerNamesWhenNullTabCompletions;
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public com.destroystokyo.paper.profile.PlayerProfile createProfile(@Nonnull UUID uuid) {
|
||||
+ return createProfile(uuid, null);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public com.destroystokyo.paper.profile.PlayerProfile createProfile(@Nonnull String name) {
|
||||
+ return createProfile(null, name);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public com.destroystokyo.paper.profile.PlayerProfile createProfile(@Nullable UUID uuid, @Nullable String name) {
|
||||
+ Player player = uuid != null ? Bukkit.getPlayer(uuid) : (name != null ? Bukkit.getPlayerExact(name) : null);
|
||||
+ if (player != null) return new com.destroystokyo.paper.profile.CraftPlayerProfile((CraftPlayer) player);
|
||||
+
|
||||
+ return new com.destroystokyo.paper.profile.CraftPlayerProfile(uuid, name);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public com.destroystokyo.paper.profile.PlayerProfile createProfileExact(@Nullable UUID uuid, @Nullable String name) {
|
||||
+ Player player = uuid != null ? Bukkit.getPlayer(uuid) : (name != null ? Bukkit.getPlayerExact(name) : null);
|
||||
+ if (player == null) return new com.destroystokyo.paper.profile.CraftPlayerProfile(uuid, name);
|
||||
+
|
||||
+ if (Objects.equals(uuid, player.getUniqueId()) && Objects.equals(name, player.getName())) {
|
||||
+ return new com.destroystokyo.paper.profile.CraftPlayerProfile((CraftPlayer) player);
|
||||
+ }
|
||||
+
|
||||
+ final com.mojang.authlib.GameProfile profile = new com.mojang.authlib.GameProfile(uuid, name);
|
||||
+ profile.getProperties().putAll(((CraftPlayer)player).getHandle().getGameProfile().getProperties());
|
||||
+ return new com.destroystokyo.paper.profile.CraftPlayerProfile(profile);
|
||||
+ }
|
||||
// Paper end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/profile/CraftPlayerProfile.java b/src/main/java/org/bukkit/craftbukkit/profile/CraftPlayerProfile.java
|
||||
index 9edc5e73819e0b55372f77c5e292eece74d837c7..9001c9dc68dc05944eb839c3354bea29249daa92 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/profile/CraftPlayerProfile.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/profile/CraftPlayerProfile.java
|
||||
@@ -27,7 +27,7 @@ import org.bukkit.profile.PlayerProfile;
|
||||
import org.bukkit.profile.PlayerTextures;
|
||||
|
||||
@SerializableAs("PlayerProfile")
|
||||
-public final class CraftPlayerProfile implements PlayerProfile {
|
||||
+public final class CraftPlayerProfile implements PlayerProfile, com.destroystokyo.paper.profile.SharedPlayerProfile { // Paper
|
||||
|
||||
@Nonnull
|
||||
public static GameProfile validateSkullProfile(@Nonnull GameProfile gameProfile) {
|
||||
@@ -92,8 +92,10 @@ public final class CraftPlayerProfile implements PlayerProfile {
|
||||
}
|
||||
}
|
||||
|
||||
- void removeProperty(String propertyName) {
|
||||
- this.properties.removeAll(propertyName);
|
||||
+ // Paper start - change return value for shared interface
|
||||
+ public boolean removeProperty(String propertyName) {
|
||||
+ return !this.properties.removeAll(propertyName).isEmpty();
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
void rebuildDirtyProperties() {
|
||||
@@ -236,6 +238,7 @@ public final class CraftPlayerProfile implements PlayerProfile {
|
||||
|
||||
@Override
|
||||
public Map<String, Object> serialize() {
|
||||
+ // Paper - diff on change
|
||||
Map<String, Object> map = new LinkedHashMap<>();
|
||||
if (this.uniqueId != null) {
|
||||
map.put("uniqueId", this.uniqueId.toString());
|
||||
@@ -251,10 +254,12 @@ public final class CraftPlayerProfile implements PlayerProfile {
|
||||
});
|
||||
map.put("properties", propertiesData);
|
||||
}
|
||||
+ // Paper - diff on change
|
||||
return map;
|
||||
}
|
||||
|
||||
public static CraftPlayerProfile deserialize(Map<String, Object> map) {
|
||||
+ // Paper - diff on change
|
||||
UUID uniqueId = ConfigSerializationUtil.getUuid(map, "uniqueId", true);
|
||||
String name = ConfigSerializationUtil.getString(map, "name", true);
|
||||
|
||||
@@ -270,7 +275,7 @@ public final class CraftPlayerProfile implements PlayerProfile {
|
||||
profile.properties.put(property.getName(), property);
|
||||
}
|
||||
}
|
||||
-
|
||||
+ // Paper - diff on change
|
||||
return profile;
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/profile/CraftPlayerTextures.java b/src/main/java/org/bukkit/craftbukkit/profile/CraftPlayerTextures.java
|
||||
index e5b61bc1f3a4bfccca386360c4920ffb8b768308..ab1fd3fb39bd40fb867432861462db5f866bce6f 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/profile/CraftPlayerTextures.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/profile/CraftPlayerTextures.java
|
||||
@@ -48,7 +48,7 @@ public final class CraftPlayerTextures implements PlayerTextures {
|
||||
}
|
||||
}
|
||||
|
||||
- private final CraftPlayerProfile profile;
|
||||
+ private final com.destroystokyo.paper.profile.SharedPlayerProfile profile; // Paper
|
||||
|
||||
// The textures data is loaded lazily:
|
||||
private boolean loaded = false;
|
||||
@@ -67,7 +67,7 @@ public final class CraftPlayerTextures implements PlayerTextures {
|
||||
// GameProfiles (even if these modifications are later reverted).
|
||||
private boolean dirty = false;
|
||||
|
||||
- CraftPlayerTextures(@Nonnull CraftPlayerProfile profile) {
|
||||
+ public CraftPlayerTextures(@Nonnull com.destroystokyo.paper.profile.SharedPlayerProfile profile) { // Paper
|
||||
this.profile = profile;
|
||||
}
|
||||
|
|
@ -1,96 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sat, 17 Jun 2017 15:18:30 -0400
|
||||
Subject: [PATCH] Shoulder Entities Release API
|
||||
|
||||
|
||||
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 9aa134e56d661d033bb7229e6ab662534bf9cba9..794081610e52b7b8e04403510d1ad05f4f11d320 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
@@ -2026,20 +2026,44 @@ public abstract class Player extends LivingEntity {
|
||||
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ public Entity releaseLeftShoulderEntity() {
|
||||
+ Entity entity = this.spawnEntityFromShoulder0(this.getShoulderEntityLeft());
|
||||
+ if (entity != null) {
|
||||
+ this.setShoulderEntityLeft(new CompoundTag());
|
||||
+ }
|
||||
+ return entity;
|
||||
+ }
|
||||
+
|
||||
+ public Entity releaseRightShoulderEntity() {
|
||||
+ Entity entity = this.spawnEntityFromShoulder0(this.getShoulderEntityRight());
|
||||
+ if (entity != null) {
|
||||
+ this.setShoulderEntityRight(new CompoundTag());
|
||||
+ }
|
||||
+ return entity;
|
||||
+ }
|
||||
+ // Paper - maintain old signature
|
||||
private boolean spawnEntityFromShoulder(CompoundTag nbttagcompound) { // CraftBukkit void->boolean
|
||||
- if (!this.level.isClientSide && !nbttagcompound.isEmpty()) {
|
||||
+ return spawnEntityFromShoulder0(nbttagcompound) != null;
|
||||
+ }
|
||||
+
|
||||
+ // Paper - return entity
|
||||
+ private Entity spawnEntityFromShoulder0(@Nullable CompoundTag nbttagcompound) {
|
||||
+ if (!this.level.isClientSide && nbttagcompound != null && !nbttagcompound.isEmpty()) {
|
||||
return EntityType.create(nbttagcompound, this.level).map((entity) -> { // CraftBukkit
|
||||
if (entity instanceof TamableAnimal) {
|
||||
((TamableAnimal) entity).setOwnerUUID(this.uuid);
|
||||
}
|
||||
|
||||
entity.setPos(this.getX(), this.getY() + 0.699999988079071D, this.getZ());
|
||||
- return ((ServerLevel) this.level).addWithUUID(entity, CreatureSpawnEvent.SpawnReason.SHOULDER_ENTITY); // CraftBukkit
|
||||
- }).orElse(true); // CraftBukkit
|
||||
+ boolean addedToWorld = ((ServerLevel) this.level).addWithUUID(entity, CreatureSpawnEvent.SpawnReason.SHOULDER_ENTITY); // CraftBukkit
|
||||
+ return addedToWorld ? entity : null;
|
||||
+ }).orElse(null); // CraftBukkit // Paper - true -> null
|
||||
}
|
||||
|
||||
- return true; // CraftBukkit
|
||||
+ return null; // Paper - return null
|
||||
}
|
||||
+ // Paper end
|
||||
|
||||
@Override
|
||||
public abstract boolean isSpectator();
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
|
||||
index 2c934b7a2142a4d1ae21feeb95d23f22cfda3be0..3954ed194388c6487c6cd0303aea9e1b65a0f8ee 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
|
||||
@@ -504,6 +504,32 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
|
||||
this.getHandle().getCooldowns().addCooldown(CraftMagicNumbers.getItem(material), ticks);
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public org.bukkit.entity.Entity releaseLeftShoulderEntity() {
|
||||
+ if (!getHandle().getShoulderEntityLeft().isEmpty()) {
|
||||
+ Entity entity = getHandle().releaseLeftShoulderEntity();
|
||||
+ if (entity != null) {
|
||||
+ return entity.getBukkitEntity();
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return null;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public org.bukkit.entity.Entity releaseRightShoulderEntity() {
|
||||
+ if (!getHandle().getShoulderEntityRight().isEmpty()) {
|
||||
+ Entity entity = getHandle().releaseRightShoulderEntity();
|
||||
+ if (entity != null) {
|
||||
+ return entity.getBukkitEntity();
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return null;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public boolean discoverRecipe(NamespacedKey recipe) {
|
||||
return this.discoverRecipes(Arrays.asList(recipe)) != 0;
|
|
@ -1,81 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sat, 17 Jun 2017 17:00:32 -0400
|
||||
Subject: [PATCH] Profile Lookup Events
|
||||
|
||||
Adds a Pre Lookup Event and a Post Lookup Event so that plugins may prefill in profile data, and cache the responses from
|
||||
profiles that had to be looked up.
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/profile/PaperGameProfileRepository.java b/src/main/java/com/destroystokyo/paper/profile/PaperGameProfileRepository.java
|
||||
index 582c169c85ac66f1f9430f79042e4655f776c157..08fdb681a68e8be6e4062af0630957ce3e524806 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/profile/PaperGameProfileRepository.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/profile/PaperGameProfileRepository.java
|
||||
@@ -1,11 +1,16 @@
|
||||
package com.destroystokyo.paper.profile;
|
||||
|
||||
+import com.destroystokyo.paper.event.profile.LookupProfileEvent;
|
||||
+import com.destroystokyo.paper.event.profile.PreLookupProfileEvent;
|
||||
+import com.google.common.collect.Sets;
|
||||
import com.mojang.authlib.Agent;
|
||||
import com.mojang.authlib.Environment;
|
||||
+import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.authlib.ProfileLookupCallback;
|
||||
import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService;
|
||||
import com.mojang.authlib.yggdrasil.YggdrasilGameProfileRepository;
|
||||
|
||||
+import java.util.Set;
|
||||
public class PaperGameProfileRepository extends YggdrasilGameProfileRepository {
|
||||
public PaperGameProfileRepository(YggdrasilAuthenticationService authenticationService, Environment environment) {
|
||||
super(authenticationService, environment);
|
||||
@@ -13,6 +18,50 @@ public class PaperGameProfileRepository extends YggdrasilGameProfileRepository {
|
||||
|
||||
@Override
|
||||
public void findProfilesByNames(String[] names, Agent agent, ProfileLookupCallback callback) {
|
||||
- super.findProfilesByNames(names, agent, callback);
|
||||
+ Set<String> unfoundNames = Sets.newHashSet();
|
||||
+ for (String name : names) {
|
||||
+ PreLookupProfileEvent event = new PreLookupProfileEvent(name);
|
||||
+ event.callEvent();
|
||||
+ if (event.getUUID() != null) {
|
||||
+ // Plugin provided UUI, we can skip network call.
|
||||
+ GameProfile gameprofile = new GameProfile(event.getUUID(), name);
|
||||
+ // We might even have properties!
|
||||
+ Set<ProfileProperty> profileProperties = event.getProfileProperties();
|
||||
+ if (!profileProperties.isEmpty()) {
|
||||
+ for (ProfileProperty property : profileProperties) {
|
||||
+ gameprofile.getProperties().put(property.getName(), CraftPlayerProfile.asAuthlib(property));
|
||||
+ }
|
||||
+ }
|
||||
+ callback.onProfileLookupSucceeded(gameprofile);
|
||||
+ } else {
|
||||
+ unfoundNames.add(name);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // Some things were not found.... Proceed to look up.
|
||||
+ if (!unfoundNames.isEmpty()) {
|
||||
+ String[] namesArr = unfoundNames.toArray(new String[unfoundNames.size()]);
|
||||
+ super.findProfilesByNames(namesArr, agent, new PreProfileLookupCallback(callback));
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private static class PreProfileLookupCallback implements ProfileLookupCallback {
|
||||
+ private final ProfileLookupCallback callback;
|
||||
+
|
||||
+ PreProfileLookupCallback(ProfileLookupCallback callback) {
|
||||
+ this.callback = callback;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void onProfileLookupSucceeded(GameProfile gameProfile) {
|
||||
+ PlayerProfile from = CraftPlayerProfile.asBukkitMirror(gameProfile);
|
||||
+ new LookupProfileEvent(from).callEvent();
|
||||
+ callback.onProfileLookupSucceeded(gameProfile);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void onProfileLookupFailed(GameProfile gameProfile, Exception e) {
|
||||
+ callback.onProfileLookupFailed(gameProfile, e);
|
||||
+ }
|
||||
}
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <zach.brown@destroystokyo.com>
|
||||
Date: Sun, 2 Jul 2017 21:35:56 -0500
|
||||
Subject: [PATCH] Block player logins during server shutdown
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
index 13f8f3a2a6382ef51567cc6f46b573d971f700f6..dc932515bada7f84a386827f3b7e1e8f69bd7159 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
@@ -79,6 +79,12 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
+ // Paper start - Do not allow logins while the server is shutting down
|
||||
+ if (!MinecraftServer.getServer().isRunning()) {
|
||||
+ this.disconnect(org.bukkit.craftbukkit.util.CraftChatMessage.fromString(org.spigotmc.SpigotConfig.restartMessage)[0]);
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end
|
||||
if (this.state == ServerLoginPacketListenerImpl.State.READY_TO_ACCEPT) {
|
||||
this.handleAcceptedLogin();
|
||||
} else if (this.state == ServerLoginPacketListenerImpl.State.DELAY_ACCEPT) {
|
|
@ -1,65 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Sun, 18 Jun 2017 18:17:05 -0500
|
||||
Subject: [PATCH] Entity#fromMobSpawner()
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
index 1daffb325617f8e9f3218aa879eb7d8467d69447..e233f1bd8047c06d69aed0e22c220658b9868729 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -380,6 +380,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
|
||||
// Spigot end
|
||||
// Paper start
|
||||
protected int numCollisions = 0; // Paper
|
||||
+ public boolean spawnedViaMobSpawner; // Paper - Yes this name is similar to above, upstream took the better one
|
||||
@javax.annotation.Nullable
|
||||
private org.bukkit.util.Vector origin;
|
||||
@javax.annotation.Nullable
|
||||
@@ -1959,6 +1960,10 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
|
||||
}
|
||||
nbt.put("Paper.Origin", this.newDoubleList(origin.getX(), origin.getY(), origin.getZ()));
|
||||
}
|
||||
+ // Save entity's from mob spawner status
|
||||
+ if (spawnedViaMobSpawner) {
|
||||
+ nbt.putBoolean("Paper.FromMobSpawner", true);
|
||||
+ }
|
||||
// Paper end
|
||||
return nbt;
|
||||
} catch (Throwable throwable) {
|
||||
@@ -2096,6 +2101,8 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
|
||||
this.originWorld = originWorld;
|
||||
origin = new org.bukkit.util.Vector(originTag.getDouble(0), originTag.getDouble(1), originTag.getDouble(2));
|
||||
}
|
||||
+
|
||||
+ spawnedViaMobSpawner = nbt.getBoolean("Paper.FromMobSpawner"); // Restore entity's from mob spawner status
|
||||
// Paper end
|
||||
|
||||
} catch (Throwable throwable) {
|
||||
diff --git a/src/main/java/net/minecraft/world/level/BaseSpawner.java b/src/main/java/net/minecraft/world/level/BaseSpawner.java
|
||||
index e5b56a85d76d1417dda2d14b1b03850bbb070f4c..5304b0455b070006922e1b5471e9c0ababc58aa2 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/BaseSpawner.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/BaseSpawner.java
|
||||
@@ -159,6 +159,7 @@ public abstract class BaseSpawner {
|
||||
}
|
||||
// Spigot End
|
||||
}
|
||||
+ entity.spawnedViaMobSpawner = true; // Paper
|
||||
// Spigot Start
|
||||
if (org.bukkit.craftbukkit.event.CraftEventFactory.callSpawnerSpawnEvent(entity, pos).isCancelled()) {
|
||||
Entity vehicle = entity.getVehicle();
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
index e1ae00c1639b4ff18e061d86b006ff733494bb00..41753b72ac6fdf0314d60dbe1ffb60e79b3e4af8 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
@@ -1212,5 +1212,10 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
|
||||
//noinspection ConstantConditions
|
||||
return originVector.toLocation(world);
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean fromMobSpawner() {
|
||||
+ return getHandle().spawnedViaMobSpawner;
|
||||
+ }
|
||||
// Paper end
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sat, 10 Dec 2016 16:24:06 -0500
|
||||
Subject: [PATCH] Improve the Saddle API for Horses
|
||||
|
||||
Not all horses with Saddles have armor. This lets us break up the horses with saddles
|
||||
and access their saddle state separately from an interface shared with Armor.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractHorse.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractHorse.java
|
||||
index d74c9eeb7f622f0a7265fec51d851ffd3de1c69b..a5202ee012034678efbbd5ca1eccf2fd72a315bd 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractHorse.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractHorse.java
|
||||
@@ -5,6 +5,7 @@ import net.minecraft.world.entity.ai.attributes.Attributes;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.craftbukkit.inventory.CraftInventoryAbstractHorse;
|
||||
+import org.bukkit.craftbukkit.inventory.CraftSaddledInventory;
|
||||
import org.bukkit.entity.AbstractHorse;
|
||||
import org.bukkit.entity.AnimalTamer;
|
||||
import org.bukkit.entity.Horse;
|
||||
@@ -108,6 +109,6 @@ public abstract class CraftAbstractHorse extends CraftAnimals implements Abstrac
|
||||
|
||||
@Override
|
||||
public AbstractHorseInventory getInventory() {
|
||||
- return new CraftInventoryAbstractHorse(this.getHandle().inventory);
|
||||
+ return new CraftSaddledInventory(getHandle().inventory);
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryHorse.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryHorse.java
|
||||
index 7013059856c2471dc34112a1a2068b96b809dd96..b72b4260fc1c0e9928d70f97589d8db00849b9e8 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryHorse.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryHorse.java
|
||||
@@ -4,7 +4,7 @@ import net.minecraft.world.Container;
|
||||
import org.bukkit.inventory.HorseInventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
-public class CraftInventoryHorse extends CraftInventoryAbstractHorse implements HorseInventory {
|
||||
+public class CraftInventoryHorse extends CraftSaddledInventory implements HorseInventory {
|
||||
|
||||
public CraftInventoryHorse(Container inventory) {
|
||||
super(inventory);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftSaddledInventory.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftSaddledInventory.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..3a617c07d445bacf5a13e0e3ff6481823cfc8477
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftSaddledInventory.java
|
||||
@@ -0,0 +1,12 @@
|
||||
+package org.bukkit.craftbukkit.inventory;
|
||||
+
|
||||
+import net.minecraft.world.Container;
|
||||
+import org.bukkit.inventory.SaddledHorseInventory;
|
||||
+
|
||||
+public class CraftSaddledInventory extends CraftInventoryAbstractHorse implements SaddledHorseInventory {
|
||||
+
|
||||
+ public CraftSaddledInventory(Container inventory) {
|
||||
+ super(inventory);
|
||||
+ }
|
||||
+
|
||||
+}
|
|
@ -1,24 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Wed, 4 May 2016 22:43:12 -0400
|
||||
Subject: [PATCH] Implement ensureServerConversions API
|
||||
|
||||
This will take a Bukkit ItemStack and run it through any conversions a server process would perform on it,
|
||||
to ensure it meets latest minecraft expectations.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java
|
||||
index a06f9775a43a245380edabde63e7999082e7958a..5f83838f3f40b778088187904b747abff703c3f2 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java
|
||||
@@ -386,5 +386,11 @@ public final class CraftItemFactory implements ItemFactory {
|
||||
public net.kyori.adventure.text.@org.jetbrains.annotations.NotNull Component displayName(@org.jetbrains.annotations.NotNull ItemStack itemStack) {
|
||||
return io.papermc.paper.adventure.PaperAdventure.asAdventure(CraftItemStack.asNMSCopy(itemStack).getDisplayName());
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public ItemStack ensureServerConversions(ItemStack item) {
|
||||
+ return CraftItemStack.asCraftMirror(CraftItemStack.asNMSCopy(item));
|
||||
+ }
|
||||
// Paper end
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Wed, 4 May 2016 23:59:38 -0400
|
||||
Subject: [PATCH] Implement getI18NDisplayName
|
||||
|
||||
Gets the Display name as seen in the Client.
|
||||
Currently the server only supports the English language. To override this,
|
||||
You must replace the language file embedded in the server jar.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java
|
||||
index 5f83838f3f40b778088187904b747abff703c3f2..f05923a6292f02a01791627abce2770daff24b6a 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java
|
||||
@@ -392,5 +392,18 @@ public final class CraftItemFactory implements ItemFactory {
|
||||
public ItemStack ensureServerConversions(ItemStack item) {
|
||||
return CraftItemStack.asCraftMirror(CraftItemStack.asNMSCopy(item));
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public String getI18NDisplayName(ItemStack item) {
|
||||
+ net.minecraft.world.item.ItemStack nms = null;
|
||||
+ if (item instanceof CraftItemStack) {
|
||||
+ nms = ((CraftItemStack) item).handle;
|
||||
+ }
|
||||
+ if (nms == null) {
|
||||
+ nms = CraftItemStack.asNMSCopy(item);
|
||||
+ }
|
||||
+
|
||||
+ return nms != null ? net.minecraft.locale.Language.getInstance().getOrDefault(nms.getItem().getDescriptionId(nms)) : null;
|
||||
+ }
|
||||
// Paper end
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 3 Jul 2017 18:11:10 -0500
|
||||
Subject: [PATCH] ProfileWhitelistVerifyEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
index 9cb9e0a4d1467cb5c23dfd38e83d495a3907d984..4a94be565a3a7f7b8b330a35d97a14ef52ac4e50 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
@@ -619,9 +619,9 @@ public abstract class PlayerList {
|
||||
|
||||
// return chatmessage;
|
||||
event.disallow(PlayerLoginEvent.Result.KICK_BANNED, PaperAdventure.asAdventure(ichatmutablecomponent)); // Paper - Adventure
|
||||
- } else if (!this.isWhiteListed(gameprofile)) {
|
||||
- ichatmutablecomponent = Component.translatable("multiplayer.disconnect.not_whitelisted");
|
||||
- event.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(org.spigotmc.SpigotConfig.whitelistMessage)); // Spigot // Paper - Adventure
|
||||
+ } else if (!this.isWhiteListed(gameprofile, event)) { // Paper
|
||||
+ //ichatmutablecomponent = Component.translatable("multiplayer.disconnect.not_whitelisted"); // Paper
|
||||
+ //event.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(org.spigotmc.SpigotConfig.whitelistMessage)); // Spigot // Paper - Adventure - moved to isWhitelisted
|
||||
} else if (this.getIpBans().isBanned(socketaddress) && !this.getIpBans().get(socketaddress).hasExpired()) {
|
||||
IpBanListEntry ipbanentry = this.ipBans.get(socketaddress);
|
||||
|
||||
@@ -1003,7 +1003,23 @@ public abstract class PlayerList {
|
||||
}
|
||||
|
||||
public boolean isWhiteListed(GameProfile profile) {
|
||||
- return !this.doWhiteList || this.ops.contains(profile) || this.whitelist.contains(profile);
|
||||
+ // Paper start
|
||||
+ return isWhiteListed(profile, null);
|
||||
+ }
|
||||
+ public boolean isWhiteListed(GameProfile gameprofile, org.bukkit.event.player.PlayerLoginEvent loginEvent) {
|
||||
+ boolean isOp = this.ops.contains(gameprofile);
|
||||
+ boolean isWhitelisted = !this.doWhiteList || isOp || this.whitelist.contains(gameprofile);
|
||||
+ final com.destroystokyo.paper.event.profile.ProfileWhitelistVerifyEvent event;
|
||||
+ event = new com.destroystokyo.paper.event.profile.ProfileWhitelistVerifyEvent(net.minecraft.server.MCUtil.toBukkit(gameprofile), this.doWhiteList, isWhitelisted, isOp, org.spigotmc.SpigotConfig.whitelistMessage);
|
||||
+ event.callEvent();
|
||||
+ if (!event.isWhitelisted()) {
|
||||
+ if (loginEvent != null) {
|
||||
+ loginEvent.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(event.getKickMessage() == null ? org.spigotmc.SpigotConfig.whitelistMessage : event.getKickMessage()));
|
||||
+ }
|
||||
+ return false;
|
||||
+ }
|
||||
+ return true;
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
public boolean isOp(GameProfile profile) {
|
|
@ -1,52 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Kyle Wood <kyle@denwav.dev>
|
||||
Date: Sun, 6 Aug 2017 17:17:53 -0500
|
||||
Subject: [PATCH] Fix this stupid bullshit
|
||||
|
||||
Disable the 15 second sleep when the server jar hasn't been rebuilt within a period of time.
|
||||
|
||||
modified in order to prevent merge conflicts when Spigot changes/disables the warning,
|
||||
and to provide some level of hint without being disruptive.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/Bootstrap.java b/src/main/java/net/minecraft/server/Bootstrap.java
|
||||
index e359919de57f97d18667df1b2f1bf54a19a49c2f..c5822637e48fad4ca4e8cf210431b5eafbf5abb1 100644
|
||||
--- a/src/main/java/net/minecraft/server/Bootstrap.java
|
||||
+++ b/src/main/java/net/minecraft/server/Bootstrap.java
|
||||
@@ -46,7 +46,7 @@ public class Bootstrap {
|
||||
public static void bootStrap() {
|
||||
if (!Bootstrap.isBootstrapped) {
|
||||
// CraftBukkit start
|
||||
- String name = Bootstrap.class.getSimpleName();
|
||||
+ /*String name = Bootstrap.class.getSimpleName(); // Paper
|
||||
switch (name) {
|
||||
case "DispenserRegistry":
|
||||
break;
|
||||
@@ -60,7 +60,7 @@ public class Bootstrap {
|
||||
System.err.println("*** WARNING: This server jar is unsupported, use at your own risk. ***");
|
||||
System.err.println("**********************************************************************");
|
||||
break;
|
||||
- }
|
||||
+ }*/ // Paper
|
||||
// CraftBukkit end
|
||||
Bootstrap.isBootstrapped = true;
|
||||
if (Registry.REGISTRY.keySet().isEmpty()) {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java
|
||||
index c59c72e36db34820ddaf881086a65ec36d79f58d..beb12dcc620d902594dbe6ba2893062fadb97dc5 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/Main.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/Main.java
|
||||
@@ -239,10 +239,12 @@ public class Main {
|
||||
Calendar deadline = Calendar.getInstance();
|
||||
deadline.add(Calendar.DAY_OF_YEAR, -14);
|
||||
if (buildDate.before(deadline.getTime())) {
|
||||
- System.err.println("*** Error, this build is outdated ***");
|
||||
+ // Paper start - This is some stupid bullshit
|
||||
+ System.err.println("*** Warning, you've not updated in a while! ***");
|
||||
System.err.println("*** Please download a new build as per instructions from https://papermc.io/downloads ***"); // Paper
|
||||
- System.err.println("*** Server will start in 20 seconds ***");
|
||||
- Thread.sleep(TimeUnit.SECONDS.toMillis(20));
|
||||
+ //System.err.println("*** Server will start in 20 seconds ***");
|
||||
+ //Thread.sleep(TimeUnit.SECONDS.toMillis(20));
|
||||
+ // Paper End
|
||||
}
|
||||
}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Mon, 31 Jul 2017 01:49:48 -0500
|
||||
Subject: [PATCH] LivingEntity#setKiller
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
index b65d44780c7e6e1e2e8724df838d1aa54edcc30a..6455a81fea0de79173419587171b5ed025c30592 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
@@ -8,6 +8,7 @@ import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
+import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.damagesource.DamageSource;
|
||||
import net.minecraft.world.effect.MobEffect;
|
||||
@@ -344,6 +345,16 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
|
||||
return this.getHandle().lastHurtByPlayer == null ? null : (Player) this.getHandle().lastHurtByPlayer.getBukkitEntity();
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public void setKiller(Player killer) {
|
||||
+ ServerPlayer entityPlayer = killer == null ? null : ((CraftPlayer) killer).getHandle();
|
||||
+ getHandle().lastHurtByPlayer = entityPlayer;
|
||||
+ getHandle().lastHurtByMob = entityPlayer;
|
||||
+ getHandle().lastHurtByPlayerTime = entityPlayer == null ? 0 : 100; // 100 value taken from EntityLiving#damageEntity
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public boolean addPotionEffect(PotionEffect effect) {
|
||||
return this.addPotionEffect(effect, false);
|
|
@ -1,19 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Mon, 31 Jul 2017 01:54:40 -0500
|
||||
Subject: [PATCH] Ocelot despawns should honor nametags and leash
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/Ocelot.java b/src/main/java/net/minecraft/world/entity/animal/Ocelot.java
|
||||
index 4b9e3729279f3bfabab4227c511c4bf89488ff8c..6a459435493295ee5bb44fe2ba79cba6acea2e35 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/Ocelot.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/Ocelot.java
|
||||
@@ -133,7 +133,7 @@ public class Ocelot extends Animal {
|
||||
|
||||
@Override
|
||||
public boolean removeWhenFarAway(double distanceSquared) {
|
||||
- return !this.isTrusting() && this.tickCount > 2400;
|
||||
+ return !this.isTrusting() && this.tickCount > 2400 && !this.hasCustomName() && !this.isLeashed(); // Paper - honor name and leash
|
||||
}
|
||||
|
||||
public static AttributeSupplier.Builder createAttributes() {
|
|
@ -1,27 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Mon, 31 Jul 2017 01:45:19 -0500
|
||||
Subject: [PATCH] Reset spawner timer when spawner event is cancelled
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/BaseSpawner.java b/src/main/java/net/minecraft/world/level/BaseSpawner.java
|
||||
index 5304b0455b070006922e1b5471e9c0ababc58aa2..ac767d107ea0d856f3f8caccfe6f79b14e933005 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/BaseSpawner.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/BaseSpawner.java
|
||||
@@ -160,6 +160,7 @@ public abstract class BaseSpawner {
|
||||
// Spigot End
|
||||
}
|
||||
entity.spawnedViaMobSpawner = true; // Paper
|
||||
+ flag = true; // Paper
|
||||
// Spigot Start
|
||||
if (org.bukkit.craftbukkit.event.CraftEventFactory.callSpawnerSpawnEvent(entity, pos).isCancelled()) {
|
||||
Entity vehicle = entity.getVehicle();
|
||||
@@ -184,7 +185,7 @@ public abstract class BaseSpawner {
|
||||
((Mob) entity).spawnAnim();
|
||||
}
|
||||
|
||||
- flag = true;
|
||||
+ //flag = true; // Paper - moved up above cancellable event
|
||||
}
|
||||
}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: kashike <kashike@vq.lc>
|
||||
Date: Thu, 17 Aug 2017 16:08:20 -0700
|
||||
Subject: [PATCH] Allow specifying a custom "authentication servers down" kick
|
||||
message
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
index dc932515bada7f84a386827f3b7e1e8f69bd7159..d2f0450c6bae722bfa9162b027e723eb10b22c78 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
@@ -358,7 +358,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener
|
||||
ServerLoginPacketListenerImpl.this.gameProfile = ServerLoginPacketListenerImpl.this.createFakeProfile(gameprofile);
|
||||
ServerLoginPacketListenerImpl.this.state = ServerLoginPacketListenerImpl.State.READY_TO_ACCEPT;
|
||||
} else {
|
||||
- ServerLoginPacketListenerImpl.this.disconnect(Component.translatable("multiplayer.disconnect.authservers_down"));
|
||||
+ ServerLoginPacketListenerImpl.this.disconnect(io.papermc.paper.adventure.PaperAdventure.asVanilla(io.papermc.paper.configuration.GlobalConfiguration.get().messages.kick.authenticationServersDown)); // Paper
|
||||
ServerLoginPacketListenerImpl.LOGGER.error("Couldn't verify username because servers are unavailable");
|
||||
}
|
||||
// CraftBukkit start - catch all exceptions
|
|
@ -1,71 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Minecrell <minecrell@minecrell.net>
|
||||
Date: Thu, 21 Sep 2017 16:14:55 +0200
|
||||
Subject: [PATCH] Handle plugin prefixes using Log4J configuration
|
||||
|
||||
Display logger name in the console for all loggers except the
|
||||
root logger, Bukkit's logger ("Minecraft") and Minecraft loggers.
|
||||
Since plugins now use the plugin name as logger name this will
|
||||
restore the plugin prefixes without having to prepend them manually
|
||||
to the log messages.
|
||||
|
||||
Logger prefixes are shown by default for all loggers except for
|
||||
the root logger, the Minecraft/Mojang loggers and the Bukkit loggers.
|
||||
This may cause additional prefixes to be disabled for plugins bypassing
|
||||
the plugin logger.
|
||||
|
||||
diff --git a/build.gradle.kts b/build.gradle.kts
|
||||
index d4141a24cb5ba20e8c53c85206b32120ff18eb48..a57fad0a75fe18f70d3dd6cd5c6a2ab90eb0498d 100644
|
||||
--- a/build.gradle.kts
|
||||
+++ b/build.gradle.kts
|
||||
@@ -17,7 +17,7 @@ dependencies {
|
||||
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")
|
||||
+ implementation("org.apache.logging.log4j:log4j-core:2.14.1") // Paper - implementation
|
||||
// Paper end
|
||||
implementation("org.apache.logging.log4j:log4j-iostreams:2.17.1") // Paper
|
||||
implementation("org.ow2.asm:asm:9.3")
|
||||
diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java
|
||||
index 051d7c7fc5796ad056ae1ba5e5e630fde8794108..c2e3d32e51902503af88f089e366e784f42d999a 100644
|
||||
--- a/src/main/java/org/spigotmc/SpigotConfig.java
|
||||
+++ b/src/main/java/org/spigotmc/SpigotConfig.java
|
||||
@@ -290,7 +290,7 @@ public class SpigotConfig
|
||||
private static void playerSample()
|
||||
{
|
||||
SpigotConfig.playerSample = SpigotConfig.getInt( "settings.sample-count", 12 );
|
||||
- System.out.println( "Server Ping Player Sample Count: " + SpigotConfig.playerSample );
|
||||
+ Bukkit.getLogger().log( Level.INFO, "Server Ping Player Sample Count: {0}", playerSample ); // Paper - Use logger
|
||||
}
|
||||
|
||||
public static int playerShuffle;
|
||||
diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml
|
||||
index 620b9490e5f159080e50289d127404a1b56adbef..a8bdaaeaa1a9316848416f0533739b9b083ca151 100644
|
||||
--- a/src/main/resources/log4j2.xml
|
||||
+++ b/src/main/resources/log4j2.xml
|
||||
@@ -5,10 +5,22 @@
|
||||
<PatternLayout pattern="[%d{HH:mm:ss} %level]: %msg%n" />
|
||||
</Queue>
|
||||
<TerminalConsole name="TerminalConsole">
|
||||
- <PatternLayout pattern="%highlightError{[%d{HH:mm:ss} %level]: %minecraftFormatting{%msg}%n%xEx}" />
|
||||
+ <PatternLayout>
|
||||
+ <LoggerNamePatternSelector defaultPattern="%highlightError{[%d{HH:mm:ss} %level]: [%logger] %minecraftFormatting{%msg}%n%xEx}">
|
||||
+ <!-- Log root, Minecraft, Mojang and Bukkit loggers without prefix -->
|
||||
+ <PatternMatch key=",net.minecraft.,Minecraft,com.mojang."
|
||||
+ pattern="%highlightError{[%d{HH:mm:ss} %level]: %minecraftFormatting{%msg}%n%xEx}" />
|
||||
+ </LoggerNamePatternSelector>
|
||||
+ </PatternLayout>
|
||||
</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]: %minecraftFormatting{%msg}{strip}%n" />
|
||||
+ <PatternLayout>
|
||||
+ <LoggerNamePatternSelector defaultPattern="[%d{HH:mm:ss}] [%t/%level]: [%logger] %minecraftFormatting{%msg}{strip}%n">
|
||||
+ <!-- Log root, Minecraft, Mojang and Bukkit loggers without prefix -->
|
||||
+ <PatternMatch key=",net.minecraft.,Minecraft,com.mojang."
|
||||
+ pattern="[%d{HH:mm:ss}] [%t/%level]: %minecraftFormatting{%msg}{strip}%n" />
|
||||
+ </LoggerNamePatternSelector>
|
||||
+ </PatternLayout>
|
||||
<Policies>
|
||||
<TimeBasedTriggeringPolicy />
|
||||
<OnStartupTriggeringPolicy />
|
|
@ -1,47 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Minecrell <minecrell@minecrell.net>
|
||||
Date: Sat, 23 Sep 2017 21:07:20 +0200
|
||||
Subject: [PATCH] Improve Log4J Configuration / Plugin Loggers
|
||||
|
||||
Add full exceptions to log4j to not truncate stack traces
|
||||
|
||||
Disable logger prefix for various plugins bypassing the plugin logger
|
||||
|
||||
Some plugins bypass the plugin logger and add the plugin prefix
|
||||
manually to the log message. Since they use other logger names
|
||||
(e.g. qualified class names) these would now also appear in the
|
||||
log. Disable the logger prefix for these plugins so the messages
|
||||
show up correctly.
|
||||
|
||||
diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml
|
||||
index a8bdaaeaa1a9316848416f0533739b9b083ca151..476f4a5cbe664ddd05474cb88553018bd334a5b8 100644
|
||||
--- a/src/main/resources/log4j2.xml
|
||||
+++ b/src/main/resources/log4j2.xml
|
||||
@@ -6,19 +6,21 @@
|
||||
</Queue>
|
||||
<TerminalConsole name="TerminalConsole">
|
||||
<PatternLayout>
|
||||
- <LoggerNamePatternSelector defaultPattern="%highlightError{[%d{HH:mm:ss} %level]: [%logger] %minecraftFormatting{%msg}%n%xEx}">
|
||||
+ <LoggerNamePatternSelector defaultPattern="%highlightError{[%d{HH:mm:ss} %level]: [%logger] %minecraftFormatting{%msg}%n%xEx{full}}">
|
||||
<!-- Log root, Minecraft, Mojang and Bukkit loggers without prefix -->
|
||||
- <PatternMatch key=",net.minecraft.,Minecraft,com.mojang."
|
||||
- pattern="%highlightError{[%d{HH:mm:ss} %level]: %minecraftFormatting{%msg}%n%xEx}" />
|
||||
+ <!-- Disable prefix for various plugins that bypass the plugin logger -->
|
||||
+ <PatternMatch key=",net.minecraft.,Minecraft,com.mojang.,com.sk89q.,ru.tehkode.,Minecraft.AWE"
|
||||
+ pattern="%highlightError{[%d{HH:mm:ss} %level]: %minecraftFormatting{%msg}%n%xEx{full}}" />
|
||||
</LoggerNamePatternSelector>
|
||||
</PatternLayout>
|
||||
</TerminalConsole>
|
||||
<RollingRandomAccessFile name="File" fileName="logs/latest.log" filePattern="logs/%d{yyyy-MM-dd}-%i.log.gz">
|
||||
<PatternLayout>
|
||||
- <LoggerNamePatternSelector defaultPattern="[%d{HH:mm:ss}] [%t/%level]: [%logger] %minecraftFormatting{%msg}{strip}%n">
|
||||
+ <LoggerNamePatternSelector defaultPattern="[%d{HH:mm:ss}] [%t/%level]: [%logger] %minecraftFormatting{%msg}{strip}%n%xEx{full}">
|
||||
<!-- Log root, Minecraft, Mojang and Bukkit loggers without prefix -->
|
||||
- <PatternMatch key=",net.minecraft.,Minecraft,com.mojang."
|
||||
- pattern="[%d{HH:mm:ss}] [%t/%level]: %minecraftFormatting{%msg}{strip}%n" />
|
||||
+ <!-- Disable prefix for various plugins that bypass the plugin logger -->
|
||||
+ <PatternMatch key=",net.minecraft.,Minecraft,com.mojang.,com.sk89q.,ru.tehkode.,Minecraft.AWE"
|
||||
+ pattern="[%d{HH:mm:ss}] [%t/%level]: %minecraftFormatting{%msg}{strip}%n%xEx{full}" />
|
||||
</LoggerNamePatternSelector>
|
||||
</PatternLayout>
|
||||
<Policies>
|
|
@ -1,46 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <zach.brown@destroystokyo.com>
|
||||
Date: Thu, 28 Sep 2017 17:21:44 -0400
|
||||
Subject: [PATCH] Add PlayerJumpEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 61752ae5602e901ed03037cb2dee29f461b68cac..751086ab2f87269ecd43306b794d8b1c3dcd143f 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -1217,7 +1217,34 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
|
||||
boolean flag = d8 > 0.0D;
|
||||
|
||||
if (this.player.isOnGround() && !packet.isOnGround() && flag) {
|
||||
- this.player.jumpFromGround();
|
||||
+ // Paper start - Add player jump event
|
||||
+ Player player = this.getCraftPlayer();
|
||||
+ Location from = new Location(player.getWorld(), lastPosX, lastPosY, lastPosZ, lastYaw, lastPitch); // Get the Players previous Event location.
|
||||
+ Location to = player.getLocation().clone(); // Start off the To location as the Players current location.
|
||||
+
|
||||
+ // If the packet contains movement information then we update the To location with the correct XYZ.
|
||||
+ if (packet.hasPos) {
|
||||
+ to.setX(packet.x);
|
||||
+ to.setY(packet.y);
|
||||
+ to.setZ(packet.z);
|
||||
+ }
|
||||
+
|
||||
+ // If the packet contains look information then we update the To location with the correct Yaw & Pitch.
|
||||
+ if (packet.hasRot) {
|
||||
+ to.setYaw(packet.yRot);
|
||||
+ to.setPitch(packet.xRot);
|
||||
+ }
|
||||
+
|
||||
+ com.destroystokyo.paper.event.player.PlayerJumpEvent event = new com.destroystokyo.paper.event.player.PlayerJumpEvent(player, from, to);
|
||||
+
|
||||
+ if (event.callEvent()) {
|
||||
+ this.player.jumpFromGround();
|
||||
+ } else {
|
||||
+ from = event.getFrom();
|
||||
+ this.internalTeleport(from.getX(), from.getY(), from.getZ(), from.getYaw(), from.getPitch(), Collections.emptySet(), false);
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
boolean flag1 = this.player.verticalCollisionBelow;
|
|
@ -1,40 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shane Freeder <theboyetronic@gmail.com>
|
||||
Date: Thu, 5 Oct 2017 01:54:07 +0100
|
||||
Subject: [PATCH] handle ServerboundKeepAlivePacket async
|
||||
|
||||
In 1.12.2, Mojang moved the processing of ServerboundKeepAlivePacket off the main
|
||||
thread, while entirely correct for the server, this causes issues with
|
||||
plugins which are expecting the PlayerQuitEvent on the main thread.
|
||||
|
||||
In order to counteract some bad behavior, we will post handling of the
|
||||
disconnection to the main thread, but leave the actual processing of the packet
|
||||
off the main thread.
|
||||
|
||||
also adding some additional logging in order to help work out what is causing
|
||||
random disconnections for clients.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 751086ab2f87269ecd43306b794d8b1c3dcd143f..1669732069b255df1b53e3d82e310deab93dd296 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -2996,14 +2996,18 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
|
||||
|
||||
@Override
|
||||
public void handleKeepAlive(ServerboundKeepAlivePacket packet) {
|
||||
- PacketUtils.ensureRunningOnSameThread(packet, this, this.player.getLevel()); // CraftBukkit
|
||||
+ //PacketUtils.ensureRunningOnSameThread(packet, this, this.player.getLevel()); // CraftBukkit // Paper - This shouldn't be on the main thread
|
||||
if (this.keepAlivePending && packet.getId() == this.keepAliveChallenge) {
|
||||
int i = (int) (Util.getMillis() - this.keepAliveTime);
|
||||
|
||||
this.player.latency = (this.player.latency * 3 + i) / 4;
|
||||
this.keepAlivePending = false;
|
||||
} else if (!this.isSingleplayerOwner()) {
|
||||
+ // Paper start - This needs to be handled on the main thread for plugins
|
||||
+ server.submit(() -> {
|
||||
this.disconnect(Component.translatable("disconnect.timeout"));
|
||||
+ });
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
}
|
|
@ -1,116 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Minecrell <minecrell@minecrell.net>
|
||||
Date: Tue, 10 Oct 2017 18:45:20 +0200
|
||||
Subject: [PATCH] Expose client protocol version and virtual host
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/network/PaperNetworkClient.java b/src/main/java/com/destroystokyo/paper/network/PaperNetworkClient.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..a5a7624f1f372a26b982836cd31cff15e2589e9b
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/network/PaperNetworkClient.java
|
||||
@@ -0,0 +1,49 @@
|
||||
+package com.destroystokyo.paper.network;
|
||||
+
|
||||
+import java.net.InetSocketAddress;
|
||||
+
|
||||
+import javax.annotation.Nullable;
|
||||
+import net.minecraft.network.Connection;
|
||||
+
|
||||
+public class PaperNetworkClient implements NetworkClient {
|
||||
+
|
||||
+ private final Connection networkManager;
|
||||
+
|
||||
+ PaperNetworkClient(Connection networkManager) {
|
||||
+ this.networkManager = networkManager;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public InetSocketAddress getAddress() {
|
||||
+ return (InetSocketAddress) this.networkManager.getRemoteAddress();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getProtocolVersion() {
|
||||
+ return this.networkManager.protocolVersion;
|
||||
+ }
|
||||
+
|
||||
+ @Nullable
|
||||
+ @Override
|
||||
+ public InetSocketAddress getVirtualHost() {
|
||||
+ return this.networkManager.virtualHost;
|
||||
+ }
|
||||
+
|
||||
+ public static InetSocketAddress prepareVirtualHost(String host, int port) {
|
||||
+ int len = host.length();
|
||||
+
|
||||
+ // FML appends a marker to the host to recognize FML clients (\0FML\0)
|
||||
+ int pos = host.indexOf('\0');
|
||||
+ if (pos >= 0) {
|
||||
+ len = pos;
|
||||
+ }
|
||||
+
|
||||
+ // When clients connect with a SRV record, their host contains a trailing '.'
|
||||
+ if (len > 0 && host.charAt(len - 1) == '.') {
|
||||
+ len--;
|
||||
+ }
|
||||
+
|
||||
+ return InetSocketAddress.createUnresolved(host.substring(0, len), port);
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
diff --git a/src/main/java/net/minecraft/network/Connection.java b/src/main/java/net/minecraft/network/Connection.java
|
||||
index 0badcf02feafafc9932420ffee5062f7b99a9eb9..0e338ebdea3a02d56e9149a6904bfdc8889167f1 100644
|
||||
--- a/src/main/java/net/minecraft/network/Connection.java
|
||||
+++ b/src/main/java/net/minecraft/network/Connection.java
|
||||
@@ -93,6 +93,10 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
private float averageSentPackets;
|
||||
private int tickCount;
|
||||
private boolean handlingFault;
|
||||
+ // Paper start - NetworkClient implementation
|
||||
+ public int protocolVersion;
|
||||
+ public java.net.InetSocketAddress virtualHost;
|
||||
+ // Paper end
|
||||
|
||||
public Connection(PacketFlow side) {
|
||||
this.receiving = side;
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java
|
||||
index 9016aced079108aeae09f030a672467a953ef93f..4170bda451df3db43e7d57d87d1abb81934d7dad 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java
|
||||
@@ -154,6 +154,10 @@ public class ServerHandshakePacketListenerImpl implements ServerHandshakePacketL
|
||||
throw new UnsupportedOperationException("Invalid intention " + packet.getIntention());
|
||||
}
|
||||
|
||||
+ // Paper start - NetworkClient implementation
|
||||
+ this.connection.protocolVersion = packet.getProtocolVersion();
|
||||
+ this.connection.virtualHost = com.destroystokyo.paper.network.PaperNetworkClient.prepareVirtualHost(packet.hostName, packet.port);
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
index 7f4ed398c48534eec4303a394f360f476b7757ad..89f722ba437a5c2563af652431432cbc2a607fdd 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
@@ -218,6 +218,20 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
}
|
||||
}
|
||||
|
||||
+ // Paper start - Implement NetworkClient
|
||||
+ @Override
|
||||
+ public int getProtocolVersion() {
|
||||
+ if (getHandle().connection == null) return -1;
|
||||
+ return getHandle().connection.connection.protocolVersion;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public InetSocketAddress getVirtualHost() {
|
||||
+ if (getHandle().connection == null) return null;
|
||||
+ return getHandle().connection.connection.virtualHost;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public double getEyeHeight(boolean ignorePose) {
|
||||
if (ignorePose) {
|
|
@ -1,73 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shane Freeder <theboyetronic@gmail.com>
|
||||
Date: Sun, 15 Oct 2017 00:29:07 +0100
|
||||
Subject: [PATCH] revert serverside behavior of keepalives
|
||||
|
||||
This patch intends to bump up the time that a client has to reply to the
|
||||
server back to 30 seconds as per pre 1.12.2, which allowed clients
|
||||
more than enough time to reply potentially allowing them to be less
|
||||
tempermental due to lag spikes on the network thread, e.g. that caused
|
||||
by plugins that are interacting with netty.
|
||||
|
||||
We also add a system property to allow people to tweak how long the server
|
||||
will wait for a reply. There is a compromise here between lower and higher
|
||||
values, lower values will mean that dead connections can be closed sooner,
|
||||
whereas higher values will make this less sensitive to issues such as spikes
|
||||
from networking or during connections flood of chunk packets on slower clients,
|
||||
at the cost of dead connections being kept open for longer.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 1669732069b255df1b53e3d82e310deab93dd296..b3d75627ecf672c048e9129e3e64a1994f683204 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -240,7 +240,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
|
||||
public ServerPlayer player;
|
||||
private int tickCount;
|
||||
private int ackBlockChangesUpTo = -1;
|
||||
- private long keepAliveTime;
|
||||
+ private long keepAliveTime = Util.getMillis();
|
||||
private boolean keepAlivePending;
|
||||
private long keepAliveChallenge;
|
||||
// CraftBukkit start - multithreaded fields
|
||||
@@ -273,6 +273,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
|
||||
private int knownMovePacketCount;
|
||||
private final ChatPreviewThrottler chatPreviewThrottler = new ChatPreviewThrottler();
|
||||
private final AtomicReference<Instant> lastChatTimeStamp;
|
||||
+ private static final long KEEPALIVE_LIMIT = Long.getLong("paper.playerconnection.keepalive", 30) * 1000; // Paper - provide property to set keepalive limit
|
||||
|
||||
public ServerGamePacketListenerImpl(MinecraftServer server, Connection connection, ServerPlayer player) {
|
||||
this.lastChatTimeStamp = new AtomicReference(Instant.EPOCH);
|
||||
@@ -360,18 +361,25 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
|
||||
}
|
||||
|
||||
this.server.getProfiler().push("keepAlive");
|
||||
- long i = Util.getMillis();
|
||||
-
|
||||
- if (i - this.keepAliveTime >= 25000L) { // CraftBukkit
|
||||
- if (this.keepAlivePending) {
|
||||
- this.disconnect(Component.translatable("disconnect.timeout"));
|
||||
- } else {
|
||||
+ // Paper Start - give clients a longer time to respond to pings as per pre 1.12.2 timings
|
||||
+ // This should effectively place the keepalive handling back to "as it was" before 1.12.2
|
||||
+ long currentTime = Util.getMillis();
|
||||
+ long elapsedTime = currentTime - this.keepAliveTime;
|
||||
+
|
||||
+ if (this.keepAlivePending) {
|
||||
+ if (!this.processedDisconnect && elapsedTime >= KEEPALIVE_LIMIT) { // check keepalive limit, don't fire if already disconnected
|
||||
+ ServerGamePacketListenerImpl.LOGGER.warn("{} was kicked due to keepalive timeout!", this.player.getScoreboardName()); // more info
|
||||
+ this.disconnect(Component.translatable("disconnect.timeout", new Object[0]));
|
||||
+ }
|
||||
+ } else {
|
||||
+ if (elapsedTime >= 15000L) { // 15 seconds
|
||||
this.keepAlivePending = true;
|
||||
- this.keepAliveTime = i;
|
||||
- this.keepAliveChallenge = i;
|
||||
+ this.keepAliveTime = currentTime;
|
||||
+ this.keepAliveChallenge = currentTime;
|
||||
this.send(new ClientboundKeepAlivePacket(this.keepAliveChallenge));
|
||||
}
|
||||
}
|
||||
+ // Paper end
|
||||
|
||||
this.server.getProfiler().pop();
|
||||
// CraftBukkit start
|
|
@ -1,72 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Brokkonaut <hannos17@gmx.de>
|
||||
Date: Tue, 31 Oct 2017 03:26:18 +0100
|
||||
Subject: [PATCH] Send attack SoundEffects only to players who can see the
|
||||
attacker
|
||||
|
||||
|
||||
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 794081610e52b7b8e04403510d1ad05f4f11d320..98d776dc6970c5412cfe54538228c6fda2b0d02e 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
@@ -1245,7 +1245,7 @@ public abstract class Player extends LivingEntity {
|
||||
int i = b0 + EnchantmentHelper.getKnockbackBonus(this);
|
||||
|
||||
if (this.isSprinting() && flag) {
|
||||
- this.level.playSound((Player) null, this.getX(), this.getY(), this.getZ(), SoundEvents.PLAYER_ATTACK_KNOCKBACK, this.getSoundSource(), 1.0F, 1.0F);
|
||||
+ sendSoundEffect(this, this.getX(), this.getY(), this.getZ(), SoundEvents.PLAYER_ATTACK_KNOCKBACK, this.getSoundSource(), 1.0F, 1.0F); // Paper - send while respecting visibility
|
||||
++i;
|
||||
flag1 = true;
|
||||
}
|
||||
@@ -1320,7 +1320,7 @@ public abstract class Player extends LivingEntity {
|
||||
}
|
||||
}
|
||||
|
||||
- this.level.playSound((Player) null, this.getX(), this.getY(), this.getZ(), SoundEvents.PLAYER_ATTACK_SWEEP, this.getSoundSource(), 1.0F, 1.0F);
|
||||
+ sendSoundEffect(this, this.getX(), this.getY(), this.getZ(), SoundEvents.PLAYER_ATTACK_SWEEP, this.getSoundSource(), 1.0F, 1.0F); // Paper - send while respecting visibility
|
||||
this.sweepAttack();
|
||||
}
|
||||
|
||||
@@ -1348,15 +1348,15 @@ public abstract class Player extends LivingEntity {
|
||||
}
|
||||
|
||||
if (flag2) {
|
||||
- this.level.playSound((Player) null, this.getX(), this.getY(), this.getZ(), SoundEvents.PLAYER_ATTACK_CRIT, this.getSoundSource(), 1.0F, 1.0F);
|
||||
+ sendSoundEffect(this, this.getX(), this.getY(), this.getZ(), SoundEvents.PLAYER_ATTACK_CRIT, this.getSoundSource(), 1.0F, 1.0F); // Paper - send while respecting visibility
|
||||
this.crit(target);
|
||||
}
|
||||
|
||||
if (!flag2 && !flag3) {
|
||||
if (flag) {
|
||||
- this.level.playSound((Player) null, this.getX(), this.getY(), this.getZ(), SoundEvents.PLAYER_ATTACK_STRONG, this.getSoundSource(), 1.0F, 1.0F);
|
||||
+ sendSoundEffect(this, this.getX(), this.getY(), this.getZ(), SoundEvents.PLAYER_ATTACK_STRONG, this.getSoundSource(), 1.0F, 1.0F); // Paper - send while respecting visibility
|
||||
} else {
|
||||
- this.level.playSound((Player) null, this.getX(), this.getY(), this.getZ(), SoundEvents.PLAYER_ATTACK_WEAK, this.getSoundSource(), 1.0F, 1.0F);
|
||||
+ sendSoundEffect(this, this.getX(), this.getY(), this.getZ(), SoundEvents.PLAYER_ATTACK_WEAK, this.getSoundSource(), 1.0F, 1.0F); // Paper - send while respecting visibility
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1408,7 +1408,7 @@ public abstract class Player extends LivingEntity {
|
||||
|
||||
this.causeFoodExhaustion(level.spigotConfig.combatExhaustion, EntityExhaustionEvent.ExhaustionReason.ATTACK); // CraftBukkit - EntityExhaustionEvent // Spigot - Change to use configurable value
|
||||
} else {
|
||||
- this.level.playSound((Player) null, this.getX(), this.getY(), this.getZ(), SoundEvents.PLAYER_ATTACK_NODAMAGE, this.getSoundSource(), 1.0F, 1.0F);
|
||||
+ sendSoundEffect(this, this.getX(), this.getY(), this.getZ(), SoundEvents.PLAYER_ATTACK_NODAMAGE, this.getSoundSource(), 1.0F, 1.0F); // Paper - send while respecting visibility
|
||||
if (flag4) {
|
||||
target.clearFire();
|
||||
}
|
||||
@@ -1861,6 +1861,14 @@ public abstract class Player extends LivingEntity {
|
||||
public int getXpNeededForNextLevel() {
|
||||
return this.experienceLevel >= 30 ? 112 + (this.experienceLevel - 30) * 9 : (this.experienceLevel >= 15 ? 37 + (this.experienceLevel - 15) * 5 : 7 + this.experienceLevel * 2);
|
||||
}
|
||||
+ // Paper start - send SoundEffect to everyone who can see fromEntity
|
||||
+ private static void sendSoundEffect(Player fromEntity, double x, double y, double z, SoundEvent soundEffect, SoundSource soundCategory, float volume, float pitch) {
|
||||
+ fromEntity.level.playSound(fromEntity, x, y, z, soundEffect, soundCategory, volume, pitch); // This will not send the effect to the entity himself
|
||||
+ if (fromEntity instanceof ServerPlayer) {
|
||||
+ ((ServerPlayer) fromEntity).connection.send(new net.minecraft.network.protocol.game.ClientboundSoundPacket(soundEffect, soundCategory, x, y, z, volume, pitch, fromEntity.random.nextLong()));
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
// CraftBukkit start
|
||||
public void causeFoodExhaustion(float exhaustion) {
|
|
@ -1,31 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: pkt77 <parkerkt77@gmail.com>
|
||||
Date: Fri, 10 Nov 2017 23:46:34 -0500
|
||||
Subject: [PATCH] Add PlayerArmorChangeEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
index 20bc6684b0394fe08aa35c371bf668d8ebcf98b1..39635eae8b2f92ffb171c5cbb37bed5bd610266b 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.minecraft.world.entity;
|
||||
|
||||
+import com.destroystokyo.paper.event.player.PlayerArmorChangeEvent; // Paper
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
@@ -2974,6 +2975,13 @@ public abstract class LivingEntity extends Entity {
|
||||
ItemStack itemstack1 = this.getItemBySlot(enumitemslot);
|
||||
|
||||
if (!ItemStack.matches(itemstack1, itemstack)) {
|
||||
+ // Paper start - PlayerArmorChangeEvent
|
||||
+ if (this instanceof ServerPlayer && enumitemslot.getType() == EquipmentSlot.Type.ARMOR) {
|
||||
+ final org.bukkit.inventory.ItemStack oldItem = CraftItemStack.asBukkitCopy(itemstack);
|
||||
+ final org.bukkit.inventory.ItemStack newItem = CraftItemStack.asBukkitCopy(itemstack1);
|
||||
+ new PlayerArmorChangeEvent((Player) this.getBukkitEntity(), PlayerArmorChangeEvent.SlotType.valueOf(enumitemslot.name()), oldItem, newItem).callEvent();
|
||||
+ }
|
||||
+ // Paper end
|
||||
if (map == null) {
|
||||
map = Maps.newEnumMap(EquipmentSlot.class);
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue