even even more work

This commit is contained in:
Spottedleaf 2020-06-25 06:11:48 -07:00
parent d30edc35eb
commit 4aa7955818
33 changed files with 200 additions and 183 deletions

View File

@ -24,7 +24,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ } + }
@Nullable @Nullable
public static Entry<EnumItemSlot, ItemStack> b(Enchantment enchantment, EntityLiving entityliving) { public static Entry<EnumItemSlot, ItemStack> b(Enchantment enchantment, EntityLiving entityliving) {
Map<EnumItemSlot, ItemStack> map = enchantment.a(entityliving); return a(enchantment, entityliving, (itemstack) -> {
diff --git a/src/main/java/net/minecraft/server/EntityExperienceOrb.java b/src/main/java/net/minecraft/server/EntityExperienceOrb.java diff --git a/src/main/java/net/minecraft/server/EntityExperienceOrb.java b/src/main/java/net/minecraft/server/EntityExperienceOrb.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/EntityExperienceOrb.java --- a/src/main/java/net/minecraft/server/EntityExperienceOrb.java

View File

@ -16,7 +16,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import com.destroystokyo.paper.profile.PlayerProfile; +import com.destroystokyo.paper.profile.PlayerProfile;
import com.mojang.authlib.GameProfile; import com.mojang.authlib.GameProfile;
import com.mojang.authlib.exceptions.AuthenticationUnavailableException; import com.mojang.authlib.exceptions.AuthenticationUnavailableException;
import io.netty.channel.ChannelFuture; import java.math.BigInteger;
@@ -0,0 +0,0 @@ import org.apache.logging.log4j.LogManager; @@ -0,0 +0,0 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;

View File

@ -11,24 +11,24 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ @@ -0,0 +0,0 @@
package net.minecraft.server; package net.minecraft.server;
+import com.destroystokyo.paper.event.player.PlayerArmorChangeEvent; +import com.destroystokyo.paper.event.player.PlayerArmorChangeEvent; // Paper
import com.google.common.base.Objects; import com.google.common.base.Objects;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableMap;
@@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity { @@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity {
ItemStack itemstack1 = this.getEquipment(enumitemslot); ItemStack itemstack1 = this.getEquipment(enumitemslot);
if (!ItemStack.matches(itemstack1, itemstack)) { if (!ItemStack.matches(itemstack1, itemstack)) {
+ // Paper start - PlayerArmorChangeEvent + // Paper start - PlayerArmorChangeEvent
+ if (this instanceof EntityPlayer && enumitemslot.getType() == EnumItemSlot.Function.ARMOR) { + if (this instanceof EntityPlayer && enumitemslot.getType() == EnumItemSlot.Function.ARMOR) {
+ final org.bukkit.inventory.ItemStack oldItem = CraftItemStack.asBukkitCopy(itemstack); + final org.bukkit.inventory.ItemStack oldItem = CraftItemStack.asBukkitCopy(itemstack);
+ final org.bukkit.inventory.ItemStack newItem = CraftItemStack.asBukkitCopy(itemstack1); + final org.bukkit.inventory.ItemStack newItem = CraftItemStack.asBukkitCopy(itemstack1);
+ new PlayerArmorChangeEvent((Player) this.getBukkitEntity(), PlayerArmorChangeEvent.SlotType.valueOf(enumitemslot.name()), oldItem, newItem).callEvent(); + new PlayerArmorChangeEvent((Player) this.getBukkitEntity(), PlayerArmorChangeEvent.SlotType.valueOf(enumitemslot.name()), oldItem, newItem).callEvent();
+ } + }
+ // Paper end + // Paper end
((WorldServer) this.world).getChunkProvider().broadcast(this, new PacketPlayOutEntityEquipment(this.getId(), enumitemslot, itemstack1)); if (map == null) {
if (!itemstack.isEmpty()) { map = Maps.newEnumMap(EnumItemSlot.class);
this.getAttributeMap().a(itemstack.a(enumitemslot)); }
diff --git a/src/main/java/net/minecraft/server/EnumItemSlot.java b/src/main/java/net/minecraft/server/EnumItemSlot.java diff --git a/src/main/java/net/minecraft/server/EnumItemSlot.java b/src/main/java/net/minecraft/server/EnumItemSlot.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/EnumItemSlot.java --- a/src/main/java/net/minecraft/server/EnumItemSlot.java

View File

@ -18,9 +18,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
// CraftBukkit end // CraftBukkit end
@@ -0,0 +0,0 @@ public class PlayerConnection implements PacketListenerPlayIn { @@ -0,0 +0,0 @@ public class PlayerConnection implements PacketListenerPlayIn {
} boolean flag = d8 > 0.0D;
if (this.player.onGround && !packetplayinflying.b() && d8 > 0.0D) { if (this.player.isOnGround() && !packetplayinflying.b() && flag) {
- this.player.jump(); - this.player.jump();
+ // Paper start - Add player jump event + // Paper start - Add player jump event
+ Player player = this.getPlayer(); + Player player = this.getPlayer();

View File

@ -8,9 +8,9 @@ diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/ja
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -0,0 +0,0 @@ import net.minecraft.server.WorldServer; @@ -0,0 +0,0 @@ import net.minecraft.server.WorldNBTStorage;
import net.minecraft.server.WorldServer;
import net.minecraft.server.WorldSettings; import net.minecraft.server.WorldSettings;
import net.minecraft.server.WorldType;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
+import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.StringUtils;
import org.bukkit.BanList; import org.bukkit.BanList;

View File

@ -38,6 +38,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ if (com.destroystokyo.paper.PaperConfig.authenticationServersDownKickMessage != null) { + if (com.destroystokyo.paper.PaperConfig.authenticationServersDownKickMessage != null) {
+ LoginListener.this.disconnect(new ChatComponentText(com.destroystokyo.paper.PaperConfig.authenticationServersDownKickMessage)); + LoginListener.this.disconnect(new ChatComponentText(com.destroystokyo.paper.PaperConfig.authenticationServersDownKickMessage));
+ } else // Paper end + } else // Paper end
LoginListener.this.disconnect(new ChatMessage("multiplayer.disconnect.authservers_down", new Object[0])); LoginListener.this.disconnect(new ChatMessage("multiplayer.disconnect.authservers_down"));
LoginListener.LOGGER.error("Couldn't verify username because servers are unavailable"); LoginListener.LOGGER.error("Couldn't verify username because servers are unavailable");
} }

View File

@ -46,19 +46,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // If the event isn't handled, we can assume that we have no completions, and so we'll ask the server + // If the event isn't handled, we can assume that we have no completions, and so we'll ask the server
+ if (!event.isHandled()) { + if (!event.isHandled()) {
+ if (!event.isCancelled()) { + if (!event.isCancelled()) {
+ // Paper end - async tab completion
+ this.minecraftServer.scheduleOnMain(() -> { // Paper - This needs to be on main
+ ParseResults<CommandListenerWrapper> parseresults = this.minecraftServer.getCommandDispatcher().a().parse(stringreader, this.player.getCommandListener());
this.minecraftServer.getCommandDispatcher().a().getCompletionSuggestions(parseresults).thenAccept((suggestions) -> { - this.minecraftServer.getCommandDispatcher().a().getCompletionSuggestions(parseresults).thenAccept((suggestions) -> {
if (((Suggestions) suggestions).isEmpty()) return; // CraftBukkit - don't send through empty suggestions - prevents [<args>] from showing for plugins with nothing more to offer - if (suggestions.isEmpty()) return; // CraftBukkit - don't send through empty suggestions - prevents [<args>] from showing for plugins with nothing more to offer
- this.networkManager.sendPacket(new PacketPlayOutTabComplete(packetplayintabcomplete.b(), (Suggestions) suggestions)); // CraftBukkit - decompile error - this.networkManager.sendPacket(new PacketPlayOutTabComplete(packetplayintabcomplete.b(), suggestions));
- }); - });
+ this.networkManager.sendPacket(new PacketPlayOutTabComplete(packetplayintabcomplete.b(), (Suggestions) suggestions)); // CraftBukkit - decompile error + this.minecraftServer.scheduleOnMain(() -> { // Paper - This needs to be on main
+ }); + ParseResults<CommandListenerWrapper> parseresults = this.minecraftServer.getCommandDispatcher().a().parse(stringreader, this.player.getCommandListener());
+ }); // Paper - This needs to be on main +
+ this.minecraftServer.getCommandDispatcher().a().getCompletionSuggestions(parseresults).thenAccept((suggestions) -> {
+ if (suggestions.isEmpty()) return; // CraftBukkit - don't send through empty suggestions - prevents [<args>] from showing for plugins with nothing more to offer
+ this.networkManager.sendPacket(new PacketPlayOutTabComplete(packetplayintabcomplete.b(), suggestions));
+ });
+ });
+ } + }
+ // Paper start - async tab completion
+ } else if (!completions.isEmpty()) { + } else if (!completions.isEmpty()) {
+ com.mojang.brigadier.suggestion.SuggestionsBuilder builder = new com.mojang.brigadier.suggestion.SuggestionsBuilder(packetplayintabcomplete.c(), stringreader.getTotalLength()); + com.mojang.brigadier.suggestion.SuggestionsBuilder builder = new com.mojang.brigadier.suggestion.SuggestionsBuilder(packetplayintabcomplete.c(), stringreader.getTotalLength());
+ +
@ -67,7 +68,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ player.playerConnection.sendPacket(new PacketPlayOutTabComplete(packetplayintabcomplete.b(), builder.buildFuture().join())); + player.playerConnection.sendPacket(new PacketPlayOutTabComplete(packetplayintabcomplete.b(), builder.buildFuture().join()));
+ } + }
+ // Paper end - async tab completion + // Paper end - async tab completion
+
} }
@Override @Override

View File

@ -315,17 +315,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ @@ -0,0 +0,0 @@
+package com.destroystokyo.paper.profile; +package com.destroystokyo.paper.profile;
+ +
+import com.mojang.authlib.Agent; +import com.mojang.authlib.*;
+import com.mojang.authlib.GameProfileRepository;
+import com.mojang.authlib.UserAuthentication;
+import com.mojang.authlib.minecraft.MinecraftSessionService; +import com.mojang.authlib.minecraft.MinecraftSessionService;
+import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService; +import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService;
+import com.mojang.authlib.yggdrasil.YggdrasilEnvironment;
+ +
+import java.net.Proxy; +import java.net.Proxy;
+ +
+public class PaperAuthenticationService extends YggdrasilAuthenticationService { +public class PaperAuthenticationService extends YggdrasilAuthenticationService {
+ private final Environment environment;
+ public PaperAuthenticationService(Proxy proxy, String clientToken) { + public PaperAuthenticationService(Proxy proxy, String clientToken) {
+ super(proxy, clientToken); + super(proxy, clientToken);
+ this.environment = (Environment)EnvironmentParser.getEnvironmentFromProperties().orElse(YggdrasilEnvironment.PROD);;
+ } + }
+ +
+ @Override + @Override
@ -335,12 +336,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ +
+ @Override + @Override
+ public MinecraftSessionService createMinecraftSessionService() { + public MinecraftSessionService createMinecraftSessionService() {
+ return new PaperMinecraftSessionService(this); + return new PaperMinecraftSessionService(this, this.environment);
+ } + }
+ +
+ @Override + @Override
+ public GameProfileRepository createProfileRepository() { + public GameProfileRepository createProfileRepository() {
+ return new PaperGameProfileRepository(this); + 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 diff --git a/src/main/java/com/destroystokyo/paper/profile/PaperGameProfileRepository.java b/src/main/java/com/destroystokyo/paper/profile/PaperGameProfileRepository.java
@ -352,13 +353,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+package com.destroystokyo.paper.profile; +package com.destroystokyo.paper.profile;
+ +
+import com.mojang.authlib.Agent; +import com.mojang.authlib.Agent;
+import com.mojang.authlib.Environment;
+import com.mojang.authlib.ProfileLookupCallback; +import com.mojang.authlib.ProfileLookupCallback;
+import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService; +import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService;
+import com.mojang.authlib.yggdrasil.YggdrasilGameProfileRepository; +import com.mojang.authlib.yggdrasil.YggdrasilGameProfileRepository;
+ +
+public class PaperGameProfileRepository extends YggdrasilGameProfileRepository { +public class PaperGameProfileRepository extends YggdrasilGameProfileRepository {
+ public PaperGameProfileRepository(YggdrasilAuthenticationService authenticationService) { + public PaperGameProfileRepository(YggdrasilAuthenticationService authenticationService, Environment environment) {
+ super(authenticationService); + super(authenticationService, environment);
+ } + }
+ +
+ @Override + @Override
@ -374,6 +376,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ @@ -0,0 +0,0 @@
+package com.destroystokyo.paper.profile; +package com.destroystokyo.paper.profile;
+ +
+import com.mojang.authlib.Environment;
+import com.mojang.authlib.GameProfile; +import com.mojang.authlib.GameProfile;
+import com.mojang.authlib.minecraft.MinecraftProfileTexture; +import com.mojang.authlib.minecraft.MinecraftProfileTexture;
+import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService; +import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService;
@ -382,8 +385,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import java.util.Map; +import java.util.Map;
+ +
+public class PaperMinecraftSessionService extends YggdrasilMinecraftSessionService { +public class PaperMinecraftSessionService extends YggdrasilMinecraftSessionService {
+ protected PaperMinecraftSessionService(YggdrasilAuthenticationService authenticationService) { + protected PaperMinecraftSessionService(YggdrasilAuthenticationService authenticationService, Environment environment) {
+ super(authenticationService); + super(authenticationService, environment);
+ } + }
+ +
+ @Override + @Override
@ -445,21 +448,25 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
/** /**
* Calculates distance between 2 entities * Calculates distance between 2 entities
* @param e1 * @param e1
diff --git a/src/main/java/net/minecraft/server/Main.java b/src/main/java/net/minecraft/server/Main.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/Main.java
+++ b/src/main/java/net/minecraft/server/Main.java
@@ -0,0 +0,0 @@ public class Main {
}
File file = (File) optionset.valueOf("universe"); // CraftBukkit
- YggdrasilAuthenticationService yggdrasilauthenticationservice = new YggdrasilAuthenticationService(Proxy.NO_PROXY, UUID.randomUUID().toString());
+ YggdrasilAuthenticationService yggdrasilauthenticationservice = new com.destroystokyo.paper.profile.PaperAuthenticationService(Proxy.NO_PROXY, UUID.randomUUID().toString()); // Paper
MinecraftSessionService minecraftsessionservice = yggdrasilauthenticationservice.createMinecraftSessionService();
GameProfileRepository gameprofilerepository = yggdrasilauthenticationservice.createProfileRepository();
UserCache usercache = new UserCache(gameprofilerepository, new File(file, MinecraftServer.b.getName()));
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java --- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
DispenserRegistry.init(); this.G = i;
DispenserRegistry.c();
File s = (File) optionset.valueOf("universe"); // CraftBukkit
- YggdrasilAuthenticationService yggdrasilauthenticationservice = new YggdrasilAuthenticationService(Proxy.NO_PROXY, UUID.randomUUID().toString());
+ YggdrasilAuthenticationService yggdrasilauthenticationservice = new com.destroystokyo.paper.profile.PaperAuthenticationService(Proxy.NO_PROXY, UUID.randomUUID().toString()); // Paper
MinecraftSessionService minecraftsessionservice = yggdrasilauthenticationservice.createMinecraftSessionService();
GameProfileRepository gameprofilerepository = yggdrasilauthenticationservice.createProfileRepository();
UserCache usercache = new UserCache(gameprofilerepository, new File(s, MinecraftServer.b.getName()));
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
this.H = i;
} }
+ public final MinecraftSessionService getSessionService() { return this.getMinecraftSessionService(); } // Paper - OBFHELPER + public final MinecraftSessionService getSessionService() { return this.getMinecraftSessionService(); } // Paper - OBFHELPER

View File

@ -27,15 +27,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
super.a(d0, flag, iblockdata, blockposition); super.a(d0, flag, iblockdata, blockposition);
} }
+ public boolean canBreatheUnderwater() { return this.cB(); } // Paper - OBFHELPER + public boolean canBreatheUnderwater() { return this.cL(); } // Paper - OBFHELPER
public boolean cB() { public boolean cL() {
return this.getMonsterType() == EnumMonsterType.UNDEAD; return this.getMonsterType() == EnumMonsterType.UNDEAD;
} }
@@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity { @@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity {
if (this.isAlive()) { if (this.isAlive()) {
if (this.a(TagsFluid.WATER) && this.world.getType(new BlockPosition(this.locX(), this.getHeadY(), this.locZ())).getBlock() != Blocks.BUBBLE_COLUMN) { if (this.a((Tag) TagsFluid.WATER) && !this.world.getType(new BlockPosition(this.locX(), this.getHeadY(), this.locZ())).a(Blocks.BUBBLE_COLUMN)) {
- if (!this.cB() && !MobEffectUtil.c(this) && !flag1) { - if (!this.cL() && !MobEffectUtil.c(this) && !flag1) {
+ if (!this.canBreatheUnderwater() && !MobEffectUtil.c(this) && !flag1) { // Paper - use OBFHELPER so it can be overridden + if (!this.canBreatheUnderwater() && !MobEffectUtil.c(this) && !flag1) { // Paper - use OBFHELPER so it can be overridden
this.setAirTicks(this.l(this.getAirTicks())); this.setAirTicks(this.l(this.getAirTicks()));
if (this.getAirTicks() == -20) { if (this.getAirTicks() == -20) {

View File

@ -64,14 +64,6 @@ diff --git a/src/main/java/net/minecraft/server/HandshakeListener.java b/src/mai
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/HandshakeListener.java --- a/src/main/java/net/minecraft/server/HandshakeListener.java
+++ b/src/main/java/net/minecraft/server/HandshakeListener.java +++ b/src/main/java/net/minecraft/server/HandshakeListener.java
@@ -0,0 +0,0 @@ public class HandshakeListener implements PacketHandshakingInListener {
private final MinecraftServer a;
private final NetworkManager b;
+ private NetworkManager getNetworkManager() { return b; } // Paper - OBFHELPER
public HandshakeListener(MinecraftServer minecraftserver, NetworkManager networkmanager) {
this.a = minecraftserver;
@@ -0,0 +0,0 @@ public class HandshakeListener implements PacketHandshakingInListener { @@ -0,0 +0,0 @@ public class HandshakeListener implements PacketHandshakingInListener {
throw new UnsupportedOperationException("Invalid intention " + packethandshakinginsetprotocol.b()); throw new UnsupportedOperationException("Invalid intention " + packethandshakinginsetprotocol.b());
} }

View File

@ -29,14 +29,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
// Update any tile entity data for this block // Update any tile entity data for this block
TileEntity tileentity = this.world.getTileEntity(blockposition); TileEntity tileentity = this.world.getTileEntity(blockposition);
@@ -0,0 +0,0 @@ public class PlayerInteractManager { @@ -0,0 +0,0 @@ public class PlayerInteractManager {
((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutBlockChange(world, bottom ? blockposition.up() : blockposition.down())); interactResult = event.useItemInHand() == Event.Result.DENY;
if (event.useInteractedBlock() == Event.Result.DENY) {
+
// If we denied a door from opening, we need to send a correcting update to the client, as it already opened the door.
if (iblockdata.getBlock() instanceof BlockDoor) {
boolean bottom = iblockdata.get(BlockDoor.HALF) == BlockPropertyDoubleBlockHalf.LOWER;
entityplayer.playerConnection.sendPacket(new PacketPlayOutBlockChange(world, bottom ? blockposition.up() : blockposition.down()));
} else if (iblockdata.getBlock() instanceof BlockCake) { } else if (iblockdata.getBlock() instanceof BlockCake) {
((EntityPlayer) entityhuman).getBukkitEntity().sendHealthUpdate(); // SPIGOT-1341 - reset health for cake entityplayer.getBukkitEntity().sendHealthUpdate(); // SPIGOT-1341 - reset health for cake
+ // Paper start - extend Player Interact cancellation // TODO: consider merging this into the extracted method + // Paper start - extend Player Interact cancellation // TODO: consider merging this into the extracted method
+ } else if (iblockdata.getBlock() instanceof BlockStructure) { + } else if (iblockdata.getBlock() instanceof BlockStructure) {
+ ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutCloseWindow()); + entityplayer.playerConnection.sendPacket(new PacketPlayOutCloseWindow());
+ } else if (iblockdata.getBlock() instanceof BlockCommand) { + } else if (iblockdata.getBlock() instanceof BlockCommand) {
+ ((EntityPlayer) entityhuman).playerConnection.sendPacket(new PacketPlayOutCloseWindow()); + entityplayer.playerConnection.sendPacket(new PacketPlayOutCloseWindow());
+ } else if (iblockdata.getBlock() instanceof BlockFlowerPot) { + } else if (iblockdata.getBlock() instanceof BlockFlowerPot) {
+ // Send a block change to air and then send back the correct block, just to make the client happy + // Send a block change to air and then send back the correct block, just to make the client happy
+ PacketPlayOutBlockChange packet = new PacketPlayOutBlockChange(this.world, blockposition); + PacketPlayOutBlockChange packet = new PacketPlayOutBlockChange(this.world, blockposition);
@ -51,6 +58,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ } + }
} }
+ // Paper end - extend Player Interact cancellation + // Paper end - extend Player Interact cancellation
((EntityPlayer) entityhuman).getBukkitEntity().updateInventory(); // SPIGOT-2867 entityplayer.getBukkitEntity().updateInventory(); // SPIGOT-2867
enuminteractionresult = (event.useItemInHand() != Event.Result.ALLOW) ? EnumInteractionResult.SUCCESS : EnumInteractionResult.PASS; enuminteractionresult = (event.useItemInHand() != Event.Result.ALLOW) ? EnumInteractionResult.SUCCESS : EnumInteractionResult.PASS;
} else if (this.gamemode == EnumGamemode.SPECTATOR) { } else if (this.gamemode == EnumGamemode.SPECTATOR) {

View File

@ -17,6 +17,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ @@ -0,0 +0,0 @@
package com.destroystokyo.paper.profile; package com.destroystokyo.paper.profile;
import com.mojang.authlib.Environment;
+import com.destroystokyo.paper.event.profile.FillProfileEvent; +import com.destroystokyo.paper.event.profile.FillProfileEvent;
+import com.destroystokyo.paper.event.profile.PreFillProfileEvent; +import com.destroystokyo.paper.event.profile.PreFillProfileEvent;
import com.mojang.authlib.GameProfile; import com.mojang.authlib.GameProfile;

View File

@ -14,7 +14,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+++ b/src/main/java/org/bukkit/craftbukkit/Main.java +++ b/src/main/java/org/bukkit/craftbukkit/Main.java
@@ -0,0 +0,0 @@ public class Main { @@ -0,0 +0,0 @@ public class Main {
Calendar deadline = Calendar.getInstance(); Calendar deadline = Calendar.getInstance();
deadline.add(Calendar.DAY_OF_YEAR, -21); deadline.add(Calendar.DAY_OF_YEAR, -3);
if (buildDate.before(deadline.getTime())) { if (buildDate.before(deadline.getTime())) {
- System.err.println("*** Error, this build is outdated ***"); - System.err.println("*** Error, this build is outdated ***");
+ // Paper start - This is some stupid bullshit + // Paper start - This is some stupid bullshit

View File

@ -180,23 +180,23 @@ diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java --- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -0,0 +0,0 @@ @@ -0,0 +0,0 @@ package net.minecraft.server;
package net.minecraft.server;
import com.google.common.base.Splitter; import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableList;
+import co.aikar.timings.Timings; +import co.aikar.timings.Timings;
+import com.destroystokyo.paper.event.server.PaperServerListPingEvent; +import com.destroystokyo.paper.event.server.PaperServerListPingEvent;
+import com.google.common.base.Stopwatch; +import com.google.common.base.Stopwatch;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.google.gson.JsonElement; import com.google.common.collect.Sets;
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
if (i - this.Z >= 5000000000L) { if (i - this.T >= 5000000000L) {
this.Z = i; this.T = i;
this.serverPing.setPlayerSample(new ServerPing.ServerPingPlayerSample(this.getMaxPlayers(), this.getPlayerCount())); this.serverPing.setPlayerSample(new ServerPing.ServerPingPlayerSample(this.getMaxPlayers(), this.getPlayerCount()));
- GameProfile[] agameprofile = new GameProfile[Math.min(this.getPlayerCount(), 12)]; - GameProfile[] agameprofile = new GameProfile[Math.min(this.getPlayerCount(), 12)];
+ GameProfile[] agameprofile = new GameProfile[Math.min(this.getPlayerCount(), org.spigotmc.SpigotConfig.playerSample)]; // Paper + GameProfile[] agameprofile = new GameProfile[Math.min(this.getPlayerCount(), org.spigotmc.SpigotConfig.playerSample)]; // Paper
int j = MathHelper.nextInt(this.q, 0, this.getPlayerCount() - agameprofile.length); int j = MathHelper.nextInt(this.r, 0, this.getPlayerCount() - agameprofile.length);
for (int k = 0; k < agameprofile.length; ++k) { for (int k = 0; k < agameprofile.length; ++k) {
diff --git a/src/main/java/net/minecraft/server/PacketStatusListener.java b/src/main/java/net/minecraft/server/PacketStatusListener.java diff --git a/src/main/java/net/minecraft/server/PacketStatusListener.java b/src/main/java/net/minecraft/server/PacketStatusListener.java

View File

@ -11,19 +11,28 @@ diff --git a/src/main/java/net/minecraft/server/LocaleLanguage.java b/src/main/j
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/LocaleLanguage.java --- a/src/main/java/net/minecraft/server/LocaleLanguage.java
+++ b/src/main/java/net/minecraft/server/LocaleLanguage.java +++ b/src/main/java/net/minecraft/server/LocaleLanguage.java
@@ -0,0 +0,0 @@ public class LocaleLanguage { @@ -0,0 +0,0 @@ public abstract class LocaleLanguage {
private static LocaleLanguage c() {
Builder<String, String> builder = ImmutableMap.builder();
- BiConsumer biconsumer = builder::put;
+ BiConsumer<String, String> biconsumer = builder::put; // Paper - decompile fix
try {
InputStream inputstream = LocaleLanguage.class.getResourceAsStream("/assets/minecraft/lang/en_us.json");
@@ -0,0 +0,0 @@ public abstract class LocaleLanguage {
} }
+ public static LocaleLanguage getInstance() { return a(); } // Paper - OBFHELPER + public static LocaleLanguage getInstance() { return a(); } // Paper - OBFHELPER
public static LocaleLanguage a() { public static LocaleLanguage a() {
return LocaleLanguage.c; return LocaleLanguage.d;
} }
+ public synchronized String translateKey(String key) { return a(key); } // Paper - OBFHELPER + public String translateKey(String key) { return a(key); } // Paper - OBFHELPER
public synchronized String a(String s) { public abstract String a(String s);
return this.c(s);
} public abstract boolean b(String s);
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java

View File

@ -10,7 +10,7 @@ diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractHorse.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractHorse.java --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractHorse.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractHorse.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractHorse.java
@@ -0,0 +0,0 @@ import net.minecraft.server.EntityHorseAbstract; @@ -0,0 +0,0 @@ import net.minecraft.server.GenericAttributes;
import org.apache.commons.lang.Validate; import org.apache.commons.lang.Validate;
import org.bukkit.craftbukkit.CraftServer; import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.craftbukkit.inventory.CraftInventoryAbstractHorse; import org.bukkit.craftbukkit.inventory.CraftInventoryAbstractHorse;

View File

@ -11,13 +11,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ public abstract class EntityInsentient extends EntityLiving { @@ -0,0 +0,0 @@ public abstract class EntityInsentient extends EntityLiving {
EntityItem entityitem = (EntityItem) iterator.next(); EntityItem entityitem = (EntityItem) iterator.next();
if (!entityitem.dead && !entityitem.getItemStack().isEmpty() && !entityitem.p()) { if (!entityitem.dead && !entityitem.getItemStack().isEmpty() && !entityitem.p() && this.i(entityitem.getItemStack())) {
+ // Paper Start + // Paper Start
+ if (!entityitem.canMobPickup) { + if (!entityitem.canMobPickup) {
+ continue; + continue;
+ } + }
+ // Paper End + // Paper End
this.a(entityitem); this.b(entityitem);
} }
} }
diff --git a/src/main/java/net/minecraft/server/EntityItem.java b/src/main/java/net/minecraft/server/EntityItem.java diff --git a/src/main/java/net/minecraft/server/EntityItem.java b/src/main/java/net/minecraft/server/EntityItem.java

View File

@ -10,13 +10,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+++ b/src/main/java/net/minecraft/server/EntityLiving.java +++ b/src/main/java/net/minecraft/server/EntityLiving.java
@@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity { @@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity {
public float aL; public float aL;
public float aM; @Nullable
public EntityHuman killer; public EntityHuman killer;
- protected int lastDamageByPlayerTime; - protected int lastDamageByPlayerTime;
+ public int lastDamageByPlayerTime; // Paper - protected -> public + public int lastDamageByPlayerTime; // Paper - protected -> public
protected boolean killed; protected boolean killed;
protected int ticksFarFromPlayer; protected int ticksFarFromPlayer;
protected float aR; protected float aQ;
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java

View File

@ -16,4 +16,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ return !this.isTrusting() && !this.hasCustomName() && !this.isLeashed() /*&& this.ticksLived > 2400*/; // CraftBukkit // Paper - honor name and leash + return !this.isTrusting() && !this.hasCustomName() && !this.isLeashed() /*&& this.ticksLived > 2400*/; // CraftBukkit // Paper - honor name and leash
} }
@Override public static AttributeProvider.Builder eL() {

View File

@ -19,5 +19,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ } + }
+ // Paper end + // Paper end
this.d(advancement); this.d(advancement);
this.i.add(advancement); this.j.add(advancement);
flag = true; flag = true;

View File

@ -13,20 +13,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java --- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
+++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java +++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
@@ -0,0 +0,0 @@ public class ChunkProviderServer extends IChunkProvider { @@ -0,0 +0,0 @@ public class ChunkProviderServer extends IChunkProvider {
this.world.timings.countNaturalMobs.stopTiming(); // Paper - timings
this.world.getMethodProfiler().exit(); this.world.getMethodProfiler().exit();
//List<PlayerChunk> list = Lists.newArrayList(this.playerChunkMap.f()); // Paper
//Collections.shuffle(list); // Paper
+ //Paper start - call player naturally spawn event + //Paper start - call player naturally spawn event
+ int chunkRange = world.spigotConfig.mobSpawnRange; + int chunkRange = world.spigotConfig.mobSpawnRange;
+ chunkRange = (chunkRange > world.spigotConfig.viewDistance) ? (byte) world.spigotConfig.viewDistance : chunkRange; + chunkRange = (chunkRange > world.spigotConfig.viewDistance) ? (byte) world.spigotConfig.viewDistance : chunkRange;
+ chunkRange = Math.min(chunkRange, 8); + chunkRange = Math.min(chunkRange, 8);
+ for (EntityPlayer entityPlayer : this.world.players) { + for (EntityPlayer entityPlayer : this.world.getPlayers()) {
+ entityPlayer.playerNaturallySpawnedEvent = new com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent(entityPlayer.getBukkitEntity(), (byte) chunkRange); + entityPlayer.playerNaturallySpawnedEvent = new com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent(entityPlayer.getBukkitEntity(), (byte) chunkRange);
+ entityPlayer.playerNaturallySpawnedEvent.callEvent(); + entityPlayer.playerNaturallySpawnedEvent.callEvent();
+ }; + };
+ // Paper end + // Paper end
this.playerChunkMap.f().forEach((playerchunk) -> { this.playerChunkMap.f().forEach((playerchunk) -> { // Paper - no... just no...
Optional<Chunk> optional = ((Either) playerchunk.b().getNow(PlayerChunk.UNLOADED_CHUNK)).left(); Optional<Chunk> optional = ((Either) playerchunk.a().getNow(PlayerChunk.UNLOADED_CHUNK)).left();
diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644

View File

@ -13,8 +13,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@Override @Override
public void pickup(EntityHuman entityhuman) { public void pickup(EntityHuman entityhuman) {
if (!this.world.isClientSide) { if (!this.world.isClientSide) {
- if (this.d == 0 && entityhuman.bC == 0) { - if (this.d == 0 && entityhuman.bB == 0) {
+ if (this.d == 0 && entityhuman.bC == 0 && new com.destroystokyo.paper.event.player.PlayerPickupExperienceEvent(((EntityPlayer) entityhuman).getBukkitEntity(), (org.bukkit.entity.ExperienceOrb) this.getBukkitEntity()).callEvent()) { // Paper + if (this.d == 0 && entityhuman.bB == 0 && new com.destroystokyo.paper.event.player.PlayerPickupExperienceEvent(((EntityPlayer) entityhuman).getBukkitEntity(), (org.bukkit.entity.ExperienceOrb) this.getBukkitEntity()).callEvent()) { // Paper
entityhuman.bC = 2; entityhuman.bB = 2;
entityhuman.receive(this, 1); entityhuman.receive(this, 1);
Entry<EnumItemSlot, ItemStack> entry = EnchantmentManager.b(Enchantments.MENDING, (EntityLiving) entityhuman); Entry<EnumItemSlot, ItemStack> entry = EnchantmentManager.a(Enchantments.MENDING, (EntityLiving) entityhuman, ItemStack::f);

View File

@ -21,9 +21,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ public abstract class MobSpawnerAbstract { @@ -0,0 +0,0 @@ public abstract class MobSpawnerAbstract {
double d5 = j >= 3 ? nbttaglist.h(2) : (double) blockposition.getZ() + (world.random.nextDouble() - world.random.nextDouble()) * (double) this.spawnRange + 0.5D; double d5 = j >= 3 ? nbttaglist.h(2) : (double) blockposition.getZ() + (world.random.nextDouble() - world.random.nextDouble()) * (double) this.spawnRange + 0.5D;
if (world.a(((EntityTypes) optional.get()).a(d3, d4, d5)) && EntityPositionTypes.a((EntityTypes) optional.get(), world.getMinecraftWorld(), EnumMobSpawn.SPAWNER, new BlockPosition(d3, d4, d5), world.getRandom())) { if (world.b(((EntityTypes) optional.get()).a(d3, d4, d5)) && EntityPositionTypes.a((EntityTypes) optional.get(), world.getMinecraftWorld(), EnumMobSpawn.SPAWNER, new BlockPosition(d3, d4, d5), world.getRandom())) {
+ // Paper start + // Paper start
+ EntityTypes entityType = optional.get(); + EntityTypes<?> entityType = optional.get();
+ String key = EntityTypes.getName(entityType).getKey(); + String key = EntityTypes.getName(entityType).getKey();
+ +
+ org.bukkit.entity.EntityType type = org.bukkit.entity.EntityType.fromName(key); + org.bukkit.entity.EntityType type = org.bukkit.entity.EntityType.fromName(key);
@ -51,37 +51,42 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/server/SpawnerCreature.java --- a/src/main/java/net/minecraft/server/SpawnerCreature.java
+++ b/src/main/java/net/minecraft/server/SpawnerCreature.java +++ b/src/main/java/net/minecraft/server/SpawnerCreature.java
@@ -0,0 +0,0 @@ public final class SpawnerCreature { @@ -0,0 +0,0 @@ public final class SpawnerCreature {
BiomeBase.BiomeMeta biomebase_biomemeta = null; j1 = biomebase_biomemeta.d + worldserver.random.nextInt(1 + biomebase_biomemeta.e - biomebase_biomemeta.d);
GroupDataEntity groupdataentity = null; }
int l1 = MathHelper.f(Math.random() * 4.0D);
- int i2 = 0;
+ int i2 = 0; // Paper - force diff on name change
int j2 = 0;
while (true) { - if (a(worldserver, enumcreaturetype, structuremanager, chunkgenerator, biomebase_biomemeta, blockposition_mutableblockposition, d2) && spawnercreature_c.test(biomebase_biomemeta.c, blockposition_mutableblockposition, ichunkaccess)) {
+ // Paper start
+ Boolean doSpawning = a(worldserver, enumcreaturetype, structuremanager, chunkgenerator, biomebase_biomemeta, blockposition_mutableblockposition, d2);
+ if (doSpawning == null) {
+ return;
+ }
+ if (doSpawning.booleanValue() && spawnercreature_c.test(biomebase_biomemeta.c, blockposition_mutableblockposition, ichunkaccess)) { // Paper end
EntityInsentient entityinsentient = a(worldserver, biomebase_biomemeta.c);
if (entityinsentient == null) {
@@ -0,0 +0,0 @@ public final class SpawnerCreature { @@ -0,0 +0,0 @@ public final class SpawnerCreature {
if (a(entitypositiontypes_surface, (IWorldReader) worldserver, (BlockPosition) blockposition_mutableblockposition, entitytypes) && EntityPositionTypes.a(entitytypes, worldserver, EnumMobSpawn.NATURAL, blockposition_mutableblockposition, worldserver.random) && worldserver.a(entitytypes.a((double) f, (double) k, (double) f1))) { }
EntityInsentient entityinsentient; }
+ // Paper start - private static boolean a(WorldServer worldserver, EnumCreatureType enumcreaturetype, StructureManager structuremanager, ChunkGenerator chunkgenerator, BiomeBase.BiomeMeta biomebase_biomemeta, BlockPosition.MutableBlockPosition blockposition_mutableblockposition, double d0) {
+ com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent event; + private static Boolean a(WorldServer worldserver, EnumCreatureType enumcreaturetype, StructureManager structuremanager, ChunkGenerator chunkgenerator, BiomeBase.BiomeMeta biomebase_biomemeta, BlockPosition.MutableBlockPosition blockposition_mutableblockposition, double d0) { // Paper
+ EntityTypes<?> cls = biomebase_biomemeta.b; EntityTypes<?> entitytypes = biomebase_biomemeta.c;
+ org.bukkit.entity.EntityType type = org.bukkit.entity.EntityType.fromName(EntityTypes.getName(cls).getKey()); + // Paper start
+ if (type != null) { + com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent event;
+ event = new com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent( + org.bukkit.entity.EntityType type = org.bukkit.entity.EntityType.fromName(EntityTypes.getName(entitytypes).getKey());
+ MCUtil.toLocation(worldserver, blockposition_mutableblockposition), + if (type != null) {
+ type, SpawnReason.NATURAL + event = new com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent(
+ ); + MCUtil.toLocation(worldserver, blockposition_mutableblockposition),
+ if (!event.callEvent()) { + type, SpawnReason.NATURAL
+ if (event.shouldAbortSpawn()) { + );
+ return; + if (!event.callEvent()) {
+ } + if (event.shouldAbortSpawn()) {
+ ++i2; + return null;
+ continue; + }
+ } + return false; // TODO is this handled correctly?
+ } + }
+ // Paper end + }
+ + // Paper end
try {
Entity entity = entitytypes.a((World) worldserver);
if (entitytypes.e() == EnumCreatureType.MISC) {
return false;

View File

@ -9,22 +9,23 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/server/BlockIceFrost.java --- a/src/main/java/net/minecraft/server/BlockIceFrost.java
+++ b/src/main/java/net/minecraft/server/BlockIceFrost.java +++ b/src/main/java/net/minecraft/server/BlockIceFrost.java
@@ -0,0 +0,0 @@ public class BlockIceFrost extends BlockIce { @@ -0,0 +0,0 @@ public class BlockIceFrost extends BlockIce {
EnumDirection enumdirection = aenumdirection[j]; EnumDirection enumdirection = aenumdirection[j];
blockposition_pooledblockposition.g(blockposition).c(enumdirection); blockposition_mutableblockposition.a((BaseBlockPosition) blockposition, enumdirection);
- IBlockData iblockdata1 = worldserver.getType(blockposition_pooledblockposition); - IBlockData iblockdata1 = worldserver.getType(blockposition_mutableblockposition);
- + IBlockData iblockdata1 = worldserver.getTypeIfLoaded(blockposition_mutableblockposition); // Paper
+ IBlockData iblockdata1 = worldserver.getTypeIfLoaded(blockposition_pooledblockposition); // Paper - don't load chunks + if (iblockdata1 == null) { continue; } // Paper
+ if (iblockdata1 == null) continue; // Paper
if (iblockdata1.getBlock() == this && !this.e(iblockdata1, (World) worldserver, blockposition_pooledblockposition)) { if (iblockdata1.a((Block) this) && !this.e(iblockdata1, (World) worldserver, blockposition_mutableblockposition)) {
worldserver.getBlockTickList().a(blockposition_pooledblockposition, this, MathHelper.nextInt(random, worldserver.paperConfig.frostedIceDelayMin, worldserver.paperConfig.frostedIceDelayMax)); // Paper - use configurable min/max delay worldserver.getBlockTickList().a(blockposition_mutableblockposition, this, MathHelper.nextInt(random, worldserver.paperConfig.frostedIceDelayMin, worldserver.paperConfig.frostedIceDelayMax)); // Paper - use configurable min/max delay
}
@@ -0,0 +0,0 @@ public class BlockIceFrost extends BlockIce { @@ -0,0 +0,0 @@ public class BlockIceFrost extends BlockIce {
EnumDirection enumdirection = aenumdirection[l]; EnumDirection enumdirection = aenumdirection[l];
blockposition_pooledblockposition.g(blockposition).c(enumdirection); blockposition_mutableblockposition.a((BaseBlockPosition) blockposition, enumdirection);
- if (iblockaccess.getType(blockposition_pooledblockposition).getBlock() == this) { - if (iblockaccess.getType(blockposition_mutableblockposition).a((Block) this)) {
+ if (((World) iblockaccess).getBlockIfLoaded(blockposition_pooledblockposition) == this) { // Paper - don't load chunks + // Paper start
++j; + IBlockData type = iblockaccess.getTypeIfLoaded(blockposition_mutableblockposition);
if (j >= i) { + if (type != null && type.a((Block) this)) { // Paper end
boolean flag = false; ++j;
if (j >= i) {
return false;

View File

@ -20,5 +20,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ } + }
+ // Paper end + // Paper end
} else if (this.g == LoginListener.EnumProtocolState.DELAY_ACCEPT) { } else if (this.g == LoginListener.EnumProtocolState.DELAY_ACCEPT) {
EntityPlayer entityplayer = this.server.getPlayerList().a(this.i.getId()); EntityPlayer entityplayer = this.server.getPlayerList().getPlayer(this.i.getId());

View File

@ -17,18 +17,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import com.destroystokyo.paper.event.profile.PreLookupProfileEvent; +import com.destroystokyo.paper.event.profile.PreLookupProfileEvent;
+import com.google.common.collect.Sets; +import com.google.common.collect.Sets;
import com.mojang.authlib.Agent; import com.mojang.authlib.Agent;
import com.mojang.authlib.Environment;
+import com.mojang.authlib.GameProfile; +import com.mojang.authlib.GameProfile;
import com.mojang.authlib.ProfileLookupCallback; import com.mojang.authlib.ProfileLookupCallback;
import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService; import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService;
import com.mojang.authlib.yggdrasil.YggdrasilGameProfileRepository; import com.mojang.authlib.yggdrasil.YggdrasilGameProfileRepository;
+import java.util.Set; +import java.util.Set;
+
public class PaperGameProfileRepository extends YggdrasilGameProfileRepository { public class PaperGameProfileRepository extends YggdrasilGameProfileRepository {
+ public PaperGameProfileRepository(YggdrasilAuthenticationService authenticationService, Environment environment) {
public PaperGameProfileRepository(YggdrasilAuthenticationService authenticationService) { super(authenticationService, environment);
super(authenticationService); @@ -0,0 +0,0 @@ public class PaperGameProfileRepository extends YggdrasilGameProfileRepository {
}
@Override @Override
public void findProfilesByNames(String[] names, Agent agent, ProfileLookupCallback callback) { public void findProfilesByNames(String[] names, Agent agent, ProfileLookupCallback callback) {

View File

@ -9,12 +9,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/server/PlayerList.java --- a/src/main/java/net/minecraft/server/PlayerList.java
+++ b/src/main/java/net/minecraft/server/PlayerList.java +++ b/src/main/java/net/minecraft/server/PlayerList.java
@@ -0,0 +0,0 @@ public abstract class PlayerList { @@ -0,0 +0,0 @@ public abstract class PlayerList {
// return chatmessage;
if (!gameprofilebanentry.hasExpired()) event.disallow(PlayerLoginEvent.Result.KICK_BANNED, CraftChatMessage.fromComponent(chatmessage)); // Spigot if (!gameprofilebanentry.hasExpired()) event.disallow(PlayerLoginEvent.Result.KICK_BANNED, CraftChatMessage.fromComponent(chatmessage)); // Spigot
- } else if (!this.isWhitelisted(gameprofile)) { } else if (!this.isWhitelisted(gameprofile)) {
+ } else if (!this.isWhitelisted(gameprofile, event)) { // Paper chatmessage = new ChatMessage("multiplayer.disconnect.not_whitelisted");
chatmessage = new ChatMessage("multiplayer.disconnect.not_whitelisted", new Object[0]);
- event.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, org.spigotmc.SpigotConfig.whitelistMessage); // Spigot - event.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, org.spigotmc.SpigotConfig.whitelistMessage); // Spigot
+ //event.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, org.spigotmc.SpigotConfig.whitelistMessage); // Spigot // Paper - moved to isWhitelisted + //event.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, org.spigotmc.SpigotConfig.whitelistMessage); // Spigot // Paper - moved to isWhitelisted
} else if (getIPBans().isBanned(socketaddress) && !getIPBans().get(socketaddress).hasExpired()) { } else if (getIPBans().isBanned(socketaddress) && !getIPBans().get(socketaddress).hasExpired()) {
@ -46,4 +43,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Paper end + // Paper end
public boolean isOp(GameProfile gameprofile) { public boolean isOp(GameProfile gameprofile) {
return this.operators.d(gameprofile) || this.server.a(gameprofile) && this.server.getWorldServer(DimensionManager.OVERWORLD).getWorldData().t() || this.u; return this.operators.d(gameprofile) || this.server.a(gameprofile) && this.server.getSaveData().n() || this.v;

View File

@ -34,9 +34,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/server/MinecraftServer.java --- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
public final Map<DimensionManager, WorldServer> worldServer = Maps.newLinkedHashMap(); // CraftBukkit - keep order, k+v already use identity methods public final Map<ResourceKey<World>, WorldServer> worldServer;
private PlayerList playerList; private PlayerList playerList;
private volatile boolean isRunning = true; private volatile boolean isRunning;
+ private volatile boolean isRestarting = false; // Paper - flag to signify we're attempting to restart + private volatile boolean isRestarting = false; // Paper - flag to signify we're attempting to restart
private boolean isStopped; private boolean isStopped;
private int ticks; private int ticks;
@ -77,7 +77,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/server/PlayerList.java --- a/src/main/java/net/minecraft/server/PlayerList.java
+++ b/src/main/java/net/minecraft/server/PlayerList.java +++ b/src/main/java/net/minecraft/server/PlayerList.java
@@ -0,0 +0,0 @@ public abstract class PlayerList { @@ -0,0 +0,0 @@ public abstract class PlayerList {
entityplayer.playerInteractManager.b(generatoraccess.getWorldData().getGameType()); entityplayer.playerInteractManager.b(worldserver.getMinecraftServer().getSaveData().getGameType());
} }
+ // Paper start - Extract method to allow for restarting flag + // Paper start - Extract method to allow for restarting flag

View File

@ -23,7 +23,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Paper end + // Paper end
+ +
public void attack(Entity entity) { public void attack(Entity entity) {
if (entity.bA()) { if (entity.bH()) {
if (!entity.t(this)) { if (!entity.t(this)) {
@@ -0,0 +0,0 @@ public abstract class EntityHuman extends EntityLiving { @@ -0,0 +0,0 @@ public abstract class EntityHuman extends EntityLiving {
int i = b0 + EnchantmentManager.b((EntityLiving) this); int i = b0 + EnchantmentManager.b((EntityLiving) this);
@ -40,7 +40,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- this.world.playSound((EntityHuman) null, this.locX(), this.locY(), this.locZ(), SoundEffects.ENTITY_PLAYER_ATTACK_SWEEP, this.getSoundCategory(), 1.0F, 1.0F); - this.world.playSound((EntityHuman) null, this.locX(), this.locY(), this.locZ(), SoundEffects.ENTITY_PLAYER_ATTACK_SWEEP, this.getSoundCategory(), 1.0F, 1.0F);
+ sendSoundEffect(this, this.locX(), this.locY(), this.locZ(), SoundEffects.ENTITY_PLAYER_ATTACK_SWEEP, this.getSoundCategory(), 1.0F, 1.0F); // Paper - send while respecting visibility + sendSoundEffect(this, this.locX(), this.locY(), this.locZ(), SoundEffects.ENTITY_PLAYER_ATTACK_SWEEP, this.getSoundCategory(), 1.0F, 1.0F); // Paper - send while respecting visibility
this.ea(); this.ew();
} }
@@ -0,0 +0,0 @@ public abstract class EntityHuman extends EntityLiving { @@ -0,0 +0,0 @@ public abstract class EntityHuman extends EntityLiving {

View File

@ -194,10 +194,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
// CraftBukkit start // CraftBukkit start
-import jline.console.ConsoleReader; -import jline.console.ConsoleReader;
+import joptsimple.OptionSet; +// Paper
import joptsimple.OptionSet;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.CraftServer; import org.bukkit.craftbukkit.CraftServer;
import org.bukkit.craftbukkit.Main;
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
public OptionSet options; public OptionSet options;
public org.bukkit.command.ConsoleCommandSender console; public org.bukkit.command.ConsoleCommandSender console;
@ -208,9 +208,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public java.util.Queue<Runnable> processQueue = new java.util.concurrent.ConcurrentLinkedQueue<Runnable>(); public java.util.Queue<Runnable> processQueue = new java.util.concurrent.ConcurrentLinkedQueue<Runnable>();
public int autosavePeriod; public int autosavePeriod;
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
this.K = s;
// CraftBukkit start
this.options = options; this.options = options;
this.datapackconfiguration = datapackconfiguration;
this.vanillaCommandDispatcher = datapackresources.commandDispatcher; // CraftBukkit
+ // Paper start - Handled by TerminalConsoleAppender + // Paper start - Handled by TerminalConsoleAppender
// Try to see if we're actually running in a terminal, disable jline if not // Try to see if we're actually running in a terminal, disable jline if not
+ /* + /*
@ -238,7 +238,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
@Override @Override
public void sendMessage(IChatBaseComponent ichatbasecomponent) { public void sendMessage(IChatBaseComponent ichatbasecomponent, UUID uuid) {
- MinecraftServer.LOGGER.info(ichatbasecomponent.getString()); - MinecraftServer.LOGGER.info(ichatbasecomponent.getString());
+ MinecraftServer.LOGGER.info(org.bukkit.craftbukkit.util.CraftChatMessage.fromComponent(ichatbasecomponent));// Paper - Log message with colors + MinecraftServer.LOGGER.info(org.bukkit.craftbukkit.util.CraftChatMessage.fromComponent(ichatbasecomponent));// Paper - Log message with colors
} }
@ -250,7 +250,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+++ b/src/main/java/net/minecraft/server/PlayerList.java +++ b/src/main/java/net/minecraft/server/PlayerList.java
@@ -0,0 +0,0 @@ public abstract class PlayerList { @@ -0,0 +0,0 @@ public abstract class PlayerList {
public PlayerList(MinecraftServer minecraftserver, int i) { public PlayerList(MinecraftServer minecraftserver, IRegistryCustom.Dimension iregistrycustom_dimension, WorldNBTStorage worldnbtstorage, int i) {
this.cserver = minecraftserver.server = new CraftServer((DedicatedServer) minecraftserver, this); this.cserver = minecraftserver.server = new CraftServer((DedicatedServer) minecraftserver, this);
- minecraftserver.console = org.bukkit.craftbukkit.command.ColouredConsoleSender.getInstance(); - minecraftserver.console = org.bukkit.craftbukkit.command.ColouredConsoleSender.getInstance();
- minecraftserver.reader.addCompleter(new org.bukkit.craftbukkit.command.ConsoleCommandCompleter(minecraftserver.server)); - minecraftserver.reader.addCompleter(new org.bukkit.craftbukkit.command.ConsoleCommandCompleter(minecraftserver.server));
@ -270,7 +270,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+//import jline.console.ConsoleReader; // Paper +//import jline.console.ConsoleReader; // Paper
import net.minecraft.server.Advancement; import net.minecraft.server.Advancement;
import net.minecraft.server.ArgumentEntity; import net.minecraft.server.ArgumentEntity;
import net.minecraft.server.Block; import net.minecraft.server.BiomeManager;
@@ -0,0 +0,0 @@ public final class CraftServer implements Server { @@ -0,0 +0,0 @@ public final class CraftServer implements Server {
return logger; return logger;
} }
@ -289,10 +289,10 @@ diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/Main.java --- a/src/main/java/org/bukkit/craftbukkit/Main.java
+++ b/src/main/java/org/bukkit/craftbukkit/Main.java +++ b/src/main/java/org/bukkit/craftbukkit/Main.java
@@ -0,0 +0,0 @@ import java.util.logging.Logger; @@ -0,0 +0,0 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import joptsimple.OptionParser; import joptsimple.OptionParser;
import joptsimple.OptionSet; import joptsimple.OptionSet;
import net.minecraft.server.MinecraftServer;
-import org.fusesource.jansi.AnsiConsole; -import org.fusesource.jansi.AnsiConsole;
+import net.minecrell.terminalconsole.TerminalConsoleAppender; // Paper +import net.minecrell.terminalconsole.TerminalConsoleAppender; // Paper
@ -325,7 +325,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ System.setProperty(TerminalConsoleAppender.JLINE_OVERRIDE_PROPERTY, "false"); // Paper + System.setProperty(TerminalConsoleAppender.JLINE_OVERRIDE_PROPERTY, "false"); // Paper
} }
if (false && Main.class.getPackage().getImplementationVendor() != null && System.getProperty("IReallyKnowWhatIAmDoingISwear") == null) { if (Main.class.getPackage().getImplementationVendor() != null && System.getProperty("IReallyKnowWhatIAmDoingISwear") == null) {
@@ -0,0 +0,0 @@ public class Main { @@ -0,0 +0,0 @@ public class Main {
System.out.println("Unable to read system info"); System.out.println("Unable to read system info");
} }
@ -333,7 +333,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- -
+ System.setProperty( "library.jansi.version", "Paper" ); // Paper - set meaningless jansi version to prevent git builds from crashing on Windows + 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..."); System.out.println("Loading libraries, please wait...");
MinecraftServer.main(options); net.minecraft.server.Main.main(options);
} catch (Throwable t) { } 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 diff --git a/src/main/java/org/bukkit/craftbukkit/command/ColouredConsoleSender.java b/src/main/java/org/bukkit/craftbukkit/command/ColouredConsoleSender.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644

View File

@ -30,10 +30,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
this.player.ping = (this.player.ping * 3 + i) / 4; this.player.ping = (this.player.ping * 3 + i) / 4;
this.awaitingKeepAlive = false; this.awaitingKeepAlive = false;
} else if (!this.isExemptPlayer()) { } else if (!this.isExemptPlayer()) {
- this.disconnect(new ChatMessage("disconnect.timeout", new Object[0]));
+ // Paper start - This needs to be handled on the main thread for plugins + // Paper start - This needs to be handled on the main thread for plugins
+ minecraftServer.scheduleOnMain(() -> { + minecraftServer.scheduleOnMain(() -> {
+ this.disconnect(new ChatMessage("disconnect.timeout")); this.disconnect(new ChatMessage("disconnect.timeout"));
+ }); + });
+ // Paper end + // Paper end
} }

View File

@ -45,6 +45,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- -
- if (i - this.lastKeepAlive >= 25000L) { // CraftBukkit - if (i - this.lastKeepAlive >= 25000L) { // CraftBukkit
- if (this.awaitingKeepAlive) { - if (this.awaitingKeepAlive) {
- this.disconnect(new ChatMessage("disconnect.timeout"));
- } else {
- this.awaitingKeepAlive = true;
- this.lastKeepAlive = i;
- this.h = i;
- this.sendPacket(new PacketPlayOutKeepAlive(this.h));
+ // Paper Start - give clients a longer time to respond to pings as per pre 1.12.2 timings + // 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 + // This should effectively place the keepalive handling back to "as it was" before 1.12.2
+ long currentTime = SystemUtils.getMonotonicMillis(); + long currentTime = SystemUtils.getMonotonicMillis();
@ -53,12 +59,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ if (this.isPendingPing()) { + if (this.isPendingPing()) {
+ if (!this.processedDisconnect && elapsedTime >= KEEPALIVE_LIMIT) { // check keepalive limit, don't fire if already disconnected + if (!this.processedDisconnect && elapsedTime >= KEEPALIVE_LIMIT) { // check keepalive limit, don't fire if already disconnected
+ PlayerConnection.LOGGER.warn("{} was kicked due to keepalive timeout!", this.player.getName()); // more info + PlayerConnection.LOGGER.warn("{} was kicked due to keepalive timeout!", this.player.getName()); // more info
this.disconnect(new ChatMessage("disconnect.timeout", new Object[0])); + this.disconnect(new ChatMessage("disconnect.timeout", new Object[0]));
- } else {
- this.awaitingKeepAlive = true;
- this.lastKeepAlive = i;
- this.h = i;
- this.sendPacket(new PacketPlayOutKeepAlive(this.h));
+ } + }
+ } else { + } else {
+ if (elapsedTime >= 15000L) { // 15 seconds + if (elapsedTime >= 15000L) { // 15 seconds
@ -66,7 +67,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ this.setLastPing(currentTime); + this.setLastPing(currentTime);
+ this.setKeepAliveID(currentTime); + this.setKeepAliveID(currentTime);
+ this.sendPacket(new PacketPlayOutKeepAlive(this.getKeepAliveID())); + this.sendPacket(new PacketPlayOutKeepAlive(this.getKeepAliveID()));
+
} }
} }
+ // Paper end + // Paper end

View File

@ -31,7 +31,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public List<EntityItem> captureDrops; public List<EntityItem> captureDrops;
public long ticksPerAnimalSpawns; public long ticksPerAnimalSpawns;
@@ -0,0 +0,0 @@ public abstract class World implements GeneratorAccess, AutoCloseable { @@ -0,0 +0,0 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
public boolean setTypeAndData(BlockPosition blockposition, IBlockData iblockdata, int i) { public boolean a(BlockPosition blockposition, IBlockData iblockdata, int i, int j) {
// CraftBukkit start - tree generation // CraftBukkit start - tree generation
if (this.captureTreeGeneration) { if (this.captureTreeGeneration) {
- CapturedBlockState blockstate = capturedBlockStates.get(blockposition); - CapturedBlockState blockstate = capturedBlockStates.get(blockposition);