Files
2022-04-27 00:57:01 +08:00

1012 lines
44 KiB
Diff

--- ../src-base/minecraft/net/minecraft/entity/player/EntityPlayerMP.java
+++ ../src-work/minecraft/net/minecraft/entity/player/EntityPlayerMP.java
@@ -1,5 +1,7 @@
package net.minecraft.entity.player;
+import catserver.server.asm.ASMFixer;
+import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.mojang.authlib.GameProfile;
import io.netty.buffer.Unpooled;
@@ -13,10 +15,10 @@
import net.minecraft.block.BlockFence;
import net.minecraft.block.BlockFenceGate;
import net.minecraft.block.BlockWall;
-import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.crash.CrashReport;
import net.minecraft.crash.CrashReportCategory;
+import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityList;
import net.minecraft.entity.EntityLivingBase;
@@ -72,6 +74,7 @@
import net.minecraft.scoreboard.Score;
import net.minecraft.scoreboard.ScoreObjective;
import net.minecraft.scoreboard.ScorePlayerTeam;
+import net.minecraft.scoreboard.Scoreboard;
import net.minecraft.scoreboard.Team;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.management.PlayerInteractionManager;
@@ -83,12 +86,14 @@
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityCommandBlock;
import net.minecraft.tileentity.TileEntitySign;
+import net.minecraft.util.CombatTracker;
import net.minecraft.util.CooldownTracker;
import net.minecraft.util.CooldownTrackerServer;
import net.minecraft.util.DamageSource;
import net.minecraft.util.EntityDamageSource;
import net.minecraft.util.EnumHand;
import net.minecraft.util.EnumHandSide;
+import net.minecraft.util.FoodStats;
import net.minecraft.util.NonNullList;
import net.minecraft.util.ReportedException;
import net.minecraft.util.ResourceLocation;
@@ -109,21 +114,36 @@
import net.minecraft.world.GameType;
import net.minecraft.world.IInteractionObject;
import net.minecraft.world.ILockableContainer;
+import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
import net.minecraft.world.storage.loot.ILootContainer;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
+import org.bukkit.Bukkit;
+import org.bukkit.GameMode;
+import org.bukkit.WeatherType;
+import org.bukkit.craftbukkit.CraftWorld;
+import org.bukkit.craftbukkit.entity.CraftPlayer;
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+import org.bukkit.craftbukkit.inventory.CraftItemStack;
+import org.bukkit.event.inventory.InventoryType;
+import org.bukkit.event.player.PlayerChangedMainHandEvent;
+import org.bukkit.event.player.PlayerGameModeChangeEvent;
+import org.bukkit.event.player.PlayerLocaleChangeEvent;
+import org.bukkit.event.player.PlayerTeleportEvent;
+import org.bukkit.inventory.InventoryView;
+import org.bukkit.inventory.MainHand;
-public class EntityPlayerMP extends EntityPlayer implements IContainerListener
+public class EntityPlayerMP extends EntityPlayer implements IContainerListener, ASMFixer.IEntityPlayerMPASMFixer
{
private static final Logger LOGGER = LogManager.getLogger();
- private String language = "en_US";
+ public String language = "en_us"; // CraftBukkit - lowercase
public NetHandlerPlayServer connection;
public final MinecraftServer mcServer;
public final PlayerInteractionManager interactionManager;
public double managedPosX;
public double managedPosZ;
- private final List<Integer> entityRemoveQueue = Lists.<Integer>newLinkedList();
+ public final List<Integer> entityRemoveQueue = Lists.<Integer>newLinkedList();
private final PlayerAdvancements advancements;
private final StatisticsManagerServer statsFile;
private float lastHealthScore = Float.MIN_VALUE;
@@ -135,13 +155,13 @@
private float lastHealth = -1.0E8F;
private int lastFoodLevel = -99999999;
private boolean wasHungry = true;
- private int lastExperience = -99999999;
- private int respawnInvulnerabilityTicks = 60;
- private EntityPlayer.EnumChatVisibility chatVisibility;
+ public int lastExperience = -99999999;
+ public int respawnInvulnerabilityTicks = 60;
+ private EnumChatVisibility chatVisibility;
private boolean chatColours = true;
private long playerLastActiveTime = System.currentTimeMillis();
private Entity spectatingEntity;
- private boolean invulnerableDimensionChange;
+ public boolean invulnerableDimensionChange;
private boolean seenCredits;
private final RecipeBookServer recipeBook = new RecipeBookServer();
private Vec3d levitationStartPos;
@@ -153,14 +173,25 @@
public int ping;
public boolean queuedEndExit;
+ public String displayName;
+ public ITextComponent listName;
+ public org.bukkit.Location compassTarget;
+ public int newExp = 0;
+ public int newLevel = 0;
+ public int newTotalExp = 0;
+ public boolean keepLevel = false;
+ public double maxHealthCache;
+ public boolean joining = true;
+ public boolean sentListPacket = false;
+
public EntityPlayerMP(MinecraftServer server, WorldServer worldIn, GameProfile profile, PlayerInteractionManager interactionManagerIn)
{
super(worldIn, profile);
interactionManagerIn.player = this;
this.interactionManager = interactionManagerIn;
- BlockPos blockpos = worldIn.getSpawnPoint();
+ BlockPos blockpos = worldIn.provider.getRandomizedSpawnPoint();
- if (worldIn.provider.hasSkyLight() && worldIn.getWorldInfo().getGameType() != GameType.ADVENTURE)
+ if (false && worldIn.provider.hasSkyLight() && worldIn.getWorldInfo().getGameType() != GameType.ADVENTURE)
{
int i = Math.max(0, server.getSpawnRadius(worldIn));
int j = MathHelper.floor(worldIn.getWorldBorder().getClosestDistance((double)blockpos.getX(), (double)blockpos.getZ()));
@@ -188,8 +219,33 @@
{
this.setPosition(this.posX, this.posY + 1.0D, this.posZ);
}
+
+ this.displayName = this.getName();
+ this.canPickUpLoot = true;
+ this.maxHealthCache = this.getMaxHealth();
}
+ public final BlockPos getSpawnPoint(MinecraftServer minecraftserver, WorldServer worldserver) {
+ BlockPos blockposition = worldserver.getSpawnPoint();
+
+ if (worldserver.provider.hasSkyLight() && worldserver.getWorldInfo().getGameType() != GameType.ADVENTURE) {
+ int i = Math.max(0, minecraftserver.getSpawnRadius(worldserver));
+ int j = MathHelper.floor(worldserver.getWorldBorder().getClosestDistance((double) blockposition.getX(), (double) blockposition.getZ()));
+
+ if (j < i) {
+ i = j;
+ }
+
+ if (j <= 1) {
+ i = 1;
+ }
+
+ blockposition = worldserver.getTopSolidOrLiquidBlock(blockposition.add(this.rand.nextInt(i * 2 + 1) - i, 0, this.rand.nextInt(i * 2 + 1) - i));
+ }
+
+ return blockposition;
+ }
+
public void readEntityFromNBT(NBTTagCompound compound)
{
super.readEntityFromNBT(compound);
@@ -218,6 +274,7 @@
{
this.recipeBook.read(compound.getCompoundTag("recipeBook"));
}
+ this.getBukkitEntity().readExtraData(compound);
}
public static void registerFixesPlayerMP(DataFixer p_191522_0_)
@@ -270,8 +327,34 @@
}
compound.setTag("recipeBook", this.recipeBook.write());
+ this.getBukkitEntity().setExtraData(compound);
}
+ // CraftBukkit start - World fallback code, either respawn location or global spawn
+ public void setWorld(World world) {
+ super.setWorld(world);
+ if (world == null) {
+ this.dead = false;
+ BlockPos position = null;
+ if (this.spawnWorld != null && !this.spawnWorld.equals("")) {
+ CraftWorld cworld = (CraftWorld) Bukkit.getServer().getWorld(this.spawnWorld);
+ if (cworld != null && this.getBedLocation() != null) {
+ world = cworld.getHandle();
+ position = EntityPlayer.getBedSpawnLocation(cworld.getHandle(), this.getBedLocation(), false);
+ }
+ }
+ if (world == null || position == null) {
+ world = ((CraftWorld) Bukkit.getServer().getWorlds().get(0)).getHandle();
+ position = world.getSpawnPoint();
+ }
+ this.world = world;
+ this.setPosition(position.getX() + 0.5, position.getY(), position.getZ() + 0.5);
+ }
+ this.dimension = ((WorldServer) this.world).dimension;
+ this.interactionManager.setWorld((WorldServer) world);
+ }
+ // CraftBukkit end
+
public void addExperienceLevel(int levels)
{
super.addExperienceLevel(levels);
@@ -313,6 +396,9 @@
public void onUpdate()
{
+ if (this.joining) {
+ this.joining = false;
+ }
this.interactionManager.updateBlockRemoving();
--this.respawnInvulnerabilityTicks;
@@ -323,7 +409,7 @@
this.openContainer.detectAndSendChanges();
- if (!this.world.isRemote && !this.openContainer.canInteractWith(this))
+ if (!this.world.isRemote && this.openContainer != null && !this.openContainer.canInteractWith(this))
{
this.closeScreen();
this.openContainer = this.inventoryContainer;
@@ -398,7 +484,7 @@
if (this.getHealth() != this.lastHealth || this.lastFoodLevel != this.foodStats.getFoodLevel() || this.foodStats.getSaturationLevel() == 0.0F != this.wasHungry)
{
- this.connection.sendPacket(new SPacketUpdateHealth(this.getHealth(), this.foodStats.getFoodLevel(), this.foodStats.getSaturationLevel()));
+ this.connection.sendPacket(new SPacketUpdateHealth(this.getBukkitEntity().getScaledHealth(), this.foodStats.getFoodLevel(), this.foodStats.getSaturationLevel()));
this.lastHealth = this.getHealth();
this.lastFoodLevel = this.foodStats.getFoodLevel();
this.wasHungry = this.foodStats.getSaturationLevel() == 0.0F;
@@ -422,6 +508,12 @@
this.updateScorePoints(IScoreCriteria.AIR, MathHelper.ceil((float)this.lastAirScore));
}
+ // CraftBukkit start - Force max health updates
+ if (this.maxHealthCache != this.getMaxHealth()) {
+ this.getBukkitEntity().updateScaledHealth();
+ }
+ // CraftBukkit end
+
if (this.getTotalArmorValue() != this.lastArmorScore)
{
this.lastArmorScore = this.getTotalArmorValue();
@@ -450,6 +542,16 @@
{
CriteriaTriggers.LOCATION.trigger(this);
}
+ // CraftBukkit start - initialize oldLevel and fire PlayerLevelChangeEvent
+ if (this.oldLevel == -1) {
+ this.oldLevel = this.experienceLevel;
+ }
+
+ if (this.oldLevel != this.experienceLevel) {
+ CraftEventFactory.callPlayerLevelChangeEvent(this.world.getServer().getPlayer(this), this.oldLevel, this.experienceLevel);
+ this.oldLevel = this.experienceLevel;
+ }
+ // CraftBukkit end
}
catch (Throwable throwable)
{
@@ -462,50 +564,91 @@
private void updateScorePoints(IScoreCriteria criteria, int points)
{
- for (ScoreObjective scoreobjective : this.getWorldScoreboard().getObjectivesFromCriteria(criteria))
+ for (Score score : this.world.getServer().getScoreboardManager().getScoreboardScores(criteria, this.getName(), new java.util.ArrayList<Score>())) // CraftBukkit - Use our scores instead
{
- Score score = this.getWorldScoreboard().getOrCreateScore(this.getName(), scoreobjective);
+ // Score score = this.getWorldScoreboard().getOrCreateScore(this.getName(), scoreobjective);
score.setScorePoints(points);
}
}
public void onDeath(DamageSource cause)
{
+ if (net.minecraftforge.common.ForgeHooks.onLivingDeath(this, cause)) return;
boolean flag = this.world.getGameRules().getBoolean("showDeathMessages");
this.connection.sendPacket(new SPacketCombatEvent(this.getCombatTracker(), SPacketCombatEvent.Event.ENTITY_DIED, flag));
+ if (this.dead) {
+ return;
+ }
+ java.util.List<org.bukkit.inventory.ItemStack> loot = new java.util.ArrayList<>(this.inventory.getSizeInventory());
+ boolean keepInventory = this.world.getGameRules().getBoolean("keepInventory") || this.isSpectator();
- if (flag)
- {
- Team team = this.getTeam();
+ if (!keepInventory) {
+ for (ItemStack item : this.inventory.getContents()) {
+ if (!item.isEmpty() && !EnchantmentHelper.hasVanishingCurse(item)) {
+ loot.add(CraftItemStack.asCraftMirror(item));
+ }
+ }
+ }
- if (team != null && team.getDeathMessageVisibility() != Team.EnumVisible.ALWAYS)
- {
- if (team.getDeathMessageVisibility() == Team.EnumVisible.HIDE_FOR_OTHER_TEAMS)
- {
- this.mcServer.getPlayerList().sendMessageToAllTeamMembers(this, this.getCombatTracker().getDeathMessage());
+ ITextComponent chatmessage = this.getCombatTracker().getDeathMessage();
+
+ String deathmessage = chatmessage.getFormattedText();
+ // CatServer start - handle drop items in Bukkit
+ captureDrops = true;
+ org.bukkit.event.entity.PlayerDeathEvent deathEvent = CraftEventFactory.callPlayerDeathEvent(this, loot,
+ this.getCombatTracker().getDeathMessage().getFormattedText(),
+ this.world.getGameRules().getBoolean("keepInventory"));
+ captureDrops = false;
+ // CatServer end
+ String deathMessage = deathEvent.getDeathMessage();
+
+ if (deathMessage != null && deathMessage.length() > 0 && flag) { // TODO: allow plugins to override?
+ if (deathMessage.equals(deathmessage)) {
+ Team scoreboardteambase = this.getTeam();
+
+ if (scoreboardteambase != null && scoreboardteambase.getDeathMessageVisibility() != Team.EnumVisible.ALWAYS) {
+ if (scoreboardteambase.getDeathMessageVisibility() == Team.EnumVisible.HIDE_FOR_OTHER_TEAMS) {
+ this.mcServer.getPlayerList().sendMessageToAllTeamMembers(this, chatmessage);
+ } else if (scoreboardteambase.getDeathMessageVisibility() == Team.EnumVisible.HIDE_FOR_OWN_TEAM) {
+ this.mcServer.getPlayerList().sendMessageToTeamOrAllPlayers(this, chatmessage);
+ }
+ } else {
+ this.mcServer.getPlayerList().sendMessage(chatmessage);
}
- else if (team.getDeathMessageVisibility() == Team.EnumVisible.HIDE_FOR_OWN_TEAM)
- {
- this.mcServer.getPlayerList().sendMessageToTeamOrAllPlayers(this, this.getCombatTracker().getDeathMessage());
- }
}
else
{
- this.mcServer.getPlayerList().sendMessage(this.getCombatTracker().getDeathMessage());
+ // this.mcServer.getPlayerList().sendMessage(this.getCombatTracker().getDeathMessage());
+ this.mcServer.getPlayerList().sendMessage(org.bukkit.craftbukkit.util.CraftChatMessage.fromString(deathMessage));
}
}
this.spawnShoulderEntities();
+ // we clean the player's inventory after the EntityDeathEvent is called so plugins can get the exact state of the inventory.
+ if (!deathEvent.getKeepInventory()) {
+ this.inventory.clear();
+ }
if (!this.world.getGameRules().getBoolean("keepInventory") && !this.isSpectator())
{
- this.destroyVanishingCursedItems();
- this.inventory.dropAllItems();
+ net.minecraftforge.event.entity.player.PlayerDropsEvent event = new net.minecraftforge.event.entity.player.PlayerDropsEvent(this, cause, capturedDrops, recentlyHit > 0);
+ if (!net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(event))
+ {
+ for (net.minecraft.entity.item.EntityItem item : capturedDrops)
+ {
+ this.world.spawnEntity(item);
+ }
+ }
}
- for (ScoreObjective scoreobjective : this.world.getScoreboard().getObjectivesFromCriteria(IScoreCriteria.DEATH_COUNT))
+ this.closeScreen();
+ this.setSpectatingEntity(this); // Remove spectated target
+
+ // CraftBukkit - Get our scores instead
+ Collection<Score> collection = this.world.getServer().getScoreboardManager().getScoreboardScores(IScoreCriteria.DEATH_COUNT, this.getName(), new java.util.ArrayList<Score>());
+ for (Score score : collection)
{
- Score score = this.getWorldScoreboard().getOrCreateScore(this.getName(), scoreobjective);
+ // Score score = this.getWorldScoreboard().getOrCreateScore(this.getName(), scoreobjective);
score.incrementScore();
}
@@ -536,23 +679,28 @@
{
super.awardKillScore(p_191956_1_, p_191956_2_, p_191956_3_);
this.addScore(p_191956_2_);
- Collection<ScoreObjective> collection = this.getWorldScoreboard().getObjectivesFromCriteria(IScoreCriteria.TOTAL_KILL_COUNT);
-
+ // CraftBukkit - Get our scores instead
+ // Collection<ScoreObjective> collection = this.getWorldScoreboard().getObjectivesFromCriteria(IScoreCriteria.TOTAL_KILL_COUNT);
+ Collection<Score> collection = this.world.getServer().getScoreboardManager().getScoreboardScores(IScoreCriteria.TOTAL_KILL_COUNT, this.getName(), new java.util.ArrayList<Score>());
if (p_191956_1_ instanceof EntityPlayer)
{
this.addStat(StatList.PLAYER_KILLS);
- collection.addAll(this.getWorldScoreboard().getObjectivesFromCriteria(IScoreCriteria.PLAYER_KILL_COUNT));
+ // CraftBukkit - Get our scores instead
+ // collection.addAll(this.getWorldScoreboard().getObjectivesFromCriteria(IScoreCriteria.PLAYER_KILL_COUNT));
+ this.world.getServer().getScoreboardManager().getScoreboardScores(IScoreCriteria.PLAYER_KILL_COUNT, this.getName(), collection);
+ // CraftBukkit end
}
else
{
this.addStat(StatList.MOB_KILLS);
}
- collection.addAll(this.awardTeamKillScores(p_191956_1_));
+ collection.addAll(this.awardTeamKillScores_CB(p_191956_1_));
- for (ScoreObjective scoreobjective : collection)
+ for (Score score : collection)
{
- this.getWorldScoreboard().getOrCreateScore(this.getName(), scoreobjective).incrementScore();
+ // this.getWorldScoreboard().getOrCreateScore(this.getName(), scoreobjective).incrementScore();
+ score.incrementScore();
}
CriteriaTriggers.PLAYER_KILLED_ENTITY.trigger(this, p_191956_1_, p_191956_3_);
@@ -593,6 +741,43 @@
return Lists.<ScoreObjective>newArrayList();
}
+ private Collection<Score> awardTeamKillScores_CB(Entity p_192038_1_)
+ {
+ String s = p_192038_1_ instanceof EntityPlayer ? p_192038_1_.getName() : p_192038_1_.getCachedUniqueIdString();
+ ScorePlayerTeam scoreplayerteam = this.getWorldScoreboard().getPlayersTeam(this.getName());
+
+ if (scoreplayerteam != null)
+ {
+ int i = scoreplayerteam.getColor().getColorIndex();
+
+ if (i >= 0 && i < IScoreCriteria.KILLED_BY_TEAM.length)
+ {
+ for (ScoreObjective scoreobjective : this.getWorldScoreboard().getObjectivesFromCriteria(IScoreCriteria.KILLED_BY_TEAM[i]))
+ {
+ Score score = this.getWorldScoreboard().getOrCreateScore(s, scoreobjective);
+ score.incrementScore();
+ }
+ }
+ }
+
+ ScorePlayerTeam scoreplayerteam1 = this.getWorldScoreboard().getPlayersTeam(s);
+
+ if (scoreplayerteam1 != null)
+ {
+ int j = scoreplayerteam1.getColor().getColorIndex();
+
+ if (j >= 0 && j < IScoreCriteria.TEAM_KILL.length)
+ {
+ // CraftBukkit - Get our scores instead
+ // return this.getWorldScoreboard().getObjectivesFromCriteria(IScoreCriteria.TEAM_KILL[j]);
+ return this.world.getServer().getScoreboardManager().getScoreboardScores(IScoreCriteria.TEAM_KILL[j], this.getName(), new java.util.ArrayList<Score>());
+ // CraftBukkit end
+ }
+ }
+
+ return Lists.<Score>newArrayList();
+ }
+
public boolean attackEntityFrom(DamageSource source, float amount)
{
if (this.isEntityInvulnerable(source))
@@ -641,13 +826,17 @@
private boolean canPlayersAttack()
{
- return this.mcServer.isPVPEnabled();
+ // CraftBukkit - this.mcServer.isPVPEnabled() -> this.world.pvpMode
+ // return this.mcServer.isPVPEnabled();
+ return this.world.pvpMode;
}
@Nullable
- public Entity changeDimension(int dimensionIn)
+ public Entity changeDimension(int dimensionIn, net.minecraftforge.common.util.ITeleporter teleporter)
{
- this.invulnerableDimensionChange = true;
+ if (!net.minecraftforge.common.ForgeHooks.onTravelToDimension(this, dimensionIn)) return this;
+ if (this.isPlayerSleeping()) return this; // CraftBukkit - SPIGOT-3154
+ // this.invulnerableDimensionChange = true; // CraftBukkit - Moved down and into PlayerList#changeDimension
if (this.dimension == 0 && dimensionIn == -1)
{
@@ -658,8 +847,9 @@
this.enteredNetherPosition = null;
}
- if (this.dimension == 1 && dimensionIn == 1)
+ if (this.dimension == 1 && dimensionIn == 1 && teleporter.isVanilla())
{
+ this.invulnerableDimensionChange = true; // CraftBukkit - Moved down from above
this.world.removeEntity(this);
if (!this.queuedEndExit)
@@ -678,7 +868,11 @@
dimensionIn = 1;
}
- this.mcServer.getPlayerList().changePlayerDimension(this, dimensionIn);
+ // this.mcServer.getPlayerList().transferPlayerToDimension(this, dimensionIn, teleporter);
+ // CatServer start
+ PlayerTeleportEvent.TeleportCause cause = (this.dimension == 1 || dimensionIn == 1) ? PlayerTeleportEvent.TeleportCause.END_PORTAL : ((this.dimension == -1 || dimensionIn == -1) ? PlayerTeleportEvent.TeleportCause.NETHER_PORTAL : PlayerTeleportEvent.TeleportCause.MOD);
+ this.mcServer.getPlayerList().transferPlayerToDimension(this, dimensionIn, teleporter, cause);
+ // CatServer end
this.connection.sendPacket(new SPacketEffect(1032, BlockPos.ORIGIN, 0, false));
this.lastExperience = -1;
this.lastHealth = -1.0F;
@@ -718,11 +912,11 @@
this.openContainer.detectAndSendChanges();
}
- public EntityPlayer.SleepResult trySleep(BlockPos bedLocation)
+ public SleepResult trySleep(BlockPos bedLocation)
{
- EntityPlayer.SleepResult entityplayer$sleepresult = super.trySleep(bedLocation);
+ SleepResult entityplayer$sleepresult = super.trySleep(bedLocation);
- if (entityplayer$sleepresult == EntityPlayer.SleepResult.OK)
+ if (entityplayer$sleepresult == SleepResult.OK)
{
this.addStat(StatList.SLEEP_IN_BED);
Packet<?> packet = new SPacketUseBed(this, bedLocation);
@@ -737,6 +931,7 @@
public void wakeUpPlayer(boolean immediately, boolean updateWorldFlag, boolean setSpawn)
{
+ if (!this.sleeping) return; // CraftBukkit - Can't leave bed if not in one!
if (this.isPlayerSleeping())
{
this.getServerWorld().getEntityTracker().sendToTrackingAndSelf(this, new SPacketAnimation(this, 2));
@@ -808,7 +1003,7 @@
BlockPos blockpos = new BlockPos(i, j, k);
IBlockState iblockstate = this.world.getBlockState(blockpos);
- if (iblockstate.getMaterial() == Material.AIR)
+ if (iblockstate.getBlock().isAir(iblockstate, this.world, blockpos))
{
BlockPos blockpos1 = blockpos.down();
IBlockState iblockstate1 = this.world.getBlockState(blockpos1);
@@ -830,6 +1025,12 @@
this.connection.sendPacket(new SPacketSignEditorOpen(signTile.getPos()));
}
+ public int getNextWindowIdCB() // CraftBukkit - void -> int
+ {
+ this.currentWindowId = this.currentWindowId % 100 + 1;
+ return this.currentWindowId;
+ }
+
public void getNextWindowId()
{
this.currentWindowId = this.currentWindowId % 100 + 1;
@@ -837,22 +1038,53 @@
public void displayGui(IInteractionObject guiOwner)
{
- if (guiOwner instanceof ILootContainer && ((ILootContainer)guiOwner).getLootTable() != null && this.isSpectator())
+ // CraftBukkit start - Inventory open hook
+ if (false && guiOwner instanceof ILootContainer && ((ILootContainer)guiOwner).getLootTable() != null && this.isSpectator())
{
this.sendStatusMessage((new TextComponentTranslation("container.spectatorCantOpen", new Object[0])).setStyle((new Style()).setColor(TextFormatting.RED)), true);
}
else
{
+ boolean cancelled = guiOwner instanceof ILootContainer && ((ILootContainer) guiOwner).getLootTable() != null && this.isSpectator();
+ Container container = CraftEventFactory.callInventoryOpenEvent(this, guiOwner.createContainer(this.inventory, this), cancelled);
+ if (container == null) {
+ return;
+ }
this.getNextWindowId();
+ this.openContainer = container;
this.connection.sendPacket(new SPacketOpenWindow(this.currentWindowId, guiOwner.getGuiID(), guiOwner.getDisplayName()));
- this.openContainer = guiOwner.createContainer(this.inventory, this);
+ // this.openContainer = guiOwner.createContainer(this.inventory, this);
this.openContainer.windowId = this.currentWindowId;
this.openContainer.addListener(this);
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.player.PlayerContainerEvent.Open(this, this.openContainer));
}
}
public void displayGUIChest(IInventory chestInventory)
{
+ // CraftBukkit start - Inventory open hook
+ // Copied from below
+ boolean cancelled = false;
+ if (chestInventory instanceof ILockableContainer) {
+ ILockableContainer itileinventory = (ILockableContainer) chestInventory;
+ cancelled = itileinventory.isLocked() && !this.canOpen(itileinventory.getLockCode()) && !this.isSpectator();
+ }
+
+ Container container;
+ if (chestInventory instanceof IInteractionObject) {
+ if (chestInventory instanceof TileEntity) {
+ Preconditions.checkArgument(((TileEntity) chestInventory).getWorld() != null, "Container must have world to be opened");
+ }
+ container = ((IInteractionObject) chestInventory).createContainer(this.inventory, this);
+ } else {
+ container = new ContainerChest(this.inventory, chestInventory, this);
+ }
+ container = CraftEventFactory.callInventoryOpenEvent(this, container, cancelled);
+ if (container == null && !cancelled) { // Let pre-cancelled events fall through
+ chestInventory.closeInventory(this);
+ return;
+ }
+ // CraftBukkit end
if (chestInventory instanceof ILootContainer && ((ILootContainer)chestInventory).getLootTable() != null && this.isSpectator())
{
this.sendStatusMessage((new TextComponentTranslation("container.spectatorCantOpen", new Object[0])).setStyle((new Style()).setColor(TextFormatting.RED)), true);
@@ -872,6 +1104,7 @@
{
this.connection.sendPacket(new SPacketChat(new TextComponentTranslation("container.isLocked", new Object[] {chestInventory.getDisplayName()}), ChatType.GAME_INFO));
this.connection.sendPacket(new SPacketSoundEffect(SoundEvents.BLOCK_CHEST_LOCKED, SoundCategory.BLOCKS, this.posX, this.posY, this.posZ, 1.0F, 1.0F));
+ ilockablecontainer.closeInventory(this);
return;
}
}
@@ -881,25 +1114,36 @@
if (chestInventory instanceof IInteractionObject)
{
this.connection.sendPacket(new SPacketOpenWindow(this.currentWindowId, ((IInteractionObject)chestInventory).getGuiID(), chestInventory.getDisplayName(), chestInventory.getSizeInventory()));
- this.openContainer = ((IInteractionObject)chestInventory).createContainer(this.inventory, this);
+ // this.openContainer = ((IInteractionObject)chestInventory).createContainer(this.inventory, this);
+ this.openContainer = container;
}
else
{
this.connection.sendPacket(new SPacketOpenWindow(this.currentWindowId, "minecraft:container", chestInventory.getDisplayName(), chestInventory.getSizeInventory()));
- this.openContainer = new ContainerChest(this.inventory, chestInventory, this);
+ // this.openContainer = new ContainerChest(this.inventory, chestInventory, this);
+ this.openContainer = container;
}
this.openContainer.windowId = this.currentWindowId;
this.openContainer.addListener(this);
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.player.PlayerContainerEvent.Open(this, this.openContainer));
}
}
public void displayVillagerTradeGui(IMerchant villager)
{
+ // CraftBukkit start - Inventory open hook
+ Container container = CraftEventFactory.callInventoryOpenEvent(this, new ContainerMerchant(this.inventory, villager, this.world));
+ if (container == null) {
+ return;
+ }
+ // CraftBukkit end
this.getNextWindowId();
- this.openContainer = new ContainerMerchant(this.inventory, villager, this.world);
+ // this.openContainer = new ContainerMerchant(this.inventory, villager, this.world);
+ this.openContainer = container;
this.openContainer.windowId = this.currentWindowId;
this.openContainer.addListener(this);
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.player.PlayerContainerEvent.Open(this, this.openContainer));
IInventory iinventory = ((ContainerMerchant)this.openContainer).getMerchantInventory();
ITextComponent itextcomponent = villager.getDisplayName();
this.connection.sendPacket(new SPacketOpenWindow(this.currentWindowId, "minecraft:villager", itextcomponent, iinventory.getSizeInventory()));
@@ -916,6 +1160,13 @@
public void openGuiHorseInventory(AbstractHorse horse, IInventory inventoryIn)
{
+ // CraftBukkit start - Inventory open hook
+ Container container = CraftEventFactory.callInventoryOpenEvent(this, new ContainerHorseInventory(this.inventory, inventoryIn, horse, this));
+ if (container == null) {
+ inventoryIn.closeInventory(this);
+ return;
+ }
+ // CraftBukkit end
if (this.openContainer != this.inventoryContainer)
{
this.closeScreen();
@@ -923,7 +1174,8 @@
this.getNextWindowId();
this.connection.sendPacket(new SPacketOpenWindow(this.currentWindowId, "EntityHorse", inventoryIn.getDisplayName(), inventoryIn.getSizeInventory(), horse.getEntityId()));
- this.openContainer = new ContainerHorseInventory(this.inventory, inventoryIn, horse, this);
+ // this.openContainer = new ContainerHorseInventory(this.inventory, inventoryIn, horse, this);
+ this.openContainer = container;
this.openContainer.windowId = this.currentWindowId;
this.openContainer.addListener(this);
}
@@ -971,6 +1223,12 @@
{
this.connection.sendPacket(new SPacketWindowItems(containerToSend.windowId, itemsList));
this.connection.sendPacket(new SPacketSetSlot(-1, -1, this.inventory.getItemStack()));
+ // CraftBukkit start - Send a Set Slot to update the crafting result slot
+ InventoryView bukkitView = containerToSend.getBukkitView();
+ if (bukkitView != null && java.util.EnumSet.of(InventoryType.CRAFTING,InventoryType.WORKBENCH).contains(bukkitView.getType())) { // CatServer - mods bypass
+ this.connection.sendPacket(new SPacketSetSlot(containerToSend.windowId, 0, containerToSend.getSlot(0).getStack()));
+ }
+ // CraftBukkit end
}
public void sendWindowProperty(Container containerIn, int varToUpdate, int newValue)
@@ -988,6 +1246,7 @@
public void closeScreen()
{
+ CraftEventFactory.handleInventoryCloseEvent(this); // CraftBukkit
this.connection.sendPacket(new SPacketCloseWindow(this.openContainer.windowId));
this.closeContainer();
}
@@ -1003,6 +1262,7 @@
public void closeContainer()
{
this.openContainer.onContainerClosed(this);
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.player.PlayerContainerEvent.Close(this, this.openContainer));
this.openContainer = this.inventoryContainer;
}
@@ -1062,6 +1322,10 @@
for (ResourceLocation resourcelocation : p_193102_1_)
{
+ if (CraftingManager.getRecipe(resourcelocation) == null) {
+ Bukkit.getLogger().warning("Ignoring grant of non existent recipe " + resourcelocation);
+ continue;
+ }
list.add(CraftingManager.getRecipe(resourcelocation));
}
@@ -1092,8 +1356,16 @@
public void setPlayerHealthUpdated()
{
this.lastHealth = -1.0E8F;
+ this.lastExperience = -1; // CraftBukkit - Added to reset
}
+ // CraftBukkit start - Support multi-line messages
+ public void sendMessage(ITextComponent[] ichatbasecomponent) {
+ for (ITextComponent component : ichatbasecomponent) {
+ this.sendMessage(component);
+ }
+ }
+
public void sendStatusMessage(ITextComponent chatComponent, boolean actionBar)
{
this.connection.sendPacket(new SPacketChat(chatComponent, actionBar ? ChatType.GAME_INFO : ChatType.CHAT));
@@ -1138,12 +1410,30 @@
this.lastExperience = -1;
this.lastHealth = -1.0F;
this.lastFoodLevel = -1;
- this.recipeBook.copyFrom(that.recipeBook);
+ // this.recipeBook.copyFrom(that.recipeBook); // CraftBukkit
this.entityRemoveQueue.addAll(that.entityRemoveQueue);
this.seenCredits = that.seenCredits;
this.enteredNetherPosition = that.enteredNetherPosition;
this.setLeftShoulderEntity(that.getLeftShoulderEntity());
this.setRightShoulderEntity(that.getRightShoulderEntity());
+
+ this.spawnChunkMap = that.spawnChunkMap;
+ this.spawnForcedMap = that.spawnForcedMap;
+ if(that.dimension != 0)
+ {
+ this.spawnPos = that.spawnPos;
+ this.spawnForced = that.spawnForced;
+ }
+
+
+ //Copy over a section of the Entity Data from the old player.
+ //Allows mods to specify data that persists after players respawn.
+ NBTTagCompound old = that.getEntityData();
+ if (old.hasKey(PERSISTED_NBT_TAG))
+ {
+ getEntityData().setTag(PERSISTED_NBT_TAG, old.getCompoundTag(PERSISTED_NBT_TAG));
+ }
+ net.minecraftforge.event.ForgeEventFactory.onPlayerClone(this, that, !keepEverything);
}
protected void onNewPotionEffect(PotionEffect id)
@@ -1211,6 +1501,15 @@
public void setGameType(GameType gameType)
{
+ if (gameType == this.interactionManager.getGameType()) {
+ return;
+ }
+
+ PlayerGameModeChangeEvent event = new PlayerGameModeChangeEvent(getBukkitEntity(), GameMode.getByValue(gameType.getID()));
+ world.getServer().getPluginManager().callEvent(event);
+ if (event.isCancelled()) {
+ return;
+ }
this.interactionManager.setGameType(gameType);
this.connection.sendPacket(new SPacketChangeGameState(3, (float)gameType.getID()));
@@ -1245,6 +1544,7 @@
public boolean canUseCommand(int permLevel, String commandName)
{
+ /* CraftBukkit start
if ("seed".equals(commandName) && !this.mcServer.isDedicatedServer())
{
return true;
@@ -1273,6 +1573,15 @@
{
return true;
}
+ */
+ if ("@".equals(commandName)) {
+ return getBukkitEntity().hasPermission("minecraft.command.selector");
+ }
+ if ("".equals(commandName)) {
+ return getBukkitEntity().isOp();
+ }
+ return getBukkitEntity().hasPermission("minecraft.command." + commandName);
+ // CraftBukkit end
}
public String getPlayerIP()
@@ -1285,6 +1594,14 @@
public void handleClientSettings(CPacketClientSettings packetIn)
{
+ if (getPrimaryHand() != packetIn.getMainHand()) {
+ PlayerChangedMainHandEvent event = new PlayerChangedMainHandEvent(getBukkitEntity(), getPrimaryHand() == EnumHandSide.LEFT ? MainHand.LEFT : MainHand.RIGHT);
+ this.mcServer.server.getPluginManager().callEvent(event);
+ }
+ if (!this.language.equals(packetIn.getLang())) {
+ PlayerLocaleChangeEvent event = new PlayerLocaleChangeEvent(getBukkitEntity(), packetIn.getLang());
+ this.mcServer.server.getPluginManager().callEvent(event);
+ }
this.language = packetIn.getLang();
this.chatVisibility = packetIn.getChatVisibility();
this.chatColours = packetIn.isColorsEnabled();
@@ -1292,7 +1609,7 @@
this.getDataManager().set(MAIN_HAND, Byte.valueOf((byte)(packetIn.getMainHand() == EnumHandSide.LEFT ? 0 : 1)));
}
- public EntityPlayer.EnumChatVisibility getChatVisibility()
+ public EnumChatVisibility getChatVisibility()
{
return this.chatVisibility;
}
@@ -1367,7 +1684,7 @@
if (entity != this.spectatingEntity)
{
this.connection.sendPacket(new SPacketCamera(this.spectatingEntity));
- this.setPositionAndUpdate(this.spectatingEntity.posX, this.spectatingEntity.posY, this.spectatingEntity.posZ);
+ this.connection.setPlayerLocation(this.spectatingEntity.posX, this.spectatingEntity.posY, this.spectatingEntity.posZ, this.rotationYaw, this.rotationPitch, PlayerTeleportEvent.TeleportCause.SPECTATE);
}
}
@@ -1399,7 +1716,8 @@
@Nullable
public ITextComponent getTabListDisplayName()
{
- return null;
+ // return null;
+ return listName;
}
public void swingArm(EnumHand hand)
@@ -1420,13 +1738,16 @@
public void setElytraFlying()
{
- this.setFlag(7, true);
+ if (!CraftEventFactory.callToggleGlideEvent(this, true).isCancelled())
+ this.setFlag(7, true);
}
public void clearElytraFlying()
{
- this.setFlag(7, true);
- this.setFlag(7, false);
+ if (!CraftEventFactory.callToggleGlideEvent(this, false).isCancelled()) {
+ this.setFlag(7, true);
+ this.setFlag(7, false);
+ }
}
public PlayerAdvancements getAdvancements()
@@ -1439,4 +1760,144 @@
{
return this.enteredNetherPosition;
}
+
+ // CraftBukkit start - Add per-player time and weather.
+ public long timeOffset = 0;
+ public boolean relativeTime = true;
+
+ public long getPlayerTime() {
+ if (this.relativeTime) {
+ // Adds timeOffset to the current server time.
+ return this.world.getWorldTime() + this.timeOffset;
+ } else {
+ // Adds timeOffset to the beginning of this day.
+ return this.world.getWorldTime() - (this.world.getWorldTime() % 24000) + this.timeOffset;
+ }
+ }
+
+ public WeatherType weather = null;
+
+ public WeatherType getPlayerWeather() {
+ return this.weather;
+ }
+
+ public void setPlayerWeather(WeatherType type, boolean plugin) {
+ if (!plugin && this.weather != null) {
+ return;
+ }
+
+ if (plugin) {
+ this.weather = type;
+ }
+
+ if (type == WeatherType.DOWNFALL) {
+ this.connection.sendPacket(new SPacketChangeGameState(2, 0));
+ } else {
+ this.connection.sendPacket(new SPacketChangeGameState(1, 0));
+ }
+ }
+
+ private float pluginRainPosition;
+ private float pluginRainPositionPrevious;
+
+ public void updateWeather(float oldRain, float newRain, float oldThunder, float newThunder) {
+ if (this.weather == null) {
+ // Vanilla
+ if (oldRain != newRain) {
+ this.connection.sendPacket(new SPacketChangeGameState(7, newRain));
+ }
+ } else {
+ // Plugin
+ if (pluginRainPositionPrevious != pluginRainPosition) {
+ this.connection.sendPacket(new SPacketChangeGameState(7, pluginRainPosition));
+ }
+ }
+
+ if (oldThunder != newThunder) {
+ if (weather == WeatherType.DOWNFALL || weather == null) {
+ this.connection.sendPacket(new SPacketChangeGameState(8, newThunder));
+ } else {
+ this.connection.sendPacket(new SPacketChangeGameState(8, 0));
+ }
+ }
+ }
+
+ public void tickWeather() {
+ if (this.weather == null) return;
+
+ pluginRainPositionPrevious = pluginRainPosition;
+ if (weather == WeatherType.DOWNFALL) {
+ pluginRainPosition += 0.01;
+ } else {
+ pluginRainPosition -= 0.01;
+ }
+
+ pluginRainPosition = MathHelper.clamp(pluginRainPosition, 0.0F, 1.0F);
+ }
+
+ public void resetPlayerWeather() {
+ this.weather = null;
+ this.setPlayerWeather(this.world.getWorldInfo().isRaining() ? WeatherType.DOWNFALL : WeatherType.CLEAR, false);
+ }
+
+ @Override
+ public String toString() {
+ return super.toString() + "(" + this.getName() + " at " + this.posX + "," + this.posY + "," + this.posZ + ")";
+ }
+
+ // SPIGOT-1903, MC-98153
+ public void forceSetPositionRotation(double x, double y, double z, float yaw, float pitch) {
+ this.setLocationAndAngles(x, y, z, yaw, pitch);
+ this.connection.captureCurrentPosition();
+ }
+
+ @Override
+ public boolean isMovementBlocked() {
+ return super.isMovementBlocked() || !getBukkitEntity().isOnline();
+ }
+
+ @Override
+ public Scoreboard getWorldScoreboard() {
+ return getBukkitEntity().getScoreboard().getHandle();
+ }
+
+ public void reset() {
+ float exp = 0;
+ boolean keepInventory = this.world.getGameRules().getBoolean("keepInventory");
+
+ if (this.keepLevel || keepInventory) {
+ exp = this.experience;
+ this.newTotalExp = this.experienceTotal;
+ this.newLevel = this.experienceLevel;
+ }
+
+ this.setHealth(this.getMaxHealth());
+ ((Entity) this).fire = 0; // CatServer - Fix binpatch remap field error
+ this.fallDistance = 0;
+ this.foodStats = new FoodStats(this);
+ this.experienceLevel = this.newLevel;
+ this.experienceTotal = this.newTotalExp;
+ this.experience = 0;
+ this.deathTime = 0;
+ this.setArrowCountInEntity(0);
+ this.clearActivePotions();
+ this.potionsNeedUpdate = true;
+ this.openContainer = this.inventoryContainer;
+ this.attackingPlayer = null;
+ this.revengeTarget = null;
+ this._combatTracker = new CombatTracker(this);
+ this.lastExperience = -1;
+ if (this.keepLevel || keepInventory) {
+ this.experience = exp;
+ } else {
+ this.addExperience(this.newExp);
+ }
+ this.keepLevel = false;
+ getEntityData().getKeySet().removeIf(tag -> !PERSISTED_NBT_TAG.equals(tag)); // CatServer - reset custom data
+ }
+
+ @Override
+ public CraftPlayer getBukkitEntity() {
+ return (CraftPlayer) super.getBukkitEntity();
+ }
}