More more patches
This commit is contained in:
@@ -1,52 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Riley Park <rileysebastianpark@gmail.com>
|
||||
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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
@@ -0,0 +0,0 @@ public class ArmorStand extends LivingEntity {
|
||||
public Rotations rightArmPose;
|
||||
public Rotations leftLegPose;
|
||||
public Rotations rightLegPose;
|
||||
+ public boolean canMove = true; // Paper
|
||||
|
||||
public ArmorStand(EntityType<? extends ArmorStand> type, Level world) {
|
||||
super(type, world);
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java
|
||||
@@ -0,0 +0,0 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand {
|
||||
public 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,62 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Byteflux <byte@byteflux.net>
|
||||
Date: Wed, 2 Mar 2016 23:30:53 -0600
|
||||
Subject: [PATCH] Add BeaconEffectEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/BeaconBlockEntity.java
|
||||
@@ -0,0 +0,0 @@ import net.minecraft.world.phys.AABB;
|
||||
import org.bukkit.craftbukkit.potion.CraftPotionUtil;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
// CraftBukkit end
|
||||
+// Paper start
|
||||
+import org.bukkit.craftbukkit.event.CraftEventFactory;
|
||||
+import com.destroystokyo.paper.event.block.BeaconEffectEvent;
|
||||
+// Paper end
|
||||
|
||||
public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Nameable {
|
||||
|
||||
@@ -0,0 +0,0 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name
|
||||
}
|
||||
}
|
||||
|
||||
- private static void applyEffect(List list, MobEffect mobeffectlist, int j, int b0) {
|
||||
- {
|
||||
+ private static void applyEffect(List list, MobEffect effects, int i, int b0, boolean isPrimary, BlockPos worldPosition) { // Paper - BeaconEffectEvent
|
||||
+ if (!list.isEmpty()) { // Paper - BeaconEffectEvent
|
||||
Iterator iterator = list.iterator();
|
||||
|
||||
Player entityhuman;
|
||||
+ // Paper start - BeaconEffectEvent
|
||||
+ org.bukkit.block.Block block = ((Player) list.get(0)).level.getWorld().getBlockAt(worldPosition.getX(), worldPosition.getY(), worldPosition.getZ());
|
||||
+ PotionEffect effect = CraftPotionUtil.toBukkit(new MobEffectInstance(effects, i, b0, true, true));
|
||||
+ // Paper end
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
- entityhuman = (Player) iterator.next();
|
||||
- entityhuman.addEffect(new MobEffectInstance(mobeffectlist, j, b0, true, true), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.BEACON);
|
||||
+ // Paper start - BeaconEffectEvent
|
||||
+ entityhuman = (ServerPlayer) iterator.next();
|
||||
+ BeaconEffectEvent event = new BeaconEffectEvent(block, effect, (org.bukkit.entity.Player) entityhuman.getBukkitEntity(), isPrimary);
|
||||
+ if (CraftEventFactory.callEvent(event).isCancelled()) continue;
|
||||
+ entityhuman.addEffect(new MobEffectInstance(CraftPotionUtil.fromBukkit(event.getEffect())), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.BEACON);
|
||||
+ // Paper end
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class BeaconBlockEntity extends BlockEntity implements MenuProvider, Name
|
||||
int j = BeaconBlockEntity.getLevel(beaconLevel);
|
||||
List list = BeaconBlockEntity.getHumansInRange(world, pos, beaconLevel);
|
||||
|
||||
- BeaconBlockEntity.applyEffect(list, primaryEffect, j, b0);
|
||||
+ BeaconBlockEntity.applyEffect(list, primaryEffect, j, b0, true, pos); // Paper - BeaconEffectEvent
|
||||
|
||||
if (BeaconBlockEntity.hasSecondaryEffect(beaconLevel, primaryEffect, secondaryEffect)) {
|
||||
- BeaconBlockEntity.applyEffect(list, secondaryEffect, j, 0);
|
||||
+ BeaconBlockEntity.applyEffect(list, secondaryEffect, j, 0, false, pos); // Paper - BeaconEffectEvent
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/npc/Villager.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java
|
||||
@@ -0,0 +0,0 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
|
||||
@Override
|
||||
public void thunderHit(ServerLevel world, LightningBolt lightning) {
|
||||
if (world.getDifficulty() != Difficulty.PEACEFUL) {
|
||||
- Villager.LOGGER.info("Villager {} was struck by lightning {}.", this, lightning);
|
||||
+ // Paper - move log down, event can cancel
|
||||
Witch entitywitch = (Witch) EntityType.WITCH.create(world);
|
||||
|
||||
if (entitywitch != null) {
|
||||
+ // Paper start
|
||||
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityZapEvent(this, lightning, entitywitch).isCancelled()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ if (org.spigotmc.SpigotConfig.logVillagerDeaths) Villager.LOGGER.info("Villager {} was struck by lightning {}.", this, lightning); // Move down
|
||||
+ // Paper end
|
||||
+
|
||||
entitywitch.moveTo(this.getX(), this.getY(), this.getZ(), this.getYRot(), this.getXRot());
|
||||
entitywitch.finalizeSpawn(world, world.getCurrentDifficultyAt(entitywitch.blockPosition()), MobSpawnType.CONVERSION, (SpawnGroupData) null, (CompoundTag) null);
|
||||
entitywitch.setNoAi(this.isNoAi());
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
@@ -0,0 +0,0 @@ public class CraftEventFactory {
|
||||
return event;
|
||||
}
|
||||
|
||||
+ // 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,38 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Steve Anton <anxuiz.nx@gmail.com>
|
||||
Date: Thu, 3 Mar 2016 00:09:38 -0600
|
||||
Subject: [PATCH] Add PlayerInitialSpawnEvent
|
||||
|
||||
For modifying a player's initial spawn location as they join the server
|
||||
|
||||
This is a duplicate API from spigot, so use our duplicate subclass and
|
||||
improve setPosition to use raw
|
||||
|
||||
== AT ==
|
||||
public net.minecraft.world.entity.Entity setRot(FF)V
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
@@ -0,0 +0,0 @@ public abstract class PlayerList {
|
||||
|
||||
// Spigot start - spawn location event
|
||||
Player spawnPlayer = player.getBukkitEntity();
|
||||
- org.spigotmc.event.player.PlayerSpawnLocationEvent ev = new org.spigotmc.event.player.PlayerSpawnLocationEvent(spawnPlayer, spawnPlayer.getLocation());
|
||||
+ org.spigotmc.event.player.PlayerSpawnLocationEvent ev = new com.destroystokyo.paper.event.player.PlayerInitialSpawnEvent(spawnPlayer, spawnPlayer.getLocation()); // Paper use our duplicate event
|
||||
this.cserver.getPluginManager().callEvent(ev);
|
||||
|
||||
Location loc = ev.getSpawnLocation();
|
||||
@@ -0,0 +0,0 @@ public abstract class PlayerList {
|
||||
|
||||
player.spawnIn(worldserver1);
|
||||
player.gameMode.setLevel((ServerLevel) player.level);
|
||||
- player.absMoveTo(loc.getX(), loc.getY(), loc.getZ(), loc.getYaw(), loc.getPitch());
|
||||
+ // Paper start - set raw so we aren't fully joined to the world (not added to chunk or world)
|
||||
+ player.setPosRaw(loc.getX(), loc.getY(), loc.getZ());
|
||||
+ player.setRot(loc.getYaw(), loc.getPitch());
|
||||
+ // Paper end
|
||||
// Spigot end
|
||||
|
||||
// CraftBukkit - Moved message to after join
|
||||
@@ -1,65 +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
|
||||
|
||||
== AT ==
|
||||
public net.minecraft.network.protocol.game.ServerboundInteractPacket$ActionType
|
||||
|
||||
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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/network/protocol/game/ServerboundInteractPacket.java
|
||||
+++ b/src/main/java/net/minecraft/network/protocol/game/ServerboundInteractPacket.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
|
||||
});
|
||||
}
|
||||
}
|
||||
+ // 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,45 +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
|
||||
|
||||
Deprecated now and replaced with ProjectileHitEvent
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
@@ -0,0 +0,0 @@ public class CraftEventFactory {
|
||||
return CraftItemStack.asNMSCopy(bitem);
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Deprecated
|
||||
+ public static com.destroystokyo.paper.event.entity.ProjectileCollideEvent callProjectileCollideEvent(Entity entity, EntityHitResult position) {
|
||||
+ Projectile projectile = (Projectile) entity.getBukkitEntity();
|
||||
+ org.bukkit.entity.Entity collided = position.getEntity().getBukkitEntity();
|
||||
+ com.destroystokyo.paper.event.entity.ProjectileCollideEvent event = new com.destroystokyo.paper.event.entity.ProjectileCollideEvent(projectile, collided);
|
||||
+ Bukkit.getPluginManager().callEvent(event);
|
||||
+ return event;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
public static ProjectileLaunchEvent callProjectileLaunchEvent(Entity entity) {
|
||||
Projectile bukkitEntity = (Projectile) entity.getBukkitEntity();
|
||||
ProjectileLaunchEvent event = new ProjectileLaunchEvent(bukkitEntity);
|
||||
@@ -0,0 +0,0 @@ public class CraftEventFactory {
|
||||
if (position.getType() == HitResult.Type.ENTITY) {
|
||||
hitEntity = ((EntityHitResult) position).getEntity().getBukkitEntity();
|
||||
}
|
||||
+ // Paper start - legacy event
|
||||
+ boolean cancelled = false;
|
||||
+ if (hitEntity != null && position instanceof EntityHitResult entityHitResult) {
|
||||
+ cancelled = callProjectileCollideEvent(entity, entityHitResult).isCancelled();
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
ProjectileHitEvent event = new ProjectileHitEvent((Projectile) entity.getBukkitEntity(), hitEntity, hitBlock, hitFace);
|
||||
+ event.setCancelled(cancelled); // Paper - propagate legacy event cancellation to modern event
|
||||
entity.level.getCraftServer().getPluginManager().callEvent(event);
|
||||
return event;
|
||||
}
|
||||
@@ -1,111 +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
|
||||
|
||||
Co-authored-by: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/commands/CommandSourceStack.java b/src/main/java/net/minecraft/commands/CommandSourceStack.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/commands/CommandSourceStack.java
|
||||
+++ b/src/main/java/net/minecraft/commands/CommandSourceStack.java
|
||||
@@ -0,0 +0,0 @@ public class CommandSourceStack implements SharedSuggestionProvider {
|
||||
}
|
||||
|
||||
public void sendFailure(Component message) {
|
||||
+ // Paper start
|
||||
+ this.sendFailure(message, true);
|
||||
+ }
|
||||
+ public void sendFailure(Component message, boolean withStyle) {
|
||||
+ // Paper end
|
||||
if (this.source.acceptsFailure() && !this.silent) {
|
||||
- this.source.sendSystemMessage(Component.empty().append(message).withStyle(ChatFormatting.RED));
|
||||
+ this.source.sendSystemMessage(withStyle ? Component.empty().append(message).withStyle(ChatFormatting.RED) : message); // Paper
|
||||
}
|
||||
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/commands/Commands.java b/src/main/java/net/minecraft/commands/Commands.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/commands/Commands.java
|
||||
+++ b/src/main/java/net/minecraft/commands/Commands.java
|
||||
@@ -0,0 +0,0 @@ public class Commands {
|
||||
public static final int LEVEL_ADMINS = 3;
|
||||
public static final int LEVEL_OWNERS = 4;
|
||||
private final com.mojang.brigadier.CommandDispatcher<CommandSourceStack> dispatcher = new com.mojang.brigadier.CommandDispatcher();
|
||||
+ public final java.util.List<CommandNode<CommandSourceStack>> vanillaCommandNodes = new java.util.ArrayList<>(); // Paper
|
||||
|
||||
public Commands(Commands.CommandSelection environment, CommandBuildContext commandRegistryAccess) {
|
||||
this(); // CraftBukkit
|
||||
@@ -0,0 +0,0 @@ public class Commands {
|
||||
if (environment.includeIntegrated) {
|
||||
PublishCommand.register(this.dispatcher);
|
||||
}
|
||||
+ this.vanillaCommandNodes.addAll(this.dispatcher.getRoot().getChildren()); // Paper
|
||||
|
||||
// CraftBukkit start
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class Commands {
|
||||
b1 = 0;
|
||||
return b1;
|
||||
} catch (CommandSyntaxException commandsyntaxexception) {
|
||||
- commandlistenerwrapper.sendFailure(ComponentUtils.fromMessage(commandsyntaxexception.getRawMessage()));
|
||||
+ // Paper start
|
||||
+ final net.kyori.adventure.text.TextComponent.Builder builder = net.kyori.adventure.text.Component.text();
|
||||
+ if ((parseresults.getContext().getNodes().isEmpty() || !this.vanillaCommandNodes.contains(parseresults.getContext().getNodes().get(0).getNode()))) {
|
||||
+ if (!org.spigotmc.SpigotConfig.unknownCommandMessage.isEmpty()) {
|
||||
+ builder.append(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(org.spigotmc.SpigotConfig.unknownCommandMessage));
|
||||
+ }
|
||||
+ } else {
|
||||
+ // commandlistenerwrapper.sendFailure(ComponentUtils.fromMessage(commandsyntaxexception.getRawMessage()));
|
||||
+ builder.color(net.kyori.adventure.text.format.NamedTextColor.RED).append(io.papermc.paper.brigadier.PaperBrigadier.componentFromMessage(commandsyntaxexception.getRawMessage()));
|
||||
+ // Paper end
|
||||
if (commandsyntaxexception.getInput() != null && commandsyntaxexception.getCursor() >= 0) {
|
||||
int j = Math.min(commandsyntaxexception.getInput().length(), commandsyntaxexception.getCursor());
|
||||
MutableComponent ichatmutablecomponent = Component.empty().withStyle(ChatFormatting.GRAY).withStyle((chatmodifier) -> {
|
||||
@@ -0,0 +0,0 @@ public class Commands {
|
||||
}
|
||||
|
||||
ichatmutablecomponent.append((Component) Component.translatable("command.context.here").withStyle(ChatFormatting.RED, ChatFormatting.ITALIC));
|
||||
- commandlistenerwrapper.sendFailure(ichatmutablecomponent);
|
||||
+ // Paper start
|
||||
+ // commandlistenerwrapper.sendFailure(ichatmutablecomponent);
|
||||
+ builder
|
||||
+ .append(net.kyori.adventure.text.Component.newline())
|
||||
+ .append(io.papermc.paper.adventure.PaperAdventure.asAdventure(ichatmutablecomponent));
|
||||
+ }
|
||||
+ }
|
||||
+ org.bukkit.event.command.UnknownCommandEvent event = new org.bukkit.event.command.UnknownCommandEvent(commandlistenerwrapper.getBukkitSender(), s, org.spigotmc.SpigotConfig.unknownCommandMessage.isEmpty() ? null : builder.build());
|
||||
+ org.bukkit.Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
+ if (event.message() != null) {
|
||||
+ commandlistenerwrapper.sendFailure(io.papermc.paper.adventure.PaperAdventure.asVanilla(event.message()), false);
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
b1 = 0;
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -0,0 +0,0 @@ public final class CraftServer implements Server {
|
||||
|
||||
if (command instanceof VanillaCommandWrapper) {
|
||||
LiteralCommandNode<CommandSourceStack> node = (LiteralCommandNode<CommandSourceStack>) ((VanillaCommandWrapper) command).vanillaCommand;
|
||||
+ dispatcher.vanillaCommandNodes.add(node); // Paper
|
||||
if (!node.getLiteral().equals(label)) {
|
||||
LiteralCommandNode<CommandSourceStack> clone = new LiteralCommandNode(label, node.getCommand(), node.getRequirement(), node.getRedirect(), node.getRedirectModifier(), node.isFork());
|
||||
|
||||
@@ -0,0 +0,0 @@ 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, net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(org.spigotmc.SpigotConfig.unknownCommandMessage));
|
||||
+ Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
+ if (event.message() != null) {
|
||||
+ sender.sendMessage(event.message());
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
// Spigot end
|
||||
|
||||
@@ -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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -0,0 +0,0 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
||||
public final LevelStorageSource.LevelStorageAccess convertable;
|
||||
public final UUID uuid;
|
||||
|
||||
- public 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/Level.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
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,33 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Riley Park <rileysebastianpark@gmail.com>
|
||||
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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/FrostedIceBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/FrostedIceBlock.java
|
||||
@@ -0,0 +0,0 @@ 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();
|
||||
|
||||
@@ -0,0 +0,0 @@ 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: Joseph Hirschfeld <joe@ibj.io>
|
||||
Date: Thu, 3 Mar 2016 02:46:17 -0600
|
||||
Subject: [PATCH] Add configurable portal search radius
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
|
||||
double d0 = DimensionType.getTeleportationScale(this.level.dimensionType(), destination.dimensionType());
|
||||
BlockPos blockposition = worldborder.clampToBounds(this.getX() * d0, this.getY(), this.getZ() * d0);
|
||||
// CraftBukkit start
|
||||
- CraftPortalEvent event = this.callPortalEvent(this, destination, new PositionImpl(blockposition.getX(), blockposition.getY(), blockposition.getZ()), PlayerTeleportEvent.TeleportCause.NETHER_PORTAL, flag2 ? 16 : 128, 16);
|
||||
+ // Paper start
|
||||
+ int portalSearchRadius = destination.paperConfig().environment.portalSearchRadius;
|
||||
+ if (level.paperConfig().environment.portalSearchVanillaDimensionScaling && flag2) { // == THE_NETHER
|
||||
+ portalSearchRadius = (int) (portalSearchRadius / destination.dimensionType().coordinateScale());
|
||||
+ }
|
||||
+ // Paper end
|
||||
+ CraftPortalEvent event = this.callPortalEvent(this, destination, new PositionImpl(blockposition.getX(), blockposition.getY(), blockposition.getZ()), PlayerTeleportEvent.TeleportCause.NETHER_PORTAL, portalSearchRadius, destination.paperConfig().environment.portalCreateRadius); // Paper start - configurable portal radius
|
||||
if (event == null) {
|
||||
return null;
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/level/portal/PortalForcer.java b/src/main/java/net/minecraft/world/level/portal/PortalForcer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/portal/PortalForcer.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/portal/PortalForcer.java
|
||||
@@ -0,0 +0,0 @@ public class PortalForcer {
|
||||
|
||||
public Optional<BlockUtil.FoundRectangle> findPortalAround(BlockPos pos, boolean destIsNether, WorldBorder worldBorder) {
|
||||
// CraftBukkit start
|
||||
- return this.findPortalAround(pos, worldBorder, destIsNether ? 16 : 128); // Search Radius
|
||||
+ return this.findPortalAround(pos, worldBorder, destIsNether ? level.paperConfig().environment.portalCreateRadius : level.paperConfig().environment.portalSearchRadius); // Search Radius // Paper - search Radius
|
||||
}
|
||||
|
||||
public Optional<BlockUtil.FoundRectangle> findPortalAround(BlockPos blockposition, WorldBorder worldborder, int i) {
|
||||
@@ -1,22 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Riley Park <rileysebastianpark@gmail.com>
|
||||
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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -0,0 +0,0 @@ public final class CraftServer implements Server {
|
||||
commandMap.registerServerAliases();
|
||||
return true;
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean suggestPlayerNamesWhenNullTabCompletions() {
|
||||
+ return io.papermc.paper.configuration.GlobalConfiguration.get().commands.suggestPlayerNamesWhenNullTabCompletions;
|
||||
+ }
|
||||
// Paper end
|
||||
}
|
||||
@@ -1,225 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Joseph Hirschfeld <joe@ibj.io>
|
||||
Date: Thu, 3 Mar 2016 03:15:41 -0600
|
||||
Subject: [PATCH] Add exception reporting event
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/ServerSchedulerReportingWrapper.java b/src/main/java/com/destroystokyo/paper/ServerSchedulerReportingWrapper.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/ServerSchedulerReportingWrapper.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package com.destroystokyo.paper;
|
||||
+
|
||||
+import com.google.common.base.Preconditions;
|
||||
+import org.bukkit.craftbukkit.scheduler.CraftTask;
|
||||
+import com.destroystokyo.paper.event.server.ServerExceptionEvent;
|
||||
+import com.destroystokyo.paper.exception.ServerSchedulerException;
|
||||
+
|
||||
+/**
|
||||
+ * Reporting wrapper to catch exceptions not natively
|
||||
+ */
|
||||
+public class ServerSchedulerReportingWrapper implements Runnable {
|
||||
+
|
||||
+ private final CraftTask internalTask;
|
||||
+
|
||||
+ public ServerSchedulerReportingWrapper(CraftTask internalTask) {
|
||||
+ this.internalTask = Preconditions.checkNotNull(internalTask, "internalTask");
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void run() {
|
||||
+ try {
|
||||
+ internalTask.run();
|
||||
+ } catch (RuntimeException e) {
|
||||
+ internalTask.getOwner().getServer().getPluginManager().callEvent(
|
||||
+ new ServerExceptionEvent(new ServerSchedulerException(e, internalTask))
|
||||
+ );
|
||||
+ throw e;
|
||||
+ } catch (Throwable t) {
|
||||
+ internalTask.getOwner().getServer().getPluginManager().callEvent(
|
||||
+ new ServerExceptionEvent(new ServerSchedulerException(t, internalTask))
|
||||
+ ); //Do not rethrow, since it is not permitted with Runnable#run
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public CraftTask getInternalTask() {
|
||||
+ return internalTask;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/net/minecraft/server/players/OldUsersConverter.java b/src/main/java/net/minecraft/server/players/OldUsersConverter.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/OldUsersConverter.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/OldUsersConverter.java
|
||||
@@ -0,0 +0,0 @@
|
||||
package net.minecraft.server.players;
|
||||
|
||||
+import com.destroystokyo.paper.exception.ServerInternalException;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.io.Files;
|
||||
@@ -0,0 +0,0 @@ public class OldUsersConverter {
|
||||
root = NbtIo.readCompressed(new java.io.FileInputStream(file5));
|
||||
} catch (Exception exception) {
|
||||
exception.printStackTrace();
|
||||
+ ServerInternalException.reportInternalException(exception); // Paper
|
||||
}
|
||||
|
||||
if (root != null) {
|
||||
@@ -0,0 +0,0 @@ public class OldUsersConverter {
|
||||
NbtIo.writeCompressed(root, new java.io.FileOutputStream(file2));
|
||||
} catch (Exception exception) {
|
||||
exception.printStackTrace();
|
||||
+ ServerInternalException.reportInternalException(exception); // Paper
|
||||
}
|
||||
}
|
||||
// CraftBukkit end
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/ai/village/VillageSiege.java b/src/main/java/net/minecraft/world/entity/ai/village/VillageSiege.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ai/village/VillageSiege.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ai/village/VillageSiege.java
|
||||
@@ -0,0 +0,0 @@ public class VillageSiege implements CustomSpawner {
|
||||
entityzombie.finalizeSpawn(world, world.getCurrentDifficultyAt(entityzombie.blockPosition()), MobSpawnType.EVENT, (SpawnGroupData) null, (CompoundTag) null);
|
||||
} catch (Exception exception) {
|
||||
VillageSiege.LOGGER.warn("Failed to create zombie for village siege at {}", vec3d, exception);
|
||||
+ com.destroystokyo.paper.exception.ServerInternalException.reportInternalException(exception); // Paper
|
||||
return;
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/Level.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
||||
@@ -0,0 +0,0 @@
|
||||
package net.minecraft.world.level;
|
||||
|
||||
+import co.aikar.timings.Timing;
|
||||
+import co.aikar.timings.Timings;
|
||||
+import com.destroystokyo.paper.event.server.ServerExceptionEvent;
|
||||
+import com.destroystokyo.paper.exception.ServerInternalException;
|
||||
+import com.google.common.base.MoreObjects;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.mojang.serialization.Codec;
|
||||
import java.io.IOException;
|
||||
@@ -0,0 +0,0 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
// Paper start - Prevent tile entity and entity crashes
|
||||
final String msg = String.format("Entity threw exception at %s:%s,%s,%s", entity.level.getWorld().getName(), entity.getX(), entity.getY(), entity.getZ());
|
||||
MinecraftServer.LOGGER.error(msg, throwable);
|
||||
+ getCraftServer().getPluginManager().callEvent(new ServerExceptionEvent(new ServerInternalException(msg, throwable)));
|
||||
entity.discard();
|
||||
// Paper end
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java
|
||||
@@ -0,0 +0,0 @@ public final class NaturalSpawner {
|
||||
NaturalSpawner.LOGGER.warn("Can't spawn entity of type: {}", BuiltInRegistries.ENTITY_TYPE.getKey(type));
|
||||
} catch (Exception exception) {
|
||||
NaturalSpawner.LOGGER.warn("Failed to create mob", exception);
|
||||
+ com.destroystokyo.paper.exception.ServerInternalException.reportInternalException(exception); // Paper
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -0,0 +0,0 @@ public final class NaturalSpawner {
|
||||
entity = biomesettingsmobs_c.type.create(world.getLevel());
|
||||
} catch (Exception exception) {
|
||||
NaturalSpawner.LOGGER.warn("Failed to create mob", exception);
|
||||
+ com.destroystokyo.paper.exception.ServerInternalException.reportInternalException(exception); // Paper
|
||||
continue;
|
||||
}
|
||||
|
||||
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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
@@ -0,0 +0,0 @@
|
||||
package net.minecraft.world.level.chunk;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
+import com.destroystokyo.paper.exception.ServerInternalException;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.UnmodifiableIterator;
|
||||
import com.mojang.logging.LogUtils;
|
||||
@@ -0,0 +0,0 @@ public class LevelChunk extends ChunkAccess {
|
||||
|
||||
// CraftBukkit start
|
||||
} else {
|
||||
- System.out.println("Attempted to place a tile entity (" + blockEntity + ") at " + blockEntity.getBlockPos().getX() + "," + blockEntity.getBlockPos().getY() + "," + blockEntity.getBlockPos().getZ()
|
||||
- + " (" + this.getBlockState(blockposition) + ") where there was no entity tile!");
|
||||
- System.out.println("Chunk coordinates: " + (this.chunkPos.x * 16) + "," + (this.chunkPos.z * 16));
|
||||
- new Exception().printStackTrace();
|
||||
+ // Paper start
|
||||
+ ServerInternalException e = new ServerInternalException(
|
||||
+ "Attempted to place a tile entity (" + blockEntity + ") at " + blockEntity.getBlockPos().getX() + ","
|
||||
+ + blockEntity.getBlockPos().getY() + "," + blockEntity.getBlockPos().getZ()
|
||||
+ + " (" + getBlockState(blockposition) + ") where there was no entity tile!\n" +
|
||||
+ "Chunk coordinates: " + (this.chunkPos.x * 16) + "," + (this.chunkPos.z * 16) +
|
||||
+ "\nWorld: " + level.getLevel().dimension().location());
|
||||
+ e.printStackTrace();
|
||||
+ ServerInternalException.reportInternalException(e);
|
||||
+ // Paper end
|
||||
// CraftBukkit end
|
||||
}
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class LevelChunk extends ChunkAccess {
|
||||
// Paper start - Prevent tile entity and entity crashes
|
||||
final String msg = String.format("BlockEntity threw exception at %s:%s,%s,%s", LevelChunk.this.getLevel().getWorld().getName(), this.getPos().getX(), this.getPos().getY(), this.getPos().getZ());
|
||||
net.minecraft.server.MinecraftServer.LOGGER.error(msg, throwable);
|
||||
+ net.minecraft.world.level.chunk.LevelChunk.this.level.getCraftServer().getPluginManager().callEvent(new com.destroystokyo.paper.event.server.ServerExceptionEvent(new ServerInternalException(msg, throwable)));
|
||||
LevelChunk.this.removeBlockEntity(this.getPos());
|
||||
// Paper end
|
||||
// Spigot start
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java
|
||||
@@ -0,0 +0,0 @@ public class RegionFile implements AutoCloseable {
|
||||
return true;
|
||||
}
|
||||
} catch (IOException ioexception) {
|
||||
+ com.destroystokyo.paper.exception.ServerInternalException.reportInternalException(ioexception); // Paper
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class RegionFile implements AutoCloseable {
|
||||
((java.nio.Buffer) buf).position(5); // CraftBukkit - decompile error
|
||||
filechannel.write(buf);
|
||||
} catch (Throwable throwable) {
|
||||
+ com.destroystokyo.paper.exception.ServerInternalException.reportInternalException(throwable); // Paper
|
||||
if (filechannel != null) {
|
||||
try {
|
||||
filechannel.close();
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
|
||||
@@ -0,0 +0,0 @@ import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.IntUnaryOperator;
|
||||
import java.util.logging.Level;
|
||||
+import com.destroystokyo.paper.ServerSchedulerReportingWrapper;
|
||||
+import com.destroystokyo.paper.event.server.ServerExceptionEvent;
|
||||
+import com.destroystokyo.paper.exception.ServerSchedulerException;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.plugin.IllegalPluginAccessException;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
@@ -0,0 +0,0 @@ public class CraftScheduler implements BukkitScheduler {
|
||||
msg,
|
||||
throwable);
|
||||
}
|
||||
+ org.bukkit.Bukkit.getServer().getPluginManager().callEvent(
|
||||
+ new ServerExceptionEvent(new ServerSchedulerException(msg, throwable, task)));
|
||||
// Paper end
|
||||
} finally {
|
||||
this.currentTask = null;
|
||||
@@ -0,0 +0,0 @@ public class CraftScheduler implements BukkitScheduler {
|
||||
this.parsePending();
|
||||
} else {
|
||||
this.debugTail = this.debugTail.setNext(new CraftAsyncDebugger(currentTick + CraftScheduler.RECENT_TICKS, task.getOwner(), task.getTaskClass()));
|
||||
- this.executor.execute(task);
|
||||
+ 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)
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Riley Park <rileysebastianpark@gmail.com>
|
||||
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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java
|
||||
@@ -0,0 +0,0 @@ public class ServerHandshakePacketListenerImpl implements ServerHandshakePacketL
|
||||
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,46 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: mrapple <tony@oc.tc>
|
||||
Date: Sun, 25 Nov 2012 13:43:39 -0600
|
||||
Subject: [PATCH] Add methods for working with arrows stuck in living entities
|
||||
|
||||
Upstream added methods for this, original methods are now
|
||||
deprecated
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
@@ -0,0 +0,0 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
|
||||
}
|
||||
|
||||
@Override
|
||||
- public void setArrowsInBody(int count) {
|
||||
+ public void setArrowsInBody(final int count, final boolean fireEvent) { // Paper
|
||||
Preconditions.checkArgument(count >= 0, "New arrow amount must be >= 0");
|
||||
+ if (!fireEvent) { // Paper
|
||||
this.getHandle().getEntityData().set(net.minecraft.world.entity.LivingEntity.DATA_ARROW_COUNT_ID, count);
|
||||
+ // Paper start
|
||||
+ } else {
|
||||
+ this.getHandle().setArrowCount(count);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -0,0 +0,0 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
|
||||
this.getHandle().persistentInvisibility = invisible;
|
||||
this.getHandle().setSharedFlag(5, invisible);
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public int getArrowsStuck() {
|
||||
+ return this.getHandle().getArrowCount();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setArrowsStuck(final int arrows) {
|
||||
+ this.getHandle().setArrowCount(arrows);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <1254957+zachbr@users.noreply.github.com>
|
||||
Date: Tue, 16 May 2017 21:29:08 -0500
|
||||
Subject: [PATCH] Add option to make parrots stay on shoulders despite movement
|
||||
|
||||
Makes parrots not fall off whenever the player changes height, or touches water, or gets hit by a passing leaf.
|
||||
Instead, switches the behavior so that players have to sneak to make the birds leave.
|
||||
|
||||
I suspect Mojang may switch to this behavior before full release.
|
||||
|
||||
To be converted into a Paper-API event at some point in the future?
|
||||
|
||||
== AT ==
|
||||
public net.minecraft.world.entity.player.Player removeEntitiesOnShoulder()V
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
|
||||
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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Player extends LivingEntity {
|
||||
this.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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/Main.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/Main.java
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/GameProfileCache.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/GameProfileCache.java
|
||||
@@ -0,0 +0,0 @@ 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();
|
||||
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/OldUsersConverter.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/OldUsersConverter.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -0,0 +0,0 @@ public final class CraftServer implements Server {
|
||||
// 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ExperienceOrb.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ExperienceOrb.java
|
||||
@@ -0,0 +0,0 @@ public class ExperienceOrb extends Entity {
|
||||
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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
@@ -0,0 +0,0 @@ public class CraftEventFactory {
|
||||
return event;
|
||||
}
|
||||
|
||||
+ // 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,88 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Joseph Hirschfeld <joe@ibj.io>
|
||||
Date: Thu, 3 Mar 2016 02:48:12 -0600
|
||||
Subject: [PATCH] Add velocity warnings
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -0,0 +0,0 @@ public final class CraftServer implements Server {
|
||||
public boolean ignoreVanillaPermissions = false;
|
||||
private final List<CraftPlayer> playerView;
|
||||
public int reloadCount;
|
||||
+ public static Exception excessiveVelEx; // Paper - Velocity warnings
|
||||
|
||||
static {
|
||||
ConfigurationSerialization.registerClass(CraftOfflinePlayer.class);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
|
||||
public void setVelocity(Vector velocity) {
|
||||
Preconditions.checkArgument(velocity != null, "velocity");
|
||||
velocity.checkFinite();
|
||||
+ // Paper start - Warn server owners when plugins try to set super high velocities
|
||||
+ if (!(this instanceof org.bukkit.entity.Projectile || this instanceof org.bukkit.entity.Minecart) && isUnsafeVelocity(velocity)) {
|
||||
+ CraftServer.excessiveVelEx = new Exception("Excessive velocity set detected: tried to set velocity of entity " + entity.getScoreboardName() + " id #" + getEntityId() + " to (" + velocity.getX() + "," + velocity.getY() + "," + velocity.getZ() + ").");
|
||||
+ }
|
||||
+ // Paper end
|
||||
this.entity.setDeltaMovement(CraftVector.toNMS(velocity));
|
||||
entity.hurtMarked = true;
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Checks if the given velocity is not necessarily safe in all situations.
|
||||
+ * This function returning true does not mean the velocity is dangerous or to be avoided, only that it may be
|
||||
+ * a detriment to performance on the server.
|
||||
+ *
|
||||
+ * It is not to be used as a hard rule of any sort.
|
||||
+ * Paper only uses it to warn server owners in watchdog crashes.
|
||||
+ *
|
||||
+ * @param vel incoming velocity to check
|
||||
+ * @return if the velocity has the potential to be a performance detriment
|
||||
+ */
|
||||
+ private static boolean isUnsafeVelocity(Vector vel) {
|
||||
+ final double x = vel.getX();
|
||||
+ final double y = vel.getY();
|
||||
+ final double z = vel.getZ();
|
||||
+
|
||||
+ if (x > 4 || x < -4 || y > 4 || y < -4 || z > 4 || z < -4) {
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ return false;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public double getHeight() {
|
||||
return this.getHandle().getBbHeight();
|
||||
diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/spigotmc/WatchdogThread.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/spigotmc/WatchdogThread.java
|
||||
+++ b/src/main/java/org/spigotmc/WatchdogThread.java
|
||||
@@ -0,0 +0,0 @@ public final class WatchdogThread extends io.papermc.paper.util.TickThread // Pa
|
||||
log.log( Level.SEVERE, "During the run of the server, a physics stackoverflow was supressed" );
|
||||
log.log( Level.SEVERE, "near " + net.minecraft.world.level.Level.lastPhysicsProblem );
|
||||
}
|
||||
- //
|
||||
+ // Paper start - Warn in watchdog if an excessive velocity was ever set
|
||||
+ if ( org.bukkit.craftbukkit.CraftServer.excessiveVelEx != null )
|
||||
+ {
|
||||
+ log.log( Level.SEVERE, "------------------------------" );
|
||||
+ log.log( Level.SEVERE, "During the run of the server, a plugin set an excessive velocity on an entity" );
|
||||
+ log.log( Level.SEVERE, "This may be the cause of the issue, or it may be entirely unrelated" );
|
||||
+ log.log( Level.SEVERE, org.bukkit.craftbukkit.CraftServer.excessiveVelEx.getMessage());
|
||||
+ for ( StackTraceElement stack : org.bukkit.craftbukkit.CraftServer.excessiveVelEx.getStackTrace() )
|
||||
+ {
|
||||
+ log.log( Level.SEVERE, "\t\t" + stack );
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
log.log( Level.SEVERE, "------------------------------" );
|
||||
log.log( Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Paper!):" ); // Paper
|
||||
io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.dumpAllChunkLoadInfo(isLongTimeout); // Paper // Paper - rewrite chunk system
|
||||
@@ -1,32 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: vemacs <d@nkmem.es>
|
||||
Date: Thu, 3 Mar 2016 01:19:22 -0600
|
||||
Subject: [PATCH] All chunks are slime spawn chunks toggle
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/Slime.java b/src/main/java/net/minecraft/world/entity/monster/Slime.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Slime.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Slime.java
|
||||
@@ -0,0 +0,0 @@ public class Slime extends Mob implements Enemy {
|
||||
}
|
||||
|
||||
ChunkPos chunkcoordintpair = new ChunkPos(pos);
|
||||
- boolean flag = WorldgenRandom.seedSlimeChunk(chunkcoordintpair.x, chunkcoordintpair.z, ((WorldGenLevel) world).getSeed(), world.getMinecraftWorld().spigotConfig.slimeSeed).nextInt(10) == 0; // Spigot
|
||||
+ boolean flag = world.getMinecraftWorld().paperConfig().entities.spawning.allChunksAreSlimeChunks || WorldgenRandom.seedSlimeChunk(chunkcoordintpair.x, chunkcoordintpair.z, ((WorldGenLevel) world).getSeed(), world.getMinecraftWorld().spigotConfig.slimeSeed).nextInt(10) == 0; // Spigot // Paper
|
||||
|
||||
if (random.nextInt(10) == 0 && flag && pos.getY() < 40) {
|
||||
return checkMobSpawnRules(type, world, spawnReason, pos, random);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
|
||||
@@ -0,0 +0,0 @@ public class CraftChunk implements Chunk {
|
||||
@Override
|
||||
public boolean isSlimeChunk() {
|
||||
// 987234911L is deterimined in EntitySlime when seeing if a slime can spawn in a chunk
|
||||
- return WorldgenRandom.seedSlimeChunk(this.getX(), this.getZ(), this.getWorld().getSeed(), worldServer.spigotConfig.slimeSeed).nextInt(10) == 0;
|
||||
+ return this.worldServer.paperConfig().entities.spawning.allChunksAreSlimeChunks || WorldgenRandom.seedSlimeChunk(this.getX(), this.getZ(), this.getWorld().getSeed(), worldServer.spigotConfig.slimeSeed).nextInt(10) == 0; // Paper
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -0,0 +0,0 @@ public final class CraftServer implements Server {
|
||||
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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -0,0 +0,0 @@ public final class CraftServer implements Server {
|
||||
}
|
||||
return 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,18 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <1254957+zachbr@users.noreply.github.com>
|
||||
Date: Wed, 2 Mar 2016 00:32:25 -0600
|
||||
Subject: [PATCH] Always tick falling blocks
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/spigotmc/ActivationRange.java
|
||||
+++ b/src/main/java/org/spigotmc/ActivationRange.java
|
||||
@@ -0,0 +0,0 @@ public class ActivationRange
|
||||
|| entity instanceof AbstractHurtingProjectile
|
||||
|| entity instanceof LightningBolt
|
||||
|| entity instanceof PrimedTnt
|
||||
+ || entity instanceof net.minecraft.world.entity.item.FallingBlockEntity // Paper - Always tick falling blocks
|
||||
|| entity instanceof EndCrystal
|
||||
|| entity instanceof FireworkRocketEntity
|
||||
|| entity instanceof ThrownTrident )
|
||||
@@ -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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
} 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
|
||||
io.papermc.paper.chunk.system.io.RegionFileIOThread.close(true); // Paper // Paper - rewrite chunk system
|
||||
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
@@ -0,0 +0,0 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
|
||||
}
|
||||
|
||||
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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/GameProfileCache.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/GameProfileCache.java
|
||||
@@ -0,0 +0,0 @@ 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() {
|
||||
@@ -0,0 +0,0 @@ public class GameProfileCache {
|
||||
}
|
||||
|
||||
if (flag && !org.spigotmc.SpigotConfig.saveUserCacheOnStopOnly) { // Spigot - skip saving if disabled
|
||||
- this.save();
|
||||
+ this.save(true); // Paper
|
||||
}
|
||||
|
||||
return optional;
|
||||
@@ -0,0 +0,0 @@ public class GameProfileCache {
|
||||
return arraylist;
|
||||
}
|
||||
|
||||
- public void save() {
|
||||
+ public void save(boolean asyncSave) { // Paper
|
||||
JsonArray jsonarray = new JsonArray();
|
||||
DateFormat dateformat = GameProfileCache.createDateFormat();
|
||||
|
||||
@@ -0,0 +0,0 @@ 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);
|
||||
@@ -0,0 +0,0 @@ public class GameProfileCache {
|
||||
} catch (IOException ioexception) {
|
||||
;
|
||||
}
|
||||
+ // Paper start
|
||||
+ };
|
||||
+ if (asyncSave) {
|
||||
+ io.papermc.paper.util.MCUtil.scheduleAsyncTask(save);
|
||||
+ } else {
|
||||
+ save.run();
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
}
|
||||
|
||||
@@ -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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerConnectionListener.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerConnectionListener.java
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
@@ -0,0 +0,0 @@ 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));
|
||||
}
|
||||
@@ -0,0 +0,0 @@ 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,770 +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
|
||||
|
||||
== AT ==
|
||||
public org.bukkit.craftbukkit.profile.CraftProfileProperty
|
||||
public org.bukkit.craftbukkit.profile.CraftPlayerTextures
|
||||
public org.bukkit.craftbukkit.profile.CraftPlayerTextures copyFrom(Lorg/bukkit/profile/PlayerTextures;)V
|
||||
public org.bukkit.craftbukkit.profile.CraftPlayerTextures rebuildPropertyIfDirty()V
|
||||
public org.bukkit.craftbukkit.profile.CraftPlayerProfile toString(Lcom/mojang/authlib/properties/PropertyMap;)Ljava/lang/String;
|
||||
# needed to maintain visibility with overriden methods
|
||||
public org.bukkit.craftbukkit.profile.CraftPlayerProfile getProperty(Ljava/lang/String;)Lcom/mojang/authlib/properties/Property;
|
||||
public org.bukkit.craftbukkit.profile.CraftPlayerProfile setProperty(Ljava/lang/String;Lcom/mojang/authlib/properties/Property;)V
|
||||
|
||||
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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/profile/CraftPlayerProfile.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/profile/PaperAuthenticationService.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/profile/PaperGameProfileRepository.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/profile/PaperMinecraftSessionService.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/profile/PaperUserAuthentication.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/profile/SharedPlayerProfile.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+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/io/papermc/paper/util/MCUtil.java b/src/main/java/io/papermc/paper/util/MCUtil.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/io/papermc/paper/util/MCUtil.java
|
||||
+++ b/src/main/java/io/papermc/paper/util/MCUtil.java
|
||||
@@ -0,0 +0,0 @@
|
||||
package io.papermc.paper.util;
|
||||
|
||||
+import com.destroystokyo.paper.profile.CraftPlayerProfile;
|
||||
+import com.destroystokyo.paper.profile.PlayerProfile;
|
||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||
import io.papermc.paper.math.Position;
|
||||
import com.google.gson.JsonArray;
|
||||
@@ -0,0 +0,0 @@ import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||
import net.minecraft.world.level.chunk.ChunkStatus;
|
||||
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;
|
||||
@@ -0,0 +0,0 @@ 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 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
|
||||
- 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/GameProfileCache.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/GameProfileCache.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
@@ -0,0 +0,0 @@ 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();
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/profile/CraftPlayerProfile.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/profile/CraftPlayerProfile.java
|
||||
@@ -0,0 +0,0 @@ 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) {
|
||||
@@ -0,0 +0,0 @@ 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() {
|
||||
@@ -0,0 +0,0 @@ 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());
|
||||
@@ -0,0 +0,0 @@ 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);
|
||||
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/profile/CraftPlayerTextures.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/profile/CraftPlayerTextures.java
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
@@ -0,0 +0,0 @@ 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,22 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Riley Park <rileysebastianpark@gmail.com>
|
||||
Date: Thu, 3 Mar 2016 02:18:39 -0600
|
||||
Subject: [PATCH] Be a bit more informative in maxHealth exception
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
@@ -0,0 +0,0 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
|
||||
public void setHealth(double health) {
|
||||
health = (float) health;
|
||||
if ((health < 0) || (health > this.getMaxHealth())) {
|
||||
- throw new IllegalArgumentException("Health must be between 0 and " + this.getMaxHealth() + "(" + health + ")");
|
||||
+ // Paper - Be more informative
|
||||
+ throw new IllegalArgumentException("Health must be between 0 and " + getMaxHealth() + ", but was " + health
|
||||
+ + ". (attribute base value: " + this.getHandle().getAttribute(Attributes.MAX_HEALTH).getBaseValue()
|
||||
+ + (this instanceof CraftPlayer ? ", player: " + this.getName() + ')' : ')'));
|
||||
}
|
||||
|
||||
// during world generation, we don't want to run logic for dropping items and xp
|
||||
@@ -1,23 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <1254957+zachbr@users.noreply.github.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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
@@ -0,0 +0,0 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener,
|
||||
|
||||
@Override
|
||||
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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/border/WorldBorder.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/border/WorldBorder.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java
|
||||
@@ -0,0 +0,0 @@ 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,63 +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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
@@ -0,0 +0,0 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener,
|
||||
|
||||
}
|
||||
|
||||
+ private static final java.util.concurrent.ExecutorService authenticatorPool = java.util.concurrent.Executors.newCachedThreadPool(new com.google.common.util.concurrent.ThreadFactoryBuilder().setNameFormat("User Authenticator #%d").setUncaughtExceptionHandler(new DefaultUncaughtExceptionHandler(LOGGER)).build()); // Paper - Cache authenticator threads
|
||||
+
|
||||
// Spigot start
|
||||
public void initUUID()
|
||||
{
|
||||
@@ -0,0 +0,0 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener,
|
||||
this.connection.send(new ClientboundHelloPacket("", this.server.getKeyPair().getPublic().getEncoded(), this.challenge));
|
||||
} else {
|
||||
// Spigot start
|
||||
- new Thread("User Authenticator #" + ServerLoginPacketListenerImpl.UNIQUE_THREAD_ID.incrementAndGet()) {
|
||||
-
|
||||
+ // Paper start - Cache authenticator threads
|
||||
+ authenticatorPool.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
@@ -0,0 +0,0 @@ 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
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
|
||||
public 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity {
|
||||
}
|
||||
}
|
||||
|
||||
- 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,19 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <1254957+zachbr@users.noreply.github.com>
|
||||
Date: Wed, 2 Mar 2016 00:03:55 -0600
|
||||
Subject: [PATCH] Check online mode before converting and renaming player data
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/storage/PlayerDataStorage.java b/src/main/java/net/minecraft/world/level/storage/PlayerDataStorage.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/storage/PlayerDataStorage.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/storage/PlayerDataStorage.java
|
||||
@@ -0,0 +0,0 @@ public class PlayerDataStorage {
|
||||
File file = new File(this.playerDir, player.getStringUUID() + ".dat");
|
||||
// Spigot Start
|
||||
boolean usingWrongFile = false;
|
||||
- if ( !file.exists() )
|
||||
+ if ( org.bukkit.Bukkit.getOnlineMode() && !file.exists() ) // Paper - Check online mode first
|
||||
{
|
||||
file = new File( this.playerDir, java.util.UUID.nameUUIDFromBytes( ( "OfflinePlayer:" + player.getScoreboardName() ).getBytes( "UTF-8" ) ).toString() + ".dat");
|
||||
if ( file.exists() )
|
||||
@@ -1,51 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 4 Mar 2013 23:46:10 -0500
|
||||
Subject: [PATCH] Chunk Save Reattempt
|
||||
|
||||
We commonly have "Stream Closed" errors on chunk saving, so this code should re-try to save the chunk in the event of failure and hopefully prevent rollbacks.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java
|
||||
@@ -0,0 +0,0 @@ public class RegionFile implements AutoCloseable {
|
||||
return true;
|
||||
}
|
||||
} catch (IOException ioexception) {
|
||||
- com.destroystokyo.paper.exception.ServerInternalException.reportInternalException(ioexception); // Paper
|
||||
+ com.destroystokyo.paper.util.SneakyThrow.sneaky(ioexception); // Paper - we want the upper try/catch to retry this
|
||||
return false;
|
||||
}
|
||||
}
|
||||
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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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
|
||||
@@ -0,0 +0,0 @@ public class RegionFileStorage implements AutoCloseable {
|
||||
}
|
||||
// Paper end - rewrite chunk system
|
||||
try { // Paper
|
||||
+ int attempts = 0; Exception laste = null; while (attempts++ < 5) { try { // Paper
|
||||
|
||||
if (nbt == null) {
|
||||
regionfile.clear(pos);
|
||||
@@ -0,0 +0,0 @@ public class RegionFileStorage implements AutoCloseable {
|
||||
dataoutputstream.close();
|
||||
}
|
||||
}
|
||||
+ // Paper start
|
||||
+ return;
|
||||
+ } catch (Exception ex) {
|
||||
+ laste = ex;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
+ if (laste != null) {
|
||||
+ com.destroystokyo.paper.exception.ServerInternalException.reportInternalException(laste);
|
||||
+ net.minecraft.server.MinecraftServer.LOGGER.error("Failed to save chunk " + pos, laste);
|
||||
+ }
|
||||
+ // Paper end
|
||||
} finally { // Paper start
|
||||
regionfile.fileLock.unlock();
|
||||
} // Paper end
|
||||
@@ -1,93 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jedediah Smith <jedediah@silencegreys.com>
|
||||
Date: Sat, 4 Apr 2015 23:17:52 -0400
|
||||
Subject: [PATCH] Complete resource pack API
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
|
||||
ServerGamePacketListenerImpl.LOGGER.info("Disconnecting {} due to resource pack rejection", this.player.getName());
|
||||
this.disconnect(Component.translatable("multiplayer.requiredTexturePrompt.disconnect"));
|
||||
}
|
||||
- this.cserver.getPluginManager().callEvent(new PlayerResourcePackStatusEvent(this.getCraftPlayer(), PlayerResourcePackStatusEvent.Status.values()[packet.action.ordinal()])); // CraftBukkit
|
||||
-
|
||||
+ // Paper start
|
||||
+ PlayerResourcePackStatusEvent.Status packStatus = PlayerResourcePackStatusEvent.Status.values()[packet.action.ordinal()];
|
||||
+ player.getBukkitEntity().setResourcePackStatus(packStatus);
|
||||
+ this.cserver.getPluginManager().callEvent(new PlayerResourcePackStatusEvent(this.getCraftPlayer(), packStatus)); // CraftBukkit
|
||||
+ // 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
@@ -0,0 +0,0 @@ import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.messaging.StandardMessenger;
|
||||
import org.bukkit.profile.PlayerProfile;
|
||||
import org.bukkit.scoreboard.Scoreboard;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import net.md_5.bungee.api.chat.BaseComponent; // Spigot
|
||||
|
||||
@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
private double healthScale = 20;
|
||||
private CraftWorldBorder clientWorldBorder = null;
|
||||
private BorderChangeListener clientWorldBorderListener = this.createWorldBorderListener();
|
||||
+ // Paper start
|
||||
+ private org.bukkit.event.player.PlayerResourcePackStatusEvent.Status resourcePackStatus;
|
||||
+ private String resourcePackHash;
|
||||
+ // Paper end
|
||||
|
||||
public CraftPlayer(CraftServer server, ServerPlayer entity) {
|
||||
super(server, entity);
|
||||
@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
public boolean getAffectsSpawning() {
|
||||
return this.getHandle().affectsSpawning;
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public void setResourcePack(@NotNull String url, @NotNull String hash) {
|
||||
+ this.setResourcePack(url, hash, false, null);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setResourcePack(@NotNull String url, @NotNull String hash, boolean required) {
|
||||
+ this.setResourcePack(url, hash, required, null);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setResourcePack(@NotNull String url, @NotNull String hash, boolean required, net.kyori.adventure.text.Component resourcePackPrompt) {
|
||||
+ Validate.notNull(url, "Resource pack URL cannot be null");
|
||||
+ Validate.notNull(hash, "Hash cannot be null");
|
||||
+ net.minecraft.network.chat.Component promptComponent = resourcePackPrompt != null ?
|
||||
+ io.papermc.paper.adventure.PaperAdventure.asVanilla(resourcePackPrompt) :
|
||||
+ null;
|
||||
+ this.getHandle().sendTexturePack(url, hash, required, promptComponent);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public org.bukkit.event.player.PlayerResourcePackStatusEvent.Status getResourcePackStatus() {
|
||||
+ return this.resourcePackStatus;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public String getResourcePackHash() {
|
||||
+ return this.resourcePackHash;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean hasResourcePack() {
|
||||
+ return this.resourcePackStatus == org.bukkit.event.player.PlayerResourcePackStatusEvent.Status.SUCCESSFULLY_LOADED;
|
||||
+ }
|
||||
+
|
||||
+ public void setResourcePackStatus(org.bukkit.event.player.PlayerResourcePackStatusEvent.Status status) {
|
||||
+ this.resourcePackStatus = status;
|
||||
+ }
|
||||
// Paper end
|
||||
|
||||
@Override
|
||||
@@ -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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/npc/VillagerTrades.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/npc/VillagerTrades.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
@@ -0,0 +0,0 @@ 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 GameEventListenerRegistry getListenerRegistry(int ySectionCoord) {
|
||||
Level world = this.level;
|
||||
@@ -1,23 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Thu, 3 Mar 2016 01:13:45 -0600
|
||||
Subject: [PATCH] Configurable Disabling Cat Chest Detection
|
||||
|
||||
Offers a gameplay feature to stop cats from blocking chests
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/ChestBlock.java b/src/main/java/net/minecraft/world/level/block/ChestBlock.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/ChestBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/ChestBlock.java
|
||||
@@ -0,0 +0,0 @@ public class ChestBlock extends AbstractChestBlock<ChestBlockEntity> implements
|
||||
}
|
||||
|
||||
private static boolean isCatSittingOnChest(LevelAccessor world, BlockPos pos) {
|
||||
+ // Paper start - Option to disable chest cat detection
|
||||
+ if (world.getMinecraftWorld().paperConfig().entities.behavior.disableChestCatDetection) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ // Paper end
|
||||
List<Cat> list = world.getEntitiesOfClass(Cat.class, new AABB((double) pos.getX(), (double) (pos.getY() + 1), (double) pos.getZ(), (double) (pos.getX() + 1), (double) (pos.getY() + 2), (double) (pos.getZ() + 1)));
|
||||
|
||||
if (!list.isEmpty()) {
|
||||
@@ -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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/SpreadingSnowyDirtBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/SpreadingSnowyDirtBlock.java
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
|
||||
@@ -0,0 +0,0 @@ public abstract class AbstractArrow extends Projectile {
|
||||
|
||||
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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/network/protocol/game/ClientboundSetPlayerTeamPacket.java
|
||||
+++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundSetPlayerTeamPacket.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
this.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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
|
||||
@@ -0,0 +0,0 @@ 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, LayeredRegistryAccess<RegistryLayer> registryManager, PlayerDataStorage saveHandler, int maxPlayers) {
|
||||
this.cserver = server.server = new CraftServer((DedicatedServer) server, this);
|
||||
@@ -0,0 +0,0 @@ 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());
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ 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();
|
||||
@@ -0,0 +0,0 @@ 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,47 +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.
|
||||
|
||||
== AT ==
|
||||
public net.minecraft.server.dedicated.Settings getStringRaw(Ljava/lang/String;)Ljava/lang/String;
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java
|
||||
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServerProperties.java
|
||||
@@ -0,0 +0,0 @@ public class DedicatedServerProperties extends Settings<DedicatedServerPropertie
|
||||
private final DedicatedServerProperties.WorldDimensionData worldDimensionData;
|
||||
public final WorldOptions worldOptions;
|
||||
|
||||
+ public final String rconIp; // Paper - Add rcon ip
|
||||
+
|
||||
// CraftBukkit start
|
||||
public DedicatedServerProperties(Properties properties, OptionSet optionset) {
|
||||
super(properties, optionset);
|
||||
@@ -0,0 +0,0 @@ public class DedicatedServerProperties extends Settings<DedicatedServerPropertie
|
||||
}, 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", ""));
|
||||
this.initialDataPackConfiguration = DedicatedServerProperties.getDatapackConfig(this.get("initial-enabled-packs", String.join(",", WorldDataConfiguration.DEFAULT.dataPacks().getEnabled())), this.get("initial-disabled-packs", String.join(",", WorldDataConfiguration.DEFAULT.dataPacks().getDisabled())));
|
||||
+ // 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/rcon/thread/RconThread.java
|
||||
+++ b/src/main/java/net/minecraft/server/rcon/thread/RconThread.java
|
||||
@@ -0,0 +0,0 @@ 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,32 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Sudzzy <originmc@outlook.com>
|
||||
Date: Wed, 2 Mar 2016 23:34:44 -0600
|
||||
Subject: [PATCH] Configurable container update tick rate
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
|
||||
private int containerCounter;
|
||||
public int latency;
|
||||
public boolean wonGame;
|
||||
+ private int containerUpdateDelay; // Paper
|
||||
|
||||
// CraftBukkit start
|
||||
public String displayName;
|
||||
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
|
||||
--this.invulnerableTime;
|
||||
}
|
||||
|
||||
- this.containerMenu.broadcastChanges();
|
||||
+ // Paper start - Configurable container update tick rate
|
||||
+ if (--containerUpdateDelay <= 0) {
|
||||
+ this.containerMenu.broadcastChanges();
|
||||
+ containerUpdateDelay = level.paperConfig().tickRates.containerUpdate;
|
||||
+ }
|
||||
+ // Paper end
|
||||
if (!this.level.isClientSide && !this.containerMenu.stillValid(this)) {
|
||||
this.closeContainer();
|
||||
this.containerMenu = this.inventoryMenu;
|
||||
@@ -1,18 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: DoctorDark <doctordark11@gmail.com>
|
||||
Date: Wed, 16 Mar 2016 02:21:39 -0500
|
||||
Subject: [PATCH] Configurable end credits
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
|
||||
this.unRide();
|
||||
this.getLevel().removePlayerImmediately(this, Entity.RemovalReason.CHANGED_DIMENSION);
|
||||
if (!this.wonGame) {
|
||||
+ if (level.paperConfig().misc.disableEndCredits) this.seenCredits = true; // Paper - Toggle to always disable end credits
|
||||
this.wonGame = true;
|
||||
this.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.WIN_GAME, this.seenCredits ? 0.0F : 1.0F));
|
||||
this.seenCredits = true;
|
||||
@@ -1,28 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Riley Park <rileysebastianpark@gmail.com>
|
||||
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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
|
||||
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 {
|
||||
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
|
||||
if (this.clientVehicleIsFloating && this.player.getRootVehicle().getControllingPassenger() == this.player) {
|
||||
if (++this.aboveGroundVehicleTickCount > 80) {
|
||||
ServerGamePacketListenerImpl.LOGGER.warn("{} was kicked for floating a vehicle too long!", this.player.getName().getString());
|
||||
- this.disconnect(Component.translatable("multiplayer.disconnect.flying"));
|
||||
+ this.disconnect(io.papermc.paper.configuration.GlobalConfiguration.get().messages.kick.flyingVehicle); // Paper - use configurable kick message
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
@@ -1,30 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Sudzzy <originmc@outlook.com>
|
||||
Date: Thu, 3 Mar 2016 02:50:31 -0600
|
||||
Subject: [PATCH] Configurable inter-world teleportation safety
|
||||
|
||||
People are able to abuse the way Bukkit handles teleportation across worlds since it provides a built in teleportation
|
||||
safety check.
|
||||
|
||||
To abuse the safety check, players are required to get into a location deemed unsafe by Bukkit e.g. be within a chest
|
||||
or door block. While they are in this block, they accept a teleport request from a player within a different world. Once
|
||||
the player teleports, Minecraft will recursively search upwards for a safe location, this could eventually land within a
|
||||
player's skybase.
|
||||
|
||||
Example setup to perform the glitch: http://puu.sh/ng3PC/cf072dcbdb.png
|
||||
The wanted destination was on top of the emerald block however the player ended on top of the diamond block.
|
||||
This only is the case if the player is teleporting between worlds.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
if (fromWorld == toWorld) {
|
||||
entity.connection.teleport(to);
|
||||
} else {
|
||||
- server.getHandle().respawn(entity, toWorld, true, to, true);
|
||||
+ server.getHandle().respawn(entity, toWorld, true, to, !toWorld.paperConfig().environment.disableTeleportationSuffocationCheck); // Paper
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Sudzzy <originmc@outlook.com>
|
||||
Date: Wed, 2 Mar 2016 15:03:53 -0600
|
||||
Subject: [PATCH] Configurable mob spawner tick rate
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/BaseSpawner.java b/src/main/java/net/minecraft/world/level/BaseSpawner.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/BaseSpawner.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/BaseSpawner.java
|
||||
@@ -0,0 +0,0 @@ public abstract class BaseSpawner {
|
||||
public int maxNearbyEntities = 6;
|
||||
public int requiredPlayerRange = 16;
|
||||
public int spawnRange = 4;
|
||||
+ private int tickDelay = 0; // Paper
|
||||
|
||||
public BaseSpawner() {}
|
||||
|
||||
@@ -0,0 +0,0 @@ public abstract class BaseSpawner {
|
||||
}
|
||||
|
||||
public void serverTick(ServerLevel world, BlockPos pos) {
|
||||
+ // Paper start - Configurable mob spawner tick rate
|
||||
+ if (spawnDelay > 0 && --tickDelay > 0) return;
|
||||
+ tickDelay = world.paperConfig().tickRates.mobSpawner;
|
||||
+ if (tickDelay == -1) { return; } // If disabled
|
||||
+ // Paper end
|
||||
if (this.isNearPlayer(world, pos)) {
|
||||
- if (this.spawnDelay == -1) {
|
||||
+ if (this.spawnDelay < -tickDelay) {
|
||||
this.delay(world, pos);
|
||||
}
|
||||
|
||||
if (this.spawnDelay > 0) {
|
||||
- --this.spawnDelay;
|
||||
+ this.spawnDelay -= tickDelay; // Paper
|
||||
} else {
|
||||
boolean flag = false;
|
||||
RandomSource randomsource = world.getRandom();
|
||||
@@ -0,0 +0,0 @@ public abstract class BaseSpawner {
|
||||
((Mob) entity).finalizeSpawn(world, world.getCurrentDifficultyAt(entity.blockPosition()), MobSpawnType.SPAWNER, (SpawnGroupData) null, (CompoundTag) null);
|
||||
}
|
||||
// Spigot Start
|
||||
- if ( entityinsentient.level.spigotConfig.nerfSpawnerMobs )
|
||||
- {
|
||||
+ if (entityinsentient.level.spigotConfig.nerfSpawnerMobs) {
|
||||
entityinsentient.aware = false;
|
||||
}
|
||||
// Spigot End
|
||||
@@ -1,27 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <1254957+zachbr@users.noreply.github.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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
|
||||
// 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,19 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <1254957+zachbr@users.noreply.github.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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -0,0 +0,0 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
||||
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,49 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <1254957+zachbr@users.noreply.github.com>
|
||||
Date: Tue, 1 Mar 2016 23:58:50 -0600
|
||||
Subject: [PATCH] Configurable top of nether void damage
|
||||
|
||||
Co-authored-by: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
|
||||
}
|
||||
|
||||
public void checkOutOfWorld() {
|
||||
- if (this.getY() < (double) (this.level.getMinBuildHeight() - 64)) {
|
||||
+ // Paper start - Configurable nether ceiling damage
|
||||
+ if (this.getY() < (double) (this.level.getMinBuildHeight() - 64) || (this.level.getWorld().getEnvironment() == org.bukkit.World.Environment.NETHER
|
||||
+ && this.level.paperConfig().environment.netherCeilingVoidDamageHeight.test(v -> this.getY() >= v)
|
||||
+ && (!(this instanceof Player player) || !player.getAbilities().invulnerable))) {
|
||||
+ // Paper end
|
||||
this.outOfWorld();
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/portal/PortalForcer.java b/src/main/java/net/minecraft/world/level/portal/PortalForcer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/portal/PortalForcer.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/portal/PortalForcer.java
|
||||
@@ -0,0 +0,0 @@ public class PortalForcer {
|
||||
Optional<PoiRecord> optional = villageplace.getInSquare((holder) -> {
|
||||
return holder.is(PoiTypes.NETHER_PORTAL);
|
||||
}, blockposition, i, PoiManager.Occupancy.ANY).filter((villageplacerecord) -> {
|
||||
- return worldborder.isWithinBounds(villageplacerecord.getPos());
|
||||
+ return worldborder.isWithinBounds(villageplacerecord.getPos()) && !this.level.paperConfig().environment.netherCeilingVoidDamageHeight.test(v -> villageplacerecord.getPos().getY() >= v); // Paper - don't teleport into void damage
|
||||
}).sorted(Comparator.comparingDouble((PoiRecord villageplacerecord) -> { // CraftBukkit - decompile error
|
||||
return villageplacerecord.getPos().distSqr(blockposition);
|
||||
}).thenComparingInt((villageplacerecord) -> {
|
||||
@@ -0,0 +0,0 @@ public class PortalForcer {
|
||||
BlockPos blockposition2 = null;
|
||||
WorldBorder worldborder = this.level.getWorldBorder();
|
||||
int i = Math.min(this.level.getMaxBuildHeight(), this.level.getMinBuildHeight() + this.level.getLogicalHeight()) - 1;
|
||||
+ // Paper start - if ceiling void damage is enabled, make sure the max height doesn't exceed the void damage height
|
||||
+ if (this.level.paperConfig().environment.netherCeilingVoidDamageHeight.enabled()) {
|
||||
+ i = Math.min(i, this.level.paperConfig().environment.netherCeilingVoidDamageHeight.intValue() - 1);
|
||||
+ }
|
||||
+ // Paper end
|
||||
BlockPos.MutableBlockPos blockposition_mutableblockposition = blockposition.mutable();
|
||||
Iterator iterator = BlockPos.spiralAround(blockposition, createRadius, Direction.EAST, Direction.SOUTH).iterator(); // CraftBukkit
|
||||
|
||||
@@ -1,49 +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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity {
|
||||
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);
|
||||
org.bukkit.inventory.EquipmentSlot hand = org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(enumhand);
|
||||
- PlayerItemConsumeEvent event = new PlayerItemConsumeEvent((Player) this.getBukkitEntity(), craftItem, hand);
|
||||
+ event = new PlayerItemConsumeEvent((Player) this.getBukkitEntity(), craftItem, hand); // Paper
|
||||
level.getCraftServer().getPluginManager().callEvent(event);
|
||||
|
||||
if (event.isCancelled()) {
|
||||
@@ -0,0 +0,0 @@ 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) {
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -0,0 +0,0 @@ public final class CraftServer implements Server {
|
||||
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();
|
||||
@@ -0,0 +0,0 @@ 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,36 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 8 Mar 2016 23:25:45 -0500
|
||||
Subject: [PATCH] Disable Scoreboards for non players by default
|
||||
|
||||
Entities collision is checking for scoreboards setting.
|
||||
This is very heavy to do map lookups for every collision to check
|
||||
this setting.
|
||||
|
||||
So avoid looking up scoreboards and short circuit to the "not on a team"
|
||||
logic which is most likely to be true.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
|
||||
|
||||
@Nullable
|
||||
public Team getTeam() {
|
||||
+ if (!this.level.paperConfig().scoreboards.allowNonPlayerEntitiesOnScoreboards && !(this instanceof Player)) { return null; } // Paper
|
||||
return this.level.getScoreboard().getPlayersTeam(this.getScoreboardName());
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity {
|
||||
if (nbt.contains("Team", 8)) {
|
||||
String s = nbt.getString("Team");
|
||||
PlayerTeam scoreboardteam = this.level.getScoreboard().getPlayerTeam(s);
|
||||
+ if (!level.paperConfig().scoreboards.allowNonPlayerEntitiesOnScoreboards && !(this instanceof net.minecraft.world.entity.player.Player)) { scoreboardteam = null; } // Paper
|
||||
boolean flag = scoreboardteam != null && this.level.getScoreboard().addPlayerToTeam(this.getStringUUID(), scoreboardteam);
|
||||
|
||||
if (!flag) {
|
||||
@@ -1,55 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Sudzzy <originmc@outlook.com>
|
||||
Date: Wed, 2 Mar 2016 14:48:03 -0600
|
||||
Subject: [PATCH] Disable explosion knockback
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity {
|
||||
}
|
||||
}
|
||||
|
||||
+ boolean knockbackCancelled = level.paperConfig().environment.disableExplosionKnockback && source.isExplosion() && this instanceof net.minecraft.world.entity.player.Player; // Paper - Disable explosion knockback
|
||||
if (flag1) {
|
||||
if (flag) {
|
||||
this.level.broadcastEntityEvent(this, (byte) 29);
|
||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity {
|
||||
b0 = 2;
|
||||
}
|
||||
|
||||
+ if (!knockbackCancelled) // Paper - Disable explosion knockback
|
||||
this.level.broadcastEntityEvent(this, b0);
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity {
|
||||
}
|
||||
}
|
||||
|
||||
+ if (knockbackCancelled) this.level.broadcastEntityEvent(this, (byte) 2); // Paper - Disable explosion knockback
|
||||
if (this.isDeadOrDying()) {
|
||||
if (!this.checkTotemDeathProtection(source)) {
|
||||
SoundEvent soundeffect = this.getDeathSound();
|
||||
diff --git a/src/main/java/net/minecraft/world/level/Explosion.java b/src/main/java/net/minecraft/world/level/Explosion.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/Explosion.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Explosion.java
|
||||
@@ -0,0 +0,0 @@ public class Explosion {
|
||||
double d14 = d13;
|
||||
|
||||
if (entity instanceof LivingEntity) {
|
||||
- d14 = ProtectionEnchantment.getExplosionKnockbackAfterDampener((LivingEntity) entity, d13);
|
||||
+ d14 = entity instanceof Player && level.paperConfig().environment.disableExplosionKnockback ? 0 : ProtectionEnchantment.getExplosionKnockbackAfterDampener((LivingEntity) entity, d13); // Paper - Disable explosion knockback
|
||||
}
|
||||
|
||||
entity.setDeltaMovement(entity.getDeltaMovement().add(d8 * d14, d9 * d14, d10 * d14));
|
||||
if (entity instanceof Player) {
|
||||
Player entityhuman = (Player) entity;
|
||||
|
||||
- if (!entityhuman.isSpectator() && (!entityhuman.isCreative() || !entityhuman.getAbilities().flying)) {
|
||||
+ if (!entityhuman.isSpectator() && (!entityhuman.isCreative() || !entityhuman.getAbilities().flying) && !level.paperConfig().environment.disableExplosionKnockback) { // Paper - Disable explosion knockback
|
||||
this.hitPlayers.put(entityhuman, new Vec3(d8 * d13, d9 * d13, d10 * d13));
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Sudzzy <originmc@outlook.com>
|
||||
Date: Wed, 2 Mar 2016 14:57:24 -0600
|
||||
Subject: [PATCH] Disable ice and snow
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -0,0 +0,0 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
||||
gameprofilerfiller.popPush("iceandsnow");
|
||||
int l;
|
||||
|
||||
- if (this.random.nextInt(16) == 0) {
|
||||
+ if (!this.paperConfig().environment.disableIceAndSnow && this.random.nextInt(16) == 0) { // Paper - Disable ice and snow
|
||||
blockposition = this.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, this.getBlockRandomPos(j, 0, k, 15));
|
||||
BlockPos blockposition1 = blockposition.below();
|
||||
Biome biomebase = (Biome) this.getBiome(blockposition).value();
|
||||
@@ -1,21 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <1254957+zachbr@users.noreply.github.com>
|
||||
Date: Wed, 2 Mar 2016 23:45:17 -0600
|
||||
Subject: [PATCH] Disable spigot tick limiters
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/Level.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
// Spigot start
|
||||
// Iterator iterator = this.blockEntityTickers.iterator();
|
||||
int tilesThisCycle = 0;
|
||||
- for (this.tileLimiter.initTick();
|
||||
- tilesThisCycle < this.blockEntityTickers.size() && (tilesThisCycle % 10 != 0 || this.tileLimiter.shouldContinue());
|
||||
- this.tileTickPosition++, tilesThisCycle++) {
|
||||
+ for (tileTickPosition = 0; tileTickPosition < this.blockEntityTickers.size(); tileTickPosition++) { // Paper - Disable tick limiters
|
||||
this.tileTickPosition = (this.tileTickPosition < this.blockEntityTickers.size()) ? this.tileTickPosition : 0;
|
||||
TickingBlockEntity tickingblockentity = (TickingBlockEntity) this.blockEntityTickers.get(tileTickPosition);
|
||||
// Spigot start
|
||||
@@ -1,19 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Sudzzy <originmc@outlook.com>
|
||||
Date: Wed, 2 Mar 2016 14:52:43 -0600
|
||||
Subject: [PATCH] Disable thunder
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -0,0 +0,0 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
||||
gameprofilerfiller.push("thunder");
|
||||
BlockPos blockposition;
|
||||
|
||||
- if (flag && this.isThundering() && this.spigotConfig.thunderChance > 0 && this.random.nextInt(this.spigotConfig.thunderChance) == 0) { // Spigot
|
||||
+ if (!this.paperConfig().environment.disableThunder && flag && this.isThundering() && this.spigotConfig.thunderChance > 0 && this.random.nextInt(this.spigotConfig.thunderChance) == 0) { // Spigot // Paper - disable thunder
|
||||
blockposition = this.findLightningTargetAround(this.getBlockRandomPos(j, 0, k, 15));
|
||||
if (this.isRainingAt(blockposition)) {
|
||||
DifficultyInstance difficultydamagescaler = this.getCurrentDifficultyAt(blockposition);
|
||||
@@ -1,23 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <1254957+zachbr@users.noreply.github.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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
@@ -0,0 +0,0 @@ public class ArmorStand extends LivingEntity {
|
||||
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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/pathfinder/WalkNodeEvaluator.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/pathfinder/WalkNodeEvaluator.java
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class WalkNodeEvaluator extends NodeEvaluator {
|
||||
if (world.getFluidState(pos).is(FluidTags.WATER)) {
|
||||
return BlockPathTypes.WATER_BORDER;
|
||||
}
|
||||
+ } // Paper
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/Util.java
|
||||
+++ b/src/main/java/net/minecraft/Util.java
|
||||
@@ -0,0 +0,0 @@ public class Util {
|
||||
private static final 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();
|
||||
private static final DateTimeFormatter FILENAME_DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd_HH.mm.ss", Locale.ROOT);
|
||||
public static TimeSource.NanoTimeSource timeSource = System::nanoTime;
|
||||
diff --git a/src/main/java/net/minecraft/server/players/GameProfileCache.java b/src/main/java/net/minecraft/server/players/GameProfileCache.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/GameProfileCache.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/GameProfileCache.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java
|
||||
@@ -0,0 +0,0 @@ public class SkullBlockEntity extends BlockEntity {
|
||||
public static void updateGameprofile(@Nullable GameProfile owner, Consumer<GameProfile> callback) {
|
||||
if (owner != null && !StringUtil.isNullOrEmpty(owner.getName()) && (!owner.isComplete() || !owner.getProperties().containsKey("textures")) && SkullBlockEntity.profileCache != null && SkullBlockEntity.sessionService != null) {
|
||||
SkullBlockEntity.profileCache.getAsync(owner.getName(), (optional) -> {
|
||||
- Util.backgroundExecutor().execute(() -> {
|
||||
+ Util.PROFILE_EXECUTOR.execute(() -> { // Paper - not a good idea to use BLOCKING OPERATIONS on the worldgen executor
|
||||
Util.ifElse(optional, (gameprofile1) -> {
|
||||
Property property = (Property) Iterables.getFirst(gameprofile1.getProperties().get("textures"), (Object) null);
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/profile/CraftPlayerProfile.java b/src/main/java/org/bukkit/craftbukkit/profile/CraftPlayerProfile.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/profile/CraftPlayerProfile.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/profile/CraftPlayerProfile.java
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
|
||||
}
|
||||
|
||||
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,18 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <1254957+zachbr@users.noreply.github.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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/GameProfileCache.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/GameProfileCache.java
|
||||
@@ -0,0 +0,0 @@ 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,35 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Riley Park <rileysebastianpark@gmail.com>
|
||||
Date: Tue, 8 Mar 2016 18:28:43 -0800
|
||||
Subject: [PATCH] Don't nest if we don't need to when cerealising text
|
||||
components
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundSystemChatPacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundSystemChatPacket.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/network/protocol/game/ClientboundSystemChatPacket.java
|
||||
+++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundSystemChatPacket.java
|
||||
@@ -0,0 +0,0 @@ public record ClientboundSystemChatPacket(@javax.annotation.Nullable net.kyori.a
|
||||
}
|
||||
|
||||
public ClientboundSystemChatPacket(net.md_5.bungee.api.chat.BaseComponent[] content, boolean overlay) {
|
||||
- this(null, net.md_5.bungee.chat.ComponentSerializer.toString(content), overlay); // Paper - Adventure
|
||||
+ this(null, improveBungeeComponentSerialization(content), overlay); // Paper - Adventure
|
||||
}
|
||||
// Spigot end
|
||||
// Paper start
|
||||
@@ -0,0 +0,0 @@ public record ClientboundSystemChatPacket(@javax.annotation.Nullable net.kyori.a
|
||||
public ClientboundSystemChatPacket(net.kyori.adventure.text.Component content, boolean overlay) {
|
||||
this(content, null, overlay);
|
||||
}
|
||||
+
|
||||
+ private static String improveBungeeComponentSerialization(net.md_5.bungee.api.chat.BaseComponent[] content) {
|
||||
+ if (content.length == 1) {
|
||||
+ return net.md_5.bungee.chat.ComponentSerializer.toString(content[0]);
|
||||
+ } else {
|
||||
+ return net.md_5.bungee.chat.ComponentSerializer.toString(content);
|
||||
+ }
|
||||
+ }
|
||||
// Paper end
|
||||
|
||||
public ClientboundSystemChatPacket(FriendlyByteBuf buf) {
|
||||
@@ -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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/scores/ScoreboardSaveData.java
|
||||
+++ b/src/main/java/net/minecraft/world/scores/ScoreboardSaveData.java
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
@@ -0,0 +0,0 @@ public abstract class PlayerList {
|
||||
}
|
||||
|
||||
public void saveAll() {
|
||||
+ io.papermc.paper.util.MCUtil.ensureMain("Save Players" , () -> { // Paper - Ensure main
|
||||
MinecraftTimings.savePlayers.startTiming(); // Paper
|
||||
for (int i = 0; i < this.players.size(); ++i) {
|
||||
- this.save((ServerPlayer) this.players.get(i));
|
||||
+ this.save(this.players.get(i));
|
||||
}
|
||||
MinecraftTimings.savePlayers.stopTiming(); // Paper
|
||||
+ return null; }); // Paper - ensure main
|
||||
}
|
||||
|
||||
public UserWhiteList getWhiteList() {
|
||||
@@ -1,170 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Thu, 3 Mar 2016 01:17:12 -0600
|
||||
Subject: [PATCH] Ensure commands are not ran async
|
||||
|
||||
Plugins calling Player.chat("/foo") or Server.dispatchCommand() could
|
||||
trigger the server to execute a command while on another thread.
|
||||
|
||||
These commands would then process EXPECTING to be on the main thread, leaving to
|
||||
very hard to trace concurrency issues.
|
||||
|
||||
This change will synchronize the command execution back to the main thread, causing a
|
||||
big slowdown in execution but throwing an exception at same time to raise awareness
|
||||
that it is happening so that plugin authors can fix their code to stop executing commands async.
|
||||
|
||||
This also properly splits up the chat and command handling to reflect the server now
|
||||
having separate packets for both, and the client always using the correct packet. Text
|
||||
from a chat packet should never be parsed into a command, even if it starts with the `/`
|
||||
character.
|
||||
|
||||
Co-authored-by: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
|
||||
return true;
|
||||
}
|
||||
|
||||
- private static boolean isChatMessageIllegal(String message) {
|
||||
+ public static boolean isChatMessageIllegal(String message) { // Paper - private -> public
|
||||
for (int i = 0; i < message.length(); ++i) {
|
||||
if (!SharedConstants.isAllowedChatCharacter(message.charAt(i))) {
|
||||
return true;
|
||||
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
|
||||
}
|
||||
OutgoingChatMessage outgoing = OutgoingChatMessage.create(original);
|
||||
|
||||
- if (!async && s.startsWith("/")) {
|
||||
+ if (false && !async && s.startsWith("/")) { // Paper - don't handle commands in chat logic
|
||||
this.handleCommand(s);
|
||||
} else if (this.player.getChatVisibility() == ChatVisiblity.SYSTEM) {
|
||||
// Do nothing, this is coming from a plugin
|
||||
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
|
||||
}
|
||||
}
|
||||
|
||||
- private void handleCommand(String s) {
|
||||
+ public void handleCommand(String s) { // Paper - private -> public
|
||||
+ // Paper Start
|
||||
+ if (!org.spigotmc.AsyncCatcher.shuttingDown && !org.bukkit.Bukkit.isPrimaryThread()) {
|
||||
+ LOGGER.error("Command Dispatched Async: " + s);
|
||||
+ LOGGER.error("Please notify author of plugin causing this execution to fix this bug! see: http://bit.ly/1oSiM6C", new Throwable());
|
||||
+ Waitable<Void> wait = new Waitable<>() {
|
||||
+ @Override
|
||||
+ protected Void evaluate() {
|
||||
+ ServerGamePacketListenerImpl.this.handleCommand(s);
|
||||
+ return null;
|
||||
+ }
|
||||
+ };
|
||||
+ server.processQueue.add(wait);
|
||||
+ try {
|
||||
+ wait.get();
|
||||
+ return;
|
||||
+ } catch (InterruptedException e) {
|
||||
+ Thread.currentThread().interrupt(); // This is proper habit for java. If we aren't handling it, pass it on!
|
||||
+ } catch (Exception e) {
|
||||
+ throw new RuntimeException("Exception processing chat command", e.getCause());
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper End
|
||||
co.aikar.timings.MinecraftTimings.playerCommandTimer.startTiming(); // Paper
|
||||
if ( org.spigotmc.SpigotConfig.logCommands ) // Spigot
|
||||
this.LOGGER.info(this.player.getScoreboardName() + " issued server command: " + s);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -0,0 +0,0 @@ public final class CraftServer implements Server {
|
||||
Validate.notNull(commandLine, "CommandLine cannot be null");
|
||||
org.spigotmc.AsyncCatcher.catchOp("command dispatch"); // Spigot
|
||||
|
||||
+ // Paper Start
|
||||
+ if (!org.spigotmc.AsyncCatcher.shuttingDown && !Bukkit.isPrimaryThread()) {
|
||||
+ final CommandSender fSender = sender;
|
||||
+ final String fCommandLine = commandLine;
|
||||
+ Bukkit.getLogger().log(Level.SEVERE, "Command Dispatched Async: " + commandLine);
|
||||
+ Bukkit.getLogger().log(Level.SEVERE, "Please notify author of plugin causing this execution to fix this bug! see: http://bit.ly/1oSiM6C", new Throwable());
|
||||
+ org.bukkit.craftbukkit.util.Waitable<Boolean> wait = new org.bukkit.craftbukkit.util.Waitable<Boolean>() {
|
||||
+ @Override
|
||||
+ protected Boolean evaluate() {
|
||||
+ return dispatchCommand(fSender, fCommandLine);
|
||||
+ }
|
||||
+ };
|
||||
+ net.minecraft.server.MinecraftServer.getServer().processQueue.add(wait);
|
||||
+ try {
|
||||
+ return wait.get();
|
||||
+ } catch (InterruptedException e) {
|
||||
+ Thread.currentThread().interrupt(); // This is proper habit for java. If we aren't handling it, pass it on!
|
||||
+ } catch (Exception e) {
|
||||
+ throw new RuntimeException("Exception processing dispatch command", e.getCause());
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper End
|
||||
if (this.commandMap.dispatch(sender, commandLine)) {
|
||||
return true;
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
public void chat(String msg) {
|
||||
if (this.getHandle().connection == null) return;
|
||||
|
||||
- this.getHandle().connection.chat(msg, PlayerChatMessage.system(msg), false);
|
||||
+ // Paper start - improve chat handling
|
||||
+ if (ServerGamePacketListenerImpl.isChatMessageIllegal(msg)) {
|
||||
+ this.getHandle().connection.disconnect(Component.translatable("multiplayer.disconnect.illegal_characters"), org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_CHARACTERS);
|
||||
+ } else {
|
||||
+ if (msg.startsWith("/")) {
|
||||
+ this.getHandle().connection.handleCommand(msg);
|
||||
+ } else {
|
||||
+ final PlayerChatMessage playerChatMessage = PlayerChatMessage.system(msg).withResult(new net.minecraft.network.chat.ChatDecorator.ModernResult(Component.literal(msg), true, false));
|
||||
+ // TODO chat decorating
|
||||
+ // TODO text filtering
|
||||
+ this.getHandle().connection.chat(msg, playerChatMessage, false);
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/util/ServerShutdownThread.java b/src/main/java/org/bukkit/craftbukkit/util/ServerShutdownThread.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/util/ServerShutdownThread.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/util/ServerShutdownThread.java
|
||||
@@ -0,0 +0,0 @@ public class ServerShutdownThread extends Thread {
|
||||
public void run() {
|
||||
try {
|
||||
org.spigotmc.AsyncCatcher.enabled = false; // Spigot
|
||||
+ org.spigotmc.AsyncCatcher.shuttingDown = true; // Paper
|
||||
this.server.close();
|
||||
} finally {
|
||||
try {
|
||||
diff --git a/src/main/java/org/spigotmc/AsyncCatcher.java b/src/main/java/org/spigotmc/AsyncCatcher.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/spigotmc/AsyncCatcher.java
|
||||
+++ b/src/main/java/org/spigotmc/AsyncCatcher.java
|
||||
@@ -0,0 +0,0 @@ public class AsyncCatcher
|
||||
{
|
||||
|
||||
public static boolean enabled = true;
|
||||
+ public static boolean shuttingDown = false; // Paper
|
||||
|
||||
public static void catchOp(String reason)
|
||||
{
|
||||
diff --git a/src/main/java/org/spigotmc/RestartCommand.java b/src/main/java/org/spigotmc/RestartCommand.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/spigotmc/RestartCommand.java
|
||||
+++ b/src/main/java/org/spigotmc/RestartCommand.java
|
||||
@@ -0,0 +0,0 @@ public class RestartCommand extends Command
|
||||
private static void restart(final String restartScript)
|
||||
{
|
||||
AsyncCatcher.enabled = false; // Disable async catcher incase it interferes with us
|
||||
+ org.spigotmc.AsyncCatcher.shuttingDown = true; // Paper
|
||||
try
|
||||
{
|
||||
String[] split = restartScript.split( " " );
|
||||
@@ -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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -0,0 +0,0 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
||||
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) {
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
|
||||
// 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
|
||||
@@ -0,0 +0,0 @@ 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) {
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/BaseSpawner.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/BaseSpawner.java
|
||||
@@ -0,0 +0,0 @@ public abstract class BaseSpawner {
|
||||
}
|
||||
// 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
|
||||
//noinspection ConstantConditions
|
||||
return originVector.toLocation(world);
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean fromMobSpawner() {
|
||||
+ return getHandle().spawnedViaMobSpawner;
|
||||
+ }
|
||||
// Paper end
|
||||
}
|
||||
@@ -1,149 +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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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
|
||||
@@ -0,0 +0,0 @@ public class GroundPathNavigation extends PathNavigation {
|
||||
}
|
||||
|
||||
@Override
|
||||
- public Path createPath(BlockPos target, int distance) {
|
||||
+ public Path createPath(BlockPos target, @javax.annotation.Nullable Entity entity, int distance) { // Paper
|
||||
if (this.level.getBlockState(target).isAir()) {
|
||||
BlockPos blockPos;
|
||||
for(blockPos = target.below(); blockPos.getY() > this.level.getMinBuildHeight() && this.level.getBlockState(blockPos).isAir(); blockPos = blockPos.below()) {
|
||||
}
|
||||
|
||||
if (blockPos.getY() > this.level.getMinBuildHeight()) {
|
||||
- return super.createPath(blockPos.above(), distance);
|
||||
+ return super.createPath(blockPos.above(), entity, distance); // Paper
|
||||
}
|
||||
|
||||
while(blockPos.getY() < this.level.getMaxBuildHeight() && this.level.getBlockState(blockPos).isAir()) {
|
||||
@@ -0,0 +0,0 @@ public class GroundPathNavigation extends PathNavigation {
|
||||
}
|
||||
|
||||
if (!this.level.getBlockState(target).getMaterial().isSolid()) {
|
||||
- return super.createPath(target, distance);
|
||||
+ return super.createPath(target, entity, distance); // Paper
|
||||
} else {
|
||||
BlockPos blockPos2;
|
||||
for(blockPos2 = target.above(); blockPos2.getY() < this.level.getMaxBuildHeight() && this.level.getBlockState(blockPos2).getMaterial().isSolid(); blockPos2 = blockPos2.above()) {
|
||||
}
|
||||
|
||||
- return super.createPath(blockPos2, distance);
|
||||
+ return super.createPath(blockPos2, entity, distance); // Paper
|
||||
}
|
||||
}
|
||||
|
||||
@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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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
|
||||
@@ -0,0 +0,0 @@ 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, @Nullable Entity entity, int distance) {
|
||||
+ return this.createPath(ImmutableSet.of(target), entity, 8, false, distance);
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -0,0 +0,0 @@ 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
|
||||
@@ -0,0 +0,0 @@ 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, followRange);
|
||||
+ }
|
||||
+
|
||||
+ @Nullable
|
||||
+ protected Path createPath(Set<BlockPos> positions, @Nullable 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, @Nullable 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()) {
|
||||
@@ -0,0 +0,0 @@ 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(),
|
||||
+ io.papermc.paper.util.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);
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/ai/navigation/WallClimberNavigation.java b/src/main/java/net/minecraft/world/entity/ai/navigation/WallClimberNavigation.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ai/navigation/WallClimberNavigation.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ai/navigation/WallClimberNavigation.java
|
||||
@@ -0,0 +0,0 @@ public class WallClimberNavigation extends GroundPathNavigation {
|
||||
}
|
||||
|
||||
@Override
|
||||
- public Path createPath(BlockPos target, int distance) {
|
||||
+ public Path createPath(BlockPos target, @Nullable Entity entity, int distance) { // Paper
|
||||
this.pathToPosition = target;
|
||||
- return super.createPath(target, distance);
|
||||
+ return super.createPath(target, entity, distance); // Paper
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1,42 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <1254957+zachbr@users.noreply.github.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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity {
|
||||
}
|
||||
|
||||
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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/food/FoodData.java
|
||||
+++ b/src/main/java/net/minecraft/world/food/FoodData.java
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
|
||||
@@ -0,0 +0,0 @@ public class ServerPlayerGameMode {
|
||||
|
||||
// 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ExperienceOrb.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ExperienceOrb.java
|
||||
@@ -0,0 +0,0 @@ public class ExperienceOrb extends Entity {
|
||||
public 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) {
|
||||
@@ -0,0 +0,0 @@ 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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ 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
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity {
|
||||
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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/Animal.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/Animal.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/Fox.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/Fox.java
|
||||
@@ -0,0 +0,0 @@ public class Fox extends Animal implements VariantHolder<Fox.Type> {
|
||||
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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/Turtle.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/Turtle.java
|
||||
@@ -0,0 +0,0 @@ public class Turtle extends Animal {
|
||||
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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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
|
||||
@@ -0,0 +0,0 @@ public class Frog extends Animal implements VariantHolder<FrogVariant> {
|
||||
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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java
|
||||
@@ -0,0 +0,0 @@ public class EnderDragon extends Mob implements Enemy {
|
||||
|
||||
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()) {
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/npc/Villager.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/npc/WanderingTrader.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/FishingHook.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/ThrownExperienceBottle.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/ThrownExperienceBottle.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java
|
||||
+++ b/src/main/java/net/minecraft/world/inventory/GrindstoneMenu.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/Block.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/Block.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit
|
||||
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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftExperienceOrb.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftExperienceOrb.java
|
||||
@@ -0,0 +0,0 @@ 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,18 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Riley Park <rileysebastianpark@gmail.com>
|
||||
Date: Thu, 3 Mar 2016 02:15:57 -0600
|
||||
Subject: [PATCH] Expose server CommandMap
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -0,0 +0,0 @@ public final class CraftServer implements Server {
|
||||
return this.helpMap;
|
||||
}
|
||||
|
||||
+ @Override // Paper - add override
|
||||
public SimpleCommandMap getCommandMap() {
|
||||
return this.commandMap;
|
||||
}
|
||||
@@ -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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/Level.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/RedstoneTorchBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/RedstoneTorchBlock.java
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
@@ -0,0 +0,0 @@ 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();
|
||||
@@ -0,0 +0,0 @@ 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()));
|
||||
@@ -0,0 +0,0 @@ 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,19 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <1254957+zachbr@users.noreply.github.com>
|
||||
Date: Sat, 12 Nov 2016 23:25:22 -0600
|
||||
Subject: [PATCH] Filter bad tile entity nbt data from falling blocks
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java b/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/item/FallingBlockEntity.java
|
||||
@@ -0,0 +0,0 @@ public class FallingBlockEntity extends Entity {
|
||||
this.dropItem = nbt.getBoolean("DropItem");
|
||||
}
|
||||
|
||||
- if (nbt.contains("TileEntityData", 10)) {
|
||||
+ if (nbt.contains("TileEntityData", 10) && !(this.level.paperConfig().entities.spawning.filterBadTileEntityNbtFromFallingBlocks && this.blockState.getBlock() instanceof net.minecraft.world.level.block.GameMasterBlock)) {
|
||||
this.blockData = nbt.getCompound("TileEntityData");
|
||||
}
|
||||
|
||||
@@ -1,93 +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
|
||||
|
||||
== AT ==
|
||||
public net.minecraft.world.entity.projectile.FireworkRocketEntity attachedToEntity
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/projectile/FireworkRocketEntity.java b/src/main/java/net/minecraft/world/entity/projectile/FireworkRocketEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/FireworkRocketEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/FireworkRocketEntity.java
|
||||
@@ -0,0 +0,0 @@ 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);
|
||||
@@ -0,0 +0,0 @@ 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
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/CrossbowItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/CrossbowItem.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/FireworkRocketItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/FireworkRocketItem.java
|
||||
@@ -0,0 +0,0 @@ public class FireworkRocketItem extends Item {
|
||||
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);
|
||||
}
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java
|
||||
@@ -0,0 +0,0 @@ public class CraftFirework extends CraftProjectile implements Firework {
|
||||
public void setShotAtAngle(boolean shotAtAngle) {
|
||||
this.getHandle().getEntityData().set(FireworkRocketEntity.DATA_SHOT_AT_ANGLE, shotAtAngle);
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public java.util.UUID getSpawningEntity() {
|
||||
+ return getHandle().spawningEntity;
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
@@ -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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -0,0 +0,0 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
||||
|
||||
@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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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
|
||||
@@ -0,0 +0,0 @@ public class StructureTemplate {
|
||||
definedstructure_blockinfo.nbt.putLong("LootTableSeed", random.nextLong());
|
||||
}
|
||||
|
||||
+ tileentity.isLoadingStructure = true; // Paper
|
||||
tileentity.load(definedstructure_blockinfo.nbt);
|
||||
+ tileentity.isLoadingStructure = false; // Paper
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Iceee <andrew@opticgaming.tv>
|
||||
Date: Wed, 2 Mar 2016 01:39:52 -0600
|
||||
Subject: [PATCH] Fix lag from explosions processing dead entities
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/Explosion.java b/src/main/java/net/minecraft/world/level/Explosion.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/Explosion.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Explosion.java
|
||||
@@ -0,0 +0,0 @@ public class Explosion {
|
||||
int i1 = Mth.floor(this.y + (double) f2 + 1.0D);
|
||||
int j1 = Mth.floor(this.z - (double) f2 - 1.0D);
|
||||
int k1 = Mth.floor(this.z + (double) f2 + 1.0D);
|
||||
- List<Entity> list = this.level.getEntities(this.source, new AABB((double) i, (double) l, (double) j1, (double) j, (double) i1, (double) k1));
|
||||
+ List<Entity> list = this.level.getEntities(this.source, new AABB((double) i, (double) l, (double) j1, (double) j, (double) i1, (double) k1), (com.google.common.base.Predicate<Entity>) entity -> entity.isAlive() && !entity.isSpectator()); // Paper - Fix lag from explosions processing dead entities
|
||||
Vec3 vec3d = new Vec3(this.x, this.y, this.z);
|
||||
|
||||
for (int l1 = 0; l1 < list.size(); ++l1) {
|
||||
@@ -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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/Bootstrap.java
|
||||
+++ b/src/main/java/net/minecraft/server/Bootstrap.java
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
@@ -0,0 +0,0 @@ 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 (BuiltInRegistries.REGISTRY.keySet().isEmpty()) {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/Main.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/Main.java
|
||||
@@ -0,0 +0,0 @@ public class Main {
|
||||
Calendar deadline = Calendar.getInstance();
|
||||
deadline.add(Calendar.DAY_OF_YEAR, -28);
|
||||
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,321 +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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
@@ -0,0 +0,0 @@ public final class ItemStack {
|
||||
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);
|
||||
}
|
||||
@@ -0,0 +0,0 @@ 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);
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ 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());
|
||||
}
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
@@ -0,0 +0,0 @@ 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) {
|
||||
@@ -0,0 +0,0 @@ public final class CraftItemStack extends ItemStack {
|
||||
if (this.handle == null) {
|
||||
return 0;
|
||||
}
|
||||
- return EnchantmentHelper.getItemEnchantmentLevel(CraftEnchantment.getRaw(ench), handle);
|
||||
+ return net.minecraft.world.item.enchantment.EnchantmentHelper.getItemEnchantmentLevel(CraftEnchantment.getRaw(ench), handle); // Paper
|
||||
}
|
||||
|
||||
@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
|
||||
+ int level = getEnchantmentLevel(ench);
|
||||
+ if (level > 0) {
|
||||
+ final ItemMeta itemMeta = this.getItemMeta();
|
||||
+ if (itemMeta == null) return 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
@@ -0,0 +0,0 @@ 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
|
||||
@@ -0,0 +0,0 @@ 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()) {
|
||||
@@ -0,0 +0,0 @@ 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);
|
||||
@@ -0,0 +0,0 @@ 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();
|
||||
@@ -0,0 +0,0 @@ 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()) {
|
||||
@@ -0,0 +0,0 @@ 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);
|
||||
@@ -0,0 +0,0 @@ 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,48 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Isaac Moore <rmsy@me.com>
|
||||
Date: Tue, 19 Apr 2016 14:09:31 -0500
|
||||
Subject: [PATCH] Implement PlayerLocaleChangeEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
|
||||
return s;
|
||||
}
|
||||
|
||||
- public String locale = "en_us"; // CraftBukkit - add, lowercase
|
||||
+ public String locale = null; // CraftBukkit - add, lowercase // Paper - default to null
|
||||
public java.util.Locale adventure$locale = java.util.Locale.US; // Paper
|
||||
public void updateOptions(ServerboundClientInformationPacket packet) {
|
||||
// CraftBukkit start
|
||||
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
|
||||
PlayerChangedMainHandEvent event = new PlayerChangedMainHandEvent(this.getBukkitEntity(), getMainArm() == HumanoidArm.LEFT ? MainHand.LEFT : MainHand.RIGHT);
|
||||
this.server.server.getPluginManager().callEvent(event);
|
||||
}
|
||||
- if (!this.locale.equals(packet.language)) {
|
||||
+ if (this.locale == null || !this.locale.equals(packet.language)) { // Paper - check for null
|
||||
PlayerLocaleChangeEvent event = new PlayerLocaleChangeEvent(this.getBukkitEntity(), packet.language);
|
||||
this.server.server.getPluginManager().callEvent(event);
|
||||
+ this.server.server.getPluginManager().callEvent(new com.destroystokyo.paper.event.player.PlayerLocaleChangeEvent(this.getBukkitEntity(), this.locale, packet.language)); // Paper
|
||||
}
|
||||
this.locale = packet.language;
|
||||
// Paper start
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
|
||||
@Override
|
||||
public String getLocale() {
|
||||
- return this.getHandle().locale;
|
||||
-
|
||||
+ // Paper start - Locale change event
|
||||
+ final String locale = this.getHandle().locale;
|
||||
+ return locale != null ? locale : "en_us";
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
// Paper start
|
||||
@@ -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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -0,0 +0,0 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
||||
{
|
||||
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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Player extends LivingEntity {
|
||||
return 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
@@ -0,0 +0,0 @@ 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
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ public class MapItemSavedData extends SavedData {
|
||||
if (abyte.length == 16384) {
|
||||
worldmap.colors = abyte;
|
||||
}
|
||||
+ worldmap.vanillaRender.buffer = abyte; // Paper
|
||||
|
||||
ListTag nbttaglist = nbt.getList("banners", 10);
|
||||
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/map/RenderData.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/map/RenderData.java
|
||||
@@ -0,0 +0,0 @@ import org.bukkit.map.MapCursor;
|
||||
|
||||
public class RenderData {
|
||||
|
||||
- public final byte[] buffer;
|
||||
+ public byte[] buffer; // Paper
|
||||
public final ArrayList<MapCursor> cursors;
|
||||
|
||||
public RenderData() {
|
||||
@@ -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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/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.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;
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryHorse.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryHorse.java
|
||||
@@ -0,0 +0,0 @@ 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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftSaddledInventory.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Mob.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Mob.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Mob extends LivingEntity {
|
||||
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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java
|
||||
@@ -0,0 +0,0 @@ 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,29 +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
|
||||
|
||||
== AT ==
|
||||
public net.minecraft.world.entity.LivingEntity lastHurtByPlayerTime
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
@@ -0,0 +0,0 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
|
||||
return this.getHandle().lastHurtByPlayer == null ? null : (Player) this.getHandle().lastHurtByPlayer.getBukkitEntity();
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public void setKiller(Player killer) {
|
||||
+ net.minecraft.server.level.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,770 +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"
|
||||
|
||||
== AT ==
|
||||
public org.bukkit.craftbukkit.block.CraftBlockEntityState getTileEntity()Lnet/minecraft/world/level/block/entity/BlockEntity;
|
||||
public org.bukkit.craftbukkit.block.CraftLootable setLootTable(Lorg/bukkit/loot/LootTable;J)V
|
||||
public org.bukkit.craftbukkit.entity.CraftMinecartContainer setLootTable(Lorg/bukkit/loot/LootTable;J)V
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/loottable/PaperContainerEntityLootableInventory.java b/src/main/java/com/destroystokyo/paper/loottable/PaperContainerEntityLootableInventory.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/loottable/PaperContainerEntityLootableInventory.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/loottable/PaperLootableBlockInventory.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/loottable/PaperLootableEntityInventory.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/loottable/PaperLootableInventory.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/loottable/PaperLootableInventoryData.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+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..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/loottable/PaperTileEntityLootableInventory.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package com.destroystokyo.paper.loottable;
|
||||
+
|
||||
+import io.papermc.paper.util.MCUtil;
|
||||
+import net.minecraft.world.level.Level;
|
||||
+import net.minecraft.world.level.block.entity.RandomizableContainerBlockEntity;
|
||||
+import org.bukkit.Bukkit;
|
||||
+import org.bukkit.craftbukkit.util.CraftNamespacedKey;
|
||||
+
|
||||
+public class PaperTileEntityLootableInventory implements PaperLootableBlockInventory {
|
||||
+ private RandomizableContainerBlockEntity tileEntityLootable;
|
||||
+
|
||||
+ public PaperTileEntityLootableInventory(RandomizableContainerBlockEntity tileEntityLootable) {
|
||||
+ this.tileEntityLootable = tileEntityLootable;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public org.bukkit.loot.LootTable getLootTable() {
|
||||
+ return tileEntityLootable.lootTable != null ? Bukkit.getLootTable(CraftNamespacedKey.fromMinecraft(tileEntityLootable.lootTable)) : null;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setLootTable(org.bukkit.loot.LootTable table, long seed) {
|
||||
+ setLootTable(table);
|
||||
+ setSeed(seed);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setLootTable(org.bukkit.loot.LootTable table) {
|
||||
+ tileEntityLootable.lootTable = (table == null) ? null : CraftNamespacedKey.toMinecraft(table.getKey());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setSeed(long seed) {
|
||||
+ tileEntityLootable.lootTableSeed = seed;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public long getSeed() {
|
||||
+ return tileEntityLootable.lootTableSeed;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public PaperLootableInventoryData getLootableData() {
|
||||
+ return tileEntityLootable.lootableData;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public RandomizableContainerBlockEntity getTileEntity() {
|
||||
+ return tileEntityLootable;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public LootableInventory getAPILootableInventory() {
|
||||
+ Level world = tileEntityLootable.getLevel();
|
||||
+ if (world == null) {
|
||||
+ return null;
|
||||
+ }
|
||||
+ return (LootableInventory) getBukkitWorld().getBlockAt(MCUtil.toLocation(world, tileEntityLootable.getBlockPos())).getState();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public Level getNMSWorld() {
|
||||
+ return tileEntityLootable.getLevel();
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
|
||||
}
|
||||
// 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
@@ -0,0 +0,0 @@ public abstract class AbstractMinecartContainer extends AbstractMinecart impleme
|
||||
@Override
|
||||
protected void addAdditionalSaveData(CompoundTag nbt) {
|
||||
super.addAdditionalSaveData(nbt);
|
||||
+ this.lootableData.saveNbt(nbt); // Paper
|
||||
this.addChestVehicleSaveData(nbt);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void readAdditionalSaveData(CompoundTag nbt) {
|
||||
super.readAdditionalSaveData(nbt);
|
||||
+ this.lootableData.loadNbt(nbt); // Paper
|
||||
this.readChestVehicleSaveData(nbt);
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/vehicle/ChestBoat.java b/src/main/java/net/minecraft/world/entity/vehicle/ChestBoat.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/vehicle/ChestBoat.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/vehicle/ChestBoat.java
|
||||
@@ -0,0 +0,0 @@ public class ChestBoat extends Boat implements HasCustomInventoryScreen, Contain
|
||||
@Override
|
||||
protected void addAdditionalSaveData(CompoundTag nbt) {
|
||||
super.addAdditionalSaveData(nbt);
|
||||
+ this.lootableData.saveNbt(nbt); // Paper
|
||||
this.addChestVehicleSaveData(nbt);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void readAdditionalSaveData(CompoundTag nbt) {
|
||||
super.readAdditionalSaveData(nbt);
|
||||
+ this.lootableData.loadNbt(nbt); // Paper
|
||||
this.readChestVehicleSaveData(nbt);
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/vehicle/ContainerEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/vehicle/ContainerEntity.java
|
||||
@@ -0,0 +0,0 @@ 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());
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ 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());
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ public interface ContainerEntity extends Container, MenuProvider {
|
||||
|
||||
default void unpackChestVehicleLootTable(@Nullable Player player) {
|
||||
MinecraftServer minecraftServer = this.getLevel().getServer();
|
||||
- if (this.getLootTable() != null && minecraftServer != null) {
|
||||
+ if (this.getLootableData().shouldReplenish(player) && minecraftServer != null) { // Paper
|
||||
LootTable lootTable = minecraftServer.getLootTables().get(this.getLootTable());
|
||||
if (player != null) {
|
||||
CriteriaTriggers.GENERATE_LOOT.trigger((ServerPlayer)player, this.getLootTable());
|
||||
}
|
||||
|
||||
- this.setLootTable((ResourceLocation)null);
|
||||
+ // this.setLootTable((ResourceLocation)null); // Paper
|
||||
+ this.getLootableData().processRefill(player); // Paper
|
||||
+
|
||||
LootContext.Builder builder = (new LootContext.Builder((ServerLevel)this.getLevel())).withParameter(LootContextParams.ORIGIN, this.position()).withOptionalRandomSeed(this.getLootTableSeed());
|
||||
if (player != null) {
|
||||
builder.withLuck(player.getLuck()).withParameter(LootContextParams.THIS_ENTITY, player);
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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
|
||||
@@ -0,0 +0,0 @@ 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);
|
||||
@@ -0,0 +0,0 @@ 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 {
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftChest.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftChest.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftLootable.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftLootable.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftChestBoat.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftChestBoat.java
|
||||
@@ -0,0 +0,0 @@ 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) {
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartChest.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartChest.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartHopper.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartHopper.java
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
|
||||
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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -0,0 +0,0 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
||||
// CraftBukkit start
|
||||
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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/Level.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
// 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/BushBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/BushBlock.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/DoublePlantBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/DoublePlantBlock.java
|
||||
@@ -0,0 +0,0 @@ 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,47 +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 global sounds to same world if limiting radius
|
||||
|
||||
Co-authored-by: Evan McCarthy <evanmccarthy@outlook.com>
|
||||
Co-authored-by: lexikiq <noellekiq@gmail.com>
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java
|
||||
@@ -0,0 +0,0 @@ public class EnderDragon extends Mob implements Enemy {
|
||||
// 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) {
|
||||
+ for (net.minecraft.server.level.ServerPlayer player : level.spigotConfig.dragonDeathSoundRadius > 0 ? ((ServerLevel) level).players() : level.getServer().getPlayerList().players) { // Paper
|
||||
double deltaX = this.getX() - player.getX();
|
||||
double deltaZ = this.getZ() - player.getZ();
|
||||
double distanceSquared = deltaX * deltaX + deltaZ * deltaZ;
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java b/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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
|
||||
@@ -0,0 +0,0 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob
|
||||
// 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) {
|
||||
+ for (ServerPlayer player : level.spigotConfig.witherSpawnSoundRadius > 0 ? ((ServerLevel) level).players() : level.getServer().getPlayerList().players) { // Paper
|
||||
double deltaX = this.getX() - player.getX();
|
||||
double deltaZ = this.getZ() - player.getZ();
|
||||
double distanceSquared = deltaX * deltaX + deltaZ * deltaZ;
|
||||
diff --git a/src/main/java/net/minecraft/world/item/EnderEyeItem.java b/src/main/java/net/minecraft/world/item/EnderEyeItem.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/EnderEyeItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/EnderEyeItem.java
|
||||
@@ -0,0 +0,0 @@ public class EnderEyeItem extends Item {
|
||||
// world.b(1038, blockposition1.c(1, 0, 1), 0);
|
||||
int viewDistance = world.getCraftServer().getViewDistance() * 16;
|
||||
BlockPos soundPos = blockposition1.offset(1, 0, 1);
|
||||
- for (ServerPlayer player : world.getServer().getPlayerList().players) {
|
||||
+ for (ServerPlayer player : world.spigotConfig.endPortalSoundRadius > 0 ? ((ServerLevel) world).players() : world.getServer().getPlayerList().players) { // Paper
|
||||
double deltaX = soundPos.getX() - player.getX();
|
||||
double deltaZ = soundPos.getZ() - player.getZ();
|
||||
double distanceSquared = deltaX * deltaX + deltaZ * deltaZ;
|
||||
@@ -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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/util/SimpleBitStorage.java
|
||||
+++ b/src/main/java/net/minecraft/util/SimpleBitStorage.java
|
||||
@@ -0,0 +0,0 @@ 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) {
|
||||
@@ -0,0 +0,0 @@ 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) {
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/util/ZeroBitStorage.java
|
||||
+++ b/src/main/java/net/minecraft/util/ZeroBitStorage.java
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
@@ -0,0 +0,0 @@ public final class ItemStack {
|
||||
}
|
||||
|
||||
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 boolean isItemEnabled(FeatureFlagSet enabledFeatures) {
|
||||
@@ -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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/Level.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
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,133 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Byteflux <byte@byteflux.net>
|
||||
Date: Wed, 2 Mar 2016 11:59:48 -0600
|
||||
Subject: [PATCH] Optimize explosions
|
||||
|
||||
The process of determining an entity's exposure from explosions can be
|
||||
expensive when there are hundreds or more entities in range.
|
||||
|
||||
This patch adds a per-tick cache that is used for storing and retrieving
|
||||
an entity's exposure during an explosion.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
|
||||
this.profiler.pop();
|
||||
this.profiler.pop();
|
||||
+ worldserver.explosionDensityCache.clear(); // Paper - Optimize explosions
|
||||
}
|
||||
|
||||
this.profiler.popPush("connection");
|
||||
diff --git a/src/main/java/net/minecraft/world/level/Explosion.java b/src/main/java/net/minecraft/world/level/Explosion.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/Explosion.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Explosion.java
|
||||
@@ -0,0 +0,0 @@ public class Explosion {
|
||||
d8 /= d11;
|
||||
d9 /= d11;
|
||||
d10 /= d11;
|
||||
- double d12 = (double) Explosion.getSeenPercent(vec3d, entity);
|
||||
+ double d12 = this.getBlockDensity(vec3d, entity); // Paper - Optimize explosions
|
||||
double d13 = (1.0D - d7) * d12;
|
||||
|
||||
// CraftBukkit start
|
||||
@@ -0,0 +0,0 @@ public class Explosion {
|
||||
|
||||
private BlockInteraction() {}
|
||||
}
|
||||
+ // Paper start - Optimize explosions
|
||||
+ private float getBlockDensity(Vec3 vec3d, Entity entity) {
|
||||
+ if (!this.level.paperConfig().environment.optimizeExplosions) {
|
||||
+ return getSeenPercent(vec3d, entity);
|
||||
+ }
|
||||
+ CacheKey key = new CacheKey(this, entity.getBoundingBox());
|
||||
+ Float blockDensity = this.level.explosionDensityCache.get(key);
|
||||
+ if (blockDensity == null) {
|
||||
+ blockDensity = getSeenPercent(vec3d, entity);
|
||||
+ this.level.explosionDensityCache.put(key, blockDensity);
|
||||
+ }
|
||||
+
|
||||
+ return blockDensity;
|
||||
+ }
|
||||
+
|
||||
+ static class CacheKey {
|
||||
+ private final Level world;
|
||||
+ private final double posX, posY, posZ;
|
||||
+ private final double minX, minY, minZ;
|
||||
+ private final double maxX, maxY, maxZ;
|
||||
+
|
||||
+ public CacheKey(Explosion explosion, AABB aabb) {
|
||||
+ this.world = explosion.level;
|
||||
+ this.posX = explosion.x;
|
||||
+ this.posY = explosion.y;
|
||||
+ this.posZ = explosion.z;
|
||||
+ this.minX = aabb.minX;
|
||||
+ this.minY = aabb.minY;
|
||||
+ this.minZ = aabb.minZ;
|
||||
+ this.maxX = aabb.maxX;
|
||||
+ this.maxY = aabb.maxY;
|
||||
+ this.maxZ = aabb.maxZ;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean equals(Object o) {
|
||||
+ if (this == o) return true;
|
||||
+ if (o == null || getClass() != o.getClass()) return false;
|
||||
+
|
||||
+ CacheKey cacheKey = (CacheKey) o;
|
||||
+
|
||||
+ if (Double.compare(cacheKey.posX, posX) != 0) return false;
|
||||
+ if (Double.compare(cacheKey.posY, posY) != 0) return false;
|
||||
+ if (Double.compare(cacheKey.posZ, posZ) != 0) return false;
|
||||
+ if (Double.compare(cacheKey.minX, minX) != 0) return false;
|
||||
+ if (Double.compare(cacheKey.minY, minY) != 0) return false;
|
||||
+ if (Double.compare(cacheKey.minZ, minZ) != 0) return false;
|
||||
+ if (Double.compare(cacheKey.maxX, maxX) != 0) return false;
|
||||
+ if (Double.compare(cacheKey.maxY, maxY) != 0) return false;
|
||||
+ if (Double.compare(cacheKey.maxZ, maxZ) != 0) return false;
|
||||
+ return world.equals(cacheKey.world);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int hashCode() {
|
||||
+ int result;
|
||||
+ long temp;
|
||||
+ result = world.hashCode();
|
||||
+ temp = Double.doubleToLongBits(posX);
|
||||
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
|
||||
+ temp = Double.doubleToLongBits(posY);
|
||||
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
|
||||
+ temp = Double.doubleToLongBits(posZ);
|
||||
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
|
||||
+ temp = Double.doubleToLongBits(minX);
|
||||
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
|
||||
+ temp = Double.doubleToLongBits(minY);
|
||||
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
|
||||
+ temp = Double.doubleToLongBits(minZ);
|
||||
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
|
||||
+ temp = Double.doubleToLongBits(maxX);
|
||||
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
|
||||
+ temp = Double.doubleToLongBits(maxY);
|
||||
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
|
||||
+ temp = Double.doubleToLongBits(maxZ);
|
||||
+ result = 31 * result + (int) (temp ^ (temp >>> 32));
|
||||
+ return result;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/Level.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
private org.spigotmc.TickLimiter entityLimiter;
|
||||
private org.spigotmc.TickLimiter tileLimiter;
|
||||
private int tileTickPosition;
|
||||
+ public final Map<Explosion.CacheKey, Float> explosionDensityCache = new HashMap<>(); // Paper - Optimize explosions
|
||||
|
||||
public CraftWorld getWorld() {
|
||||
return this.world;
|
||||
@@ -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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/core/Vec3i.java
|
||||
+++ b/src/main/java/net/minecraft/core/Vec3i.java
|
||||
@@ -0,0 +0,0 @@ public class Vec3i implements Comparable<Vec3i> {
|
||||
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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/Level.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
}
|
||||
|
||||
public boolean 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/ChunkAccess.java
|
||||
@@ -0,0 +0,0 @@ public abstract class ChunkAccess implements BlockGetter, BiomeManager.NoiseBiom
|
||||
return GameEventListenerRegistry.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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/EmptyLevelChunk.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/EmptyLevelChunk.java
|
||||
@@ -0,0 +0,0 @@ public class EmptyLevelChunk extends LevelChunk {
|
||||
public void setBlockEmptinessMap(final boolean[] emptinessMap) {}
|
||||
// Paper end - starlight
|
||||
|
||||
+ // 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/ImposterProtoChunk.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/ImposterProtoChunk.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java
|
||||
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/ProtoChunk.java
|
||||
@@ -0,0 +0,0 @@ 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,44 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <1254957+zachbr@users.noreply.github.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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/io/papermc/paper/adventure/ChatProcessor.java
|
||||
+++ b/src/main/java/io/papermc/paper/adventure/ChatProcessor.java
|
||||
@@ -0,0 +0,0 @@ import net.minecraft.network.chat.PlayerChatMessage;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
+import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.ConsoleCommandSender;
|
||||
+import org.bukkit.craftbukkit.CraftWorld;
|
||||
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||
import org.bukkit.craftbukkit.util.LazyPlayerSet;
|
||||
import org.bukkit.craftbukkit.util.Waitable;
|
||||
@@ -0,0 +0,0 @@ public final class ChatProcessor {
|
||||
}
|
||||
|
||||
static String legacyDisplayName(final CraftPlayer player) {
|
||||
+ if (((org.bukkit.craftbukkit.CraftWorld) player.getWorld()).getHandle().paperConfig().scoreboards.useVanillaWorldScoreboardNameColoring) {
|
||||
+ return legacySection().serialize(player.teamDisplayName()) + ChatColor.RESET;
|
||||
+ }
|
||||
return player.getDisplayName();
|
||||
}
|
||||
|
||||
static Component displayName(final CraftPlayer player) {
|
||||
+ if (((CraftWorld) player.getWorld()).getHandle().paperConfig().scoreboards.useVanillaWorldScoreboardNameColoring) {
|
||||
+ return player.teamDisplayName();
|
||||
+ }
|
||||
return player.displayName();
|
||||
}
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <1254957+zachbr@users.noreply.github.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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerEntity.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerEntity.java
|
||||
@@ -0,0 +0,0 @@ public class ServerEntity {
|
||||
@Nullable
|
||||
private List<SynchedEntityData.DataValue<?>> trackedDataValues;
|
||||
// CraftBukkit start
|
||||
- private final Set<ServerPlayerConnection> trackedPlayers;
|
||||
+ final Set<ServerPlayerConnection> trackedPlayers; // Paper - private -> package
|
||||
|
||||
public ServerEntity(ServerLevel worldserver, Entity entity, int i, boolean flag, Consumer<Packet<?>> consumer, Set<ServerPlayerConnection> trackedPlayers) {
|
||||
this.trackedPlayers = trackedPlayers;
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java b/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/item/PrimedTnt.java
|
||||
@@ -0,0 +0,0 @@ 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() {
|
||||
@@ -0,0 +0,0 @@ public class PrimedTnt extends Entity {
|
||||
public int getFuse() {
|
||||
return (Integer) this.entityData.get(PrimedTnt.DATA_FUSE_ID);
|
||||
}
|
||||
+
|
||||
+ // Paper start - Optional prevent TNT from moving in water
|
||||
+ @Override
|
||||
+ public boolean isPushedByFluid() {
|
||||
+ return !level.paperConfig().fixes.preventTntFromMovingInWater && super.isPushedByFluid();
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
@@ -1,176 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Techcable <Techcable@outlook.com>
|
||||
Date: Thu, 3 Mar 2016 02:32:10 -0600
|
||||
Subject: [PATCH] Player Tab List and Title APIs
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/network/FriendlyByteBuf.java b/src/main/java/net/minecraft/network/FriendlyByteBuf.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/network/FriendlyByteBuf.java
|
||||
+++ b/src/main/java/net/minecraft/network/FriendlyByteBuf.java
|
||||
@@ -0,0 +0,0 @@ public class FriendlyByteBuf extends ByteBuf {
|
||||
public FriendlyByteBuf writeComponent(final net.kyori.adventure.text.Component component) {
|
||||
return this.writeUtf(PaperAdventure.asJsonString(component, this.adventure$locale), 262144);
|
||||
}
|
||||
+
|
||||
+ @Deprecated
|
||||
+ public FriendlyByteBuf writeComponent(final net.md_5.bungee.api.chat.BaseComponent[] component) {
|
||||
+ return this.writeUtf(net.md_5.bungee.chat.ComponentSerializer.toString(component), 262144);
|
||||
+ }
|
||||
// Paper end
|
||||
|
||||
public FriendlyByteBuf writeComponent(Component text) {
|
||||
diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundSetSubtitleTextPacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundSetSubtitleTextPacket.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/network/protocol/game/ClientboundSetSubtitleTextPacket.java
|
||||
+++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundSetSubtitleTextPacket.java
|
||||
@@ -0,0 +0,0 @@ import net.minecraft.network.protocol.Packet;
|
||||
public class ClientboundSetSubtitleTextPacket 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 ClientboundSetSubtitleTextPacket(Component subtitle) {
|
||||
this.text = subtitle;
|
||||
@@ -0,0 +0,0 @@ public class ClientboundSetSubtitleTextPacket implements Packet<ClientGamePacket
|
||||
// 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/net/minecraft/network/protocol/game/ClientboundSetTitleTextPacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundSetTitleTextPacket.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/network/protocol/game/ClientboundSetTitleTextPacket.java
|
||||
+++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundSetTitleTextPacket.java
|
||||
@@ -0,0 +0,0 @@ import net.minecraft.network.protocol.Packet;
|
||||
public class ClientboundSetTitleTextPacket 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 ClientboundSetTitleTextPacket(Component title) {
|
||||
this.text = title;
|
||||
@@ -0,0 +0,0 @@ public class ClientboundSetTitleTextPacket implements Packet<ClientGamePacketLis
|
||||
// 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
@@ -0,0 +0,0 @@
|
||||
package org.bukkit.craftbukkit.entity;
|
||||
|
||||
+import com.destroystokyo.paper.Title;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.io.BaseEncoding;
|
||||
@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
}
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public void setPlayerListHeaderFooter(BaseComponent[] header, BaseComponent[] footer) {
|
||||
+ if (header != null) {
|
||||
+ String headerJson = net.md_5.bungee.chat.ComponentSerializer.toString(header);
|
||||
+ playerListHeader = net.kyori.adventure.text.serializer.gson.GsonComponentSerializer.gson().deserialize(headerJson);
|
||||
+ } else {
|
||||
+ playerListHeader = null;
|
||||
+ }
|
||||
+
|
||||
+ if (footer != null) {
|
||||
+ String footerJson = net.md_5.bungee.chat.ComponentSerializer.toString(footer);
|
||||
+ playerListFooter = net.kyori.adventure.text.serializer.gson.GsonComponentSerializer.gson().deserialize(footerJson);
|
||||
+ } else {
|
||||
+ playerListFooter = null;
|
||||
+ }
|
||||
+
|
||||
+ updatePlayerListHeaderFooter();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setPlayerListHeaderFooter(BaseComponent header, BaseComponent footer) {
|
||||
+ this.setPlayerListHeaderFooter(header == null ? null : new BaseComponent[]{header},
|
||||
+ footer == null ? null : new BaseComponent[]{footer});
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ @Override
|
||||
+ public void setTitleTimes(int fadeInTicks, int stayTicks, int fadeOutTicks) {
|
||||
+ getHandle().connection.send(new ClientboundSetTitlesAnimationPacket(fadeInTicks, stayTicks, fadeOutTicks));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setSubtitle(BaseComponent[] subtitle) {
|
||||
+ final ClientboundSetSubtitleTextPacket packet = new ClientboundSetSubtitleTextPacket((net.minecraft.network.chat.Component) null);
|
||||
+ packet.components = subtitle;
|
||||
+ getHandle().connection.send(packet);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setSubtitle(BaseComponent subtitle) {
|
||||
+ setSubtitle(new BaseComponent[]{subtitle});
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void showTitle(BaseComponent[] title) {
|
||||
+ final ClientboundSetTitleTextPacket packet = new ClientboundSetTitleTextPacket((net.minecraft.network.chat.Component) null);
|
||||
+ packet.components = title;
|
||||
+ getHandle().connection.send(packet);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void showTitle(BaseComponent title) {
|
||||
+ showTitle(new BaseComponent[]{title});
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void showTitle(BaseComponent[] title, BaseComponent[] subtitle, int fadeInTicks, int stayTicks, int fadeOutTicks) {
|
||||
+ setTitleTimes(fadeInTicks, stayTicks, fadeOutTicks);
|
||||
+ setSubtitle(subtitle);
|
||||
+ showTitle(title);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void showTitle(BaseComponent title, BaseComponent subtitle, int fadeInTicks, int stayTicks, int fadeOutTicks) {
|
||||
+ setTitleTimes(fadeInTicks, stayTicks, fadeOutTicks);
|
||||
+ setSubtitle(subtitle);
|
||||
+ showTitle(title);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void sendTitle(Title title) {
|
||||
+ Preconditions.checkNotNull(title, "Title is null");
|
||||
+ setTitleTimes(title.getFadeIn(), title.getStay(), title.getFadeOut());
|
||||
+ setSubtitle(title.getSubtitle() == null ? new BaseComponent[0] : title.getSubtitle());
|
||||
+ showTitle(title.getTitle());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void updateTitle(Title title) {
|
||||
+ Preconditions.checkNotNull(title, "Title is null");
|
||||
+ setTitleTimes(title.getFadeIn(), title.getStay(), title.getFadeOut());
|
||||
+ if (title.getSubtitle() != null) {
|
||||
+ setSubtitle(title.getSubtitle());
|
||||
+ }
|
||||
+ showTitle(title.getTitle());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void hideTitle() {
|
||||
+ getHandle().connection.send(new ClientboundClearTitlesPacket(false));
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
if(true) return io.papermc.paper.adventure.DisplayNames.getLegacy(this); // Paper
|
||||
@@ -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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java
|
||||
@@ -0,0 +0,0 @@ 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 {
|
||||
|
||||
@@ -0,0 +0,0 @@ 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,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/item/ItemEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/item/ItemEntity.java
|
||||
@@ -0,0 +0,0 @@ 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);
|
||||
@@ -0,0 +0,0 @@ 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;
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ 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);
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user