mirror of
https://github.com/barkeser2002/CatServer.git
synced 2026-09-25 04:20:02 +03:00
This should fix some mechanic inconsistencies in mods like SimpleDifficulty. Vanilla re-create a player instance when a player changes world, CraftBukkit made only single instance per player during its lifecycle(online period). Sadly, we can do nothing for this but call events that broken by CraftBukkit respawn logic.
1268 lines
65 KiB
Diff
1268 lines
65 KiB
Diff
--- ../src-base/minecraft/net/minecraft/server/management/PlayerList.java
|
|
+++ ../src-work/minecraft/net/minecraft/server/management/PlayerList.java
|
|
@@ -1,5 +1,7 @@
|
|
package net.minecraft.server.management;
|
|
|
|
+import com.google.common.base.Predicate;
|
|
+import com.google.common.collect.Iterables;
|
|
import com.google.common.collect.Lists;
|
|
import com.google.common.collect.Maps;
|
|
import com.google.common.collect.Sets;
|
|
@@ -8,6 +10,8 @@
|
|
import java.io.File;
|
|
import java.net.SocketAddress;
|
|
import java.text.SimpleDateFormat;
|
|
+import java.util.ArrayList;
|
|
+import java.util.Iterator;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Set;
|
|
@@ -27,6 +31,7 @@
|
|
import net.minecraft.network.play.server.SPacketChat;
|
|
import net.minecraft.network.play.server.SPacketCustomPayload;
|
|
import net.minecraft.network.play.server.SPacketEntityEffect;
|
|
+import net.minecraft.network.play.server.SPacketEntityMetadata;
|
|
import net.minecraft.network.play.server.SPacketEntityStatus;
|
|
import net.minecraft.network.play.server.SPacketHeldItemChange;
|
|
import net.minecraft.network.play.server.SPacketJoinGame;
|
|
@@ -45,6 +50,7 @@
|
|
import net.minecraft.scoreboard.ServerScoreboard;
|
|
import net.minecraft.scoreboard.Team;
|
|
import net.minecraft.server.MinecraftServer;
|
|
+import net.minecraft.server.network.NetHandlerLoginServer;
|
|
import net.minecraft.stats.StatList;
|
|
import net.minecraft.stats.StatisticsManagerServer;
|
|
import net.minecraft.util.math.BlockPos;
|
|
@@ -52,7 +58,7 @@
|
|
import net.minecraft.util.text.ChatType;
|
|
import net.minecraft.util.text.ITextComponent;
|
|
import net.minecraft.util.text.TextComponentTranslation;
|
|
-import net.minecraft.util.text.TextFormatting;
|
|
+import net.minecraft.util.text.translation.I18n;
|
|
import net.minecraft.world.DimensionType;
|
|
import net.minecraft.world.GameType;
|
|
import net.minecraft.world.World;
|
|
@@ -66,6 +72,23 @@
|
|
import net.minecraftforge.fml.relauncher.SideOnly;
|
|
import org.apache.logging.log4j.LogManager;
|
|
import org.apache.logging.log4j.Logger;
|
|
+import org.bukkit.Bukkit;
|
|
+import org.bukkit.Location;
|
|
+import org.bukkit.TravelAgent;
|
|
+import org.bukkit.craftbukkit.CraftServer;
|
|
+import org.bukkit.craftbukkit.CraftWorld;
|
|
+import org.bukkit.craftbukkit.chunkio.ChunkIOExecutor;
|
|
+import org.bukkit.craftbukkit.util.CraftChatMessage;
|
|
+import org.bukkit.entity.Player;
|
|
+import org.bukkit.event.player.PlayerChangedWorldEvent;
|
|
+import org.bukkit.event.player.PlayerJoinEvent;
|
|
+import org.bukkit.event.player.PlayerLoginEvent;
|
|
+import org.bukkit.event.player.PlayerPortalEvent;
|
|
+import org.bukkit.event.player.PlayerQuitEvent;
|
|
+import org.bukkit.event.player.PlayerRespawnEvent;
|
|
+import org.bukkit.event.player.PlayerTeleportEvent;
|
|
+import org.bukkit.util.Vector;
|
|
+import org.spigotmc.event.player.PlayerSpawnLocationEvent;
|
|
|
|
public abstract class PlayerList
|
|
{
|
|
@@ -76,7 +99,7 @@
|
|
private static final Logger LOGGER = LogManager.getLogger();
|
|
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd 'at' HH:mm:ss z");
|
|
private final MinecraftServer mcServer;
|
|
- private final List<EntityPlayerMP> playerEntityList = Lists.<EntityPlayerMP>newArrayList();
|
|
+ public final List<EntityPlayerMP> playerEntityList = new java.util.concurrent.CopyOnWriteArrayList<>(); // CraftBukkit - ArrayList -> CopyOnWriteArrayList: Iterator safety
|
|
private final Map<UUID, EntityPlayerMP> uuidToPlayerMap = Maps.<UUID, EntityPlayerMP>newHashMap();
|
|
private final UserListBans bannedPlayers;
|
|
private final UserListIPBans bannedIPs;
|
|
@@ -84,7 +107,7 @@
|
|
private final UserListWhitelist whiteListedPlayers;
|
|
private final Map<UUID, StatisticsManagerServer> playerStatFiles;
|
|
private final Map<UUID, PlayerAdvancements> advancements;
|
|
- private IPlayerFileData playerDataManager;
|
|
+ public IPlayerFileData playerDataManager;
|
|
private boolean whiteListEnforced;
|
|
protected int maxPlayers;
|
|
private int viewDistance;
|
|
@@ -92,6 +115,8 @@
|
|
private boolean commandsAllowedForAll;
|
|
private int playerPingIndex;
|
|
|
|
+ private CraftServer cserver;
|
|
+
|
|
public PlayerList(MinecraftServer server)
|
|
{
|
|
this.bannedPlayers = new UserListBans(FILE_PLAYERBANS);
|
|
@@ -106,8 +131,22 @@
|
|
this.maxPlayers = 8;
|
|
}
|
|
|
|
- public void initializeConnectionToPlayer(NetworkManager netManager, EntityPlayerMP playerIn)
|
|
+ // CatServer start
|
|
+ public PlayerList initCraftServer() {
|
|
+ this.cserver = mcServer.server = new CraftServer(mcServer, this);
|
|
+ mcServer.console = org.bukkit.craftbukkit.command.ColouredConsoleSender.getInstance();
|
|
+ return this;
|
|
+ }
|
|
+ // CatServer end
|
|
+
|
|
+ public void initializeConnectionToPlayer(NetworkManager netManager, EntityPlayerMP playerIn, NetHandlerPlayServer nethandlerplayserver)
|
|
{
|
|
+ // CatServer start
|
|
+ if (this.playerEntityList.stream().anyMatch(p -> p.getName().toLowerCase(java.util.Locale.ROOT).equals(playerIn.getName().toLowerCase(java.util.Locale.ROOT)) || p.getUniqueID().equals(playerIn.getUniqueID()))) {
|
|
+ nethandlerplayserver.disconnect(new TextComponentTranslation("multiplayer.disconnect.duplicate_login", new Object[0]));
|
|
+ return;
|
|
+ }
|
|
+ // CatServer end
|
|
GameProfile gameprofile = playerIn.getGameProfile();
|
|
PlayerProfileCache playerprofilecache = this.mcServer.getPlayerProfileCache();
|
|
GameProfile gameprofile1 = playerprofilecache.getProfileByUUID(gameprofile.getId());
|
|
@@ -115,6 +154,24 @@
|
|
playerprofilecache.addEntry(gameprofile);
|
|
NBTTagCompound nbttagcompound = this.readPlayerDataFromFile(playerIn);
|
|
playerIn.setWorld(this.mcServer.getWorld(playerIn.dimension));
|
|
+
|
|
+ World playerWorld = this.mcServer.getWorld(playerIn.dimension);
|
|
+ if (playerWorld == null)
|
|
+ {
|
|
+ playerIn.dimension = 0;
|
|
+ playerWorld = this.mcServer.getWorld(0);
|
|
+ BlockPos spawnPoint = playerWorld.provider.getRandomizedSpawnPoint();
|
|
+ playerIn.setPosition(spawnPoint.getX(), spawnPoint.getY(), spawnPoint.getZ());
|
|
+ }
|
|
+
|
|
+ // CraftBukkit start - Better rename detection
|
|
+ if (nbttagcompound != null && nbttagcompound.hasKey("bukkit")) {
|
|
+ NBTTagCompound bukkit = nbttagcompound.getCompoundTag("bukkit");
|
|
+ s = bukkit.hasKey("lastKnownName", 8) ? bukkit.getString("lastKnownName") : s;
|
|
+ }
|
|
+ // CraftBukkit end
|
|
+
|
|
+ playerIn.setWorld(playerWorld);
|
|
playerIn.interactionManager.setWorld((WorldServer)playerIn.world);
|
|
String s1 = "local";
|
|
|
|
@@ -123,12 +180,33 @@
|
|
s1 = netManager.getRemoteAddress().toString();
|
|
}
|
|
|
|
- LOGGER.info("{}[{}] logged in with entity id {} at ({}, {}, {})", playerIn.getName(), s1, Integer.valueOf(playerIn.getEntityId()), Double.valueOf(playerIn.posX), Double.valueOf(playerIn.posY), Double.valueOf(playerIn.posZ));
|
|
+ catserver.server.PlayerDataFixer.checkLocation(playerIn); // CatServer - fix invalid location
|
|
+ catserver.server.PlayerDataFixer.checkHealth(playerIn); // CatServer - fix invalid health
|
|
+
|
|
+ // Spigot start - spawn location event
|
|
+ Player bukkitPlayer = playerIn.getBukkitEntity();
|
|
+ PlayerSpawnLocationEvent ev = new PlayerSpawnLocationEvent(bukkitPlayer, bukkitPlayer.getLocation());
|
|
+ Bukkit.getPluginManager().callEvent(ev);
|
|
+
|
|
+ Location loc = ev.getSpawnLocation();
|
|
+ WorldServer world = ((CraftWorld) loc.getWorld()).getHandle();
|
|
+
|
|
+ playerIn.setWorld(world);
|
|
+ playerIn.setPosition(loc.getX(), loc.getY(), loc.getZ());
|
|
+ playerIn.setRotation(loc.getYaw(), loc.getPitch());
|
|
+ // Spigot end
|
|
+
|
|
+
|
|
+ // CraftBukkit - Moved message to after join
|
|
+ // LOGGER.info("{}[{}] logged in with entity id {} at ({}, {}, {})", playerIn.getName(), s1, Integer.valueOf(playerIn.getEntityId()), Double.valueOf(playerIn.posX), Double.valueOf(playerIn.posY), Double.valueOf(playerIn.posZ));
|
|
WorldServer worldserver = this.mcServer.getWorld(playerIn.dimension);
|
|
WorldInfo worldinfo = worldserver.getWorldInfo();
|
|
this.setPlayerGameTypeBasedOnOther(playerIn, (EntityPlayerMP)null, worldserver);
|
|
- NetHandlerPlayServer nethandlerplayserver = new NetHandlerPlayServer(this.mcServer, netManager, playerIn);
|
|
- nethandlerplayserver.sendPacket(new SPacketJoinGame(playerIn.getEntityId(), playerIn.interactionManager.getGameType(), worldinfo.isHardcoreModeEnabled(), worldserver.provider.getDimensionType().getId(), worldserver.getDifficulty(), this.getMaxPlayers(), worldinfo.getTerrainType(), worldserver.getGameRules().getBoolean("reducedDebugInfo")));
|
|
+ playerIn.connection = nethandlerplayserver;
|
|
+ catserver.server.CatServerNetwork.registerBukkitWorldToClient(playerIn, playerIn.dimension); // send DimensionRegisterMessage to client before attempting to login to a Bukkit dimension
|
|
+ net.minecraftforge.fml.common.FMLCommonHandler.instance().fireServerConnectionEvent(netManager);
|
|
+ nethandlerplayserver.sendPacket(new SPacketJoinGame(playerIn.getEntityId(), playerIn.interactionManager.getGameType(), worldinfo.isHardcoreModeEnabled(), worldserver.provider.getDimension(), worldserver.getDifficulty(), this.getMaxPlayers(), worldinfo.getTerrainType(), worldserver.getGameRules().getBoolean("reducedDebugInfo")));
|
|
+ playerIn.getBukkitEntity().sendSupportedChannels(); // CraftBukkit
|
|
nethandlerplayserver.sendPacket(new SPacketCustomPayload("MC|Brand", (new PacketBuffer(Unpooled.buffer())).writeString(this.getServerInstance().getServerModName())));
|
|
nethandlerplayserver.sendPacket(new SPacketServerDifficulty(worldinfo.getDifficulty(), worldinfo.isDifficultyLocked()));
|
|
nethandlerplayserver.sendPacket(new SPacketPlayerAbilities(playerIn.capabilities));
|
|
@@ -138,20 +216,23 @@
|
|
playerIn.getRecipeBook().init(playerIn);
|
|
this.sendScoreboard((ServerScoreboard)worldserver.getScoreboard(), playerIn);
|
|
this.mcServer.refreshStatusNextTick();
|
|
- TextComponentTranslation textcomponenttranslation;
|
|
-
|
|
+ // CraftBukkit start - login message is handled in the event
|
|
+ // TextComponentTranslation textcomponenttranslation;
|
|
+ String joinMessage;
|
|
if (playerIn.getName().equalsIgnoreCase(s))
|
|
{
|
|
- textcomponenttranslation = new TextComponentTranslation("multiplayer.player.joined", new Object[] {playerIn.getDisplayName()});
|
|
+ // textcomponenttranslation = new TextComponentTranslation("multiplayer.player.joined", new Object[] {playerIn.getDisplayName()});
|
|
+ joinMessage = "\u00A7e" + I18n.translateToLocalFormatted("multiplayer.player.joined", playerIn.getName());
|
|
}
|
|
else
|
|
{
|
|
- textcomponenttranslation = new TextComponentTranslation("multiplayer.player.joined.renamed", new Object[] {playerIn.getDisplayName(), s});
|
|
+ // textcomponenttranslation = new TextComponentTranslation("multiplayer.player.joined.renamed", new Object[] {playerIn.getDisplayName(), s});
|
|
+ joinMessage = "\u00A7e" + I18n.translateToLocalFormatted("multiplayer.player.joined.renamed", playerIn.getName(), s);
|
|
}
|
|
|
|
- textcomponenttranslation.getStyle().setColor(TextFormatting.YELLOW);
|
|
- this.sendMessage(textcomponenttranslation);
|
|
- this.playerLoggedIn(playerIn);
|
|
+ // textcomponenttranslation.getStyle().setColor(TextFormatting.YELLOW);
|
|
+ // this.sendMessage(textcomponenttranslation);
|
|
+ this.playerLoggedIn(playerIn, joinMessage);
|
|
nethandlerplayserver.setPlayerLocation(playerIn.posX, playerIn.posY, playerIn.posZ, playerIn.rotationYaw, playerIn.rotationPitch);
|
|
this.updateTimeAndWeatherForPlayer(playerIn, worldserver);
|
|
|
|
@@ -204,9 +285,12 @@
|
|
}
|
|
|
|
playerIn.addSelfToInternalCraftingInventory();
|
|
+ net.minecraftforge.fml.common.FMLCommonHandler.instance().firePlayerLoggedIn(playerIn);
|
|
+ // CraftBukkit - Moved from above, added world
|
|
+ PlayerList.LOGGER.info(playerIn.getName() + "[" + s1 + "] logged in with entity id " + playerIn.getEntityId() + " at ([" + playerIn.world.worldInfo.getWorldName() + "]" + playerIn.posX + ", " + playerIn.posY + ", " + playerIn.posZ + ")");
|
|
}
|
|
|
|
- protected void sendScoreboard(ServerScoreboard scoreboardIn, EntityPlayerMP playerIn)
|
|
+ public void sendScoreboard(ServerScoreboard scoreboardIn, EntityPlayerMP playerIn)
|
|
{
|
|
Set<ScoreObjective> set = Sets.<ScoreObjective>newHashSet();
|
|
|
|
@@ -233,28 +317,29 @@
|
|
|
|
public void setPlayerManager(WorldServer[] worldServers)
|
|
{
|
|
+ if (playerDataManager != null) return;
|
|
this.playerDataManager = worldServers[0].getSaveHandler().getPlayerNBTManager();
|
|
worldServers[0].getWorldBorder().addListener(new IBorderListener()
|
|
{
|
|
public void onSizeChanged(WorldBorder border, double newSize)
|
|
{
|
|
- PlayerList.this.sendPacketToAllPlayers(new SPacketWorldBorder(border, SPacketWorldBorder.Action.SET_SIZE));
|
|
+ PlayerList.this.sendAll(new SPacketWorldBorder(border, SPacketWorldBorder.Action.SET_SIZE), border.world);
|
|
}
|
|
public void onTransitionStarted(WorldBorder border, double oldSize, double newSize, long time)
|
|
{
|
|
- PlayerList.this.sendPacketToAllPlayers(new SPacketWorldBorder(border, SPacketWorldBorder.Action.LERP_SIZE));
|
|
+ PlayerList.this.sendAll(new SPacketWorldBorder(border, SPacketWorldBorder.Action.LERP_SIZE), border.world);
|
|
}
|
|
public void onCenterChanged(WorldBorder border, double x, double z)
|
|
{
|
|
- PlayerList.this.sendPacketToAllPlayers(new SPacketWorldBorder(border, SPacketWorldBorder.Action.SET_CENTER));
|
|
+ PlayerList.this.sendAll(new SPacketWorldBorder(border, SPacketWorldBorder.Action.SET_CENTER), border.world);
|
|
}
|
|
public void onWarningTimeChanged(WorldBorder border, int newTime)
|
|
{
|
|
- PlayerList.this.sendPacketToAllPlayers(new SPacketWorldBorder(border, SPacketWorldBorder.Action.SET_WARNING_TIME));
|
|
+ PlayerList.this.sendAll(new SPacketWorldBorder(border, SPacketWorldBorder.Action.SET_WARNING_TIME), border.world);
|
|
}
|
|
public void onWarningDistanceChanged(WorldBorder border, int newDistance)
|
|
{
|
|
- PlayerList.this.sendPacketToAllPlayers(new SPacketWorldBorder(border, SPacketWorldBorder.Action.SET_WARNING_BLOCKS));
|
|
+ PlayerList.this.sendAll(new SPacketWorldBorder(border, SPacketWorldBorder.Action.SET_WARNING_BLOCKS), border.world);
|
|
}
|
|
public void onDamageAmountChanged(WorldBorder border, double newAmount)
|
|
{
|
|
@@ -296,7 +381,7 @@
|
|
@Nullable
|
|
public NBTTagCompound readPlayerDataFromFile(EntityPlayerMP playerIn)
|
|
{
|
|
- NBTTagCompound nbttagcompound = this.mcServer.worlds[0].getWorldInfo().getPlayerNBTTagCompound();
|
|
+ NBTTagCompound nbttagcompound = this.mcServer.worldServerList.get(0).getWorldInfo().getPlayerNBTTagCompound();
|
|
NBTTagCompound nbttagcompound1;
|
|
|
|
if (playerIn.getName().equals(this.mcServer.getServerOwner()) && nbttagcompound != null)
|
|
@@ -304,6 +389,7 @@
|
|
nbttagcompound1 = nbttagcompound;
|
|
playerIn.readFromNBT(nbttagcompound);
|
|
LOGGER.debug("loading single player");
|
|
+ net.minecraftforge.event.ForgeEventFactory.firePlayerLoadingEvent(playerIn, this.playerDataManager, playerIn.getUniqueID().toString());
|
|
}
|
|
else
|
|
{
|
|
@@ -313,8 +399,24 @@
|
|
return nbttagcompound1;
|
|
}
|
|
|
|
+ public NBTTagCompound getPlayerNBT(EntityPlayerMP player)
|
|
+ {
|
|
+ // Hacky method to allow loading the NBT for a player prior to login
|
|
+ NBTTagCompound nbttagcompound = this.mcServer.worldServerList.get(0).getWorldInfo().getPlayerNBTTagCompound();
|
|
+ if (player.getName().equals(this.mcServer.getServerOwner()) && nbttagcompound != null)
|
|
+ {
|
|
+ return nbttagcompound;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ return ((net.minecraft.world.storage.SaveHandler)this.playerDataManager).getPlayerNBT(player);
|
|
+ }
|
|
+ }
|
|
+
|
|
protected void writePlayerData(EntityPlayerMP playerIn)
|
|
{
|
|
+ if (playerIn.connection == null) return;
|
|
+
|
|
this.playerDataManager.writePlayerData(playerIn);
|
|
StatisticsManagerServer statisticsmanagerserver = this.playerStatFiles.get(playerIn.getUniqueID());
|
|
|
|
@@ -343,19 +445,90 @@
|
|
playerIn.connection.sendPacket(new SPacketPlayerListItem(SPacketPlayerListItem.Action.ADD_PLAYER, new EntityPlayerMP[] {this.playerEntityList.get(i)}));
|
|
}
|
|
|
|
+ net.minecraftforge.common.chunkio.ChunkIOExecutor.adjustPoolSize(this.getCurrentPlayerCount());
|
|
worldserver.spawnEntity(playerIn);
|
|
this.preparePlayer(playerIn, (WorldServer)null);
|
|
}
|
|
|
|
+ public void playerLoggedIn(EntityPlayerMP playerIn, String joinMessage)
|
|
+ {
|
|
+ this.playerEntityList.add(playerIn);
|
|
+ this.uuidToPlayerMap.put(playerIn.getUniqueID(), playerIn);
|
|
+ // this.sendPacketToAllPlayers(new SPacketPlayerListItem(SPacketPlayerListItem.Action.ADD_PLAYER, new EntityPlayerMP[] {playerIn})); // CraftBukkit - replaced with loop below
|
|
+ WorldServer worldserver = this.mcServer.getWorld(playerIn.dimension);
|
|
+
|
|
+ PlayerJoinEvent playerJoinEvent = new PlayerJoinEvent(cserver.getPlayer(playerIn), joinMessage);
|
|
+ cserver.getPluginManager().callEvent(playerJoinEvent);
|
|
+
|
|
+ if (!playerIn.connection.netManager.isChannelOpen()) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ joinMessage = playerJoinEvent.getJoinMessage();
|
|
+
|
|
+ if (joinMessage != null && joinMessage.length() > 0) {
|
|
+ for (ITextComponent line : org.bukkit.craftbukkit.util.CraftChatMessage.fromString(joinMessage)) {
|
|
+ mcServer.getPlayerList().sendPacketToAllPlayers(new SPacketChat(line));
|
|
+ }
|
|
+ }
|
|
+
|
|
+ ChunkIOExecutor.adjustPoolSize(getCurrentPlayerCount());
|
|
+
|
|
+ // CraftBukkit start - sendAll above replaced with this loop
|
|
+ SPacketPlayerListItem packet = new SPacketPlayerListItem(SPacketPlayerListItem.Action.ADD_PLAYER, playerIn);
|
|
+ for (int i = 0; i < this.playerEntityList.size(); ++i)
|
|
+ {
|
|
+ // playerIn.connection.sendPacket(new SPacketPlayerListItem(SPacketPlayerListItem.Action.ADD_PLAYER, new EntityPlayerMP[] {this.playerEntityList.get(i)}));
|
|
+ EntityPlayerMP entityplayer1 = this.playerEntityList.get(i);
|
|
+
|
|
+ if (entityplayer1.getBukkitEntity().canSee(playerIn.getBukkitEntity())) {
|
|
+ entityplayer1.connection.sendPacket(packet);
|
|
+ }
|
|
+
|
|
+ if (!playerIn.getBukkitEntity().canSee(entityplayer1.getBukkitEntity())) {
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ playerIn.connection.sendPacket(new SPacketPlayerListItem(SPacketPlayerListItem.Action.ADD_PLAYER, new EntityPlayerMP[] { entityplayer1}));
|
|
+ }
|
|
+ playerIn.sentListPacket = true;
|
|
+ // CraftBukkit end
|
|
+
|
|
+ playerIn.connection.sendPacket(new SPacketEntityMetadata(playerIn.getEntityId(), playerIn.getDataManager(), true)); // CraftBukkit - BungeeCord#2321, send complete data to self on spawn
|
|
+ net.minecraftforge.common.chunkio.ChunkIOExecutor.adjustPoolSize(this.getCurrentPlayerCount());
|
|
+ // CraftBukkit start - Only add if the player wasn't moved in the event
|
|
+ if (playerIn.world == worldserver && !worldserver.playerEntities.contains(playerIn)) {
|
|
+ worldserver.spawnEntity(playerIn);
|
|
+ this.preparePlayer(playerIn, null);
|
|
+ }
|
|
+ // CraftBukkit end
|
|
+ }
|
|
+
|
|
public void serverUpdateMovingPlayer(EntityPlayerMP playerIn)
|
|
{
|
|
playerIn.getServerWorld().getPlayerChunkMap().updateMovingPlayer(playerIn);
|
|
}
|
|
|
|
- public void playerLoggedOut(EntityPlayerMP playerIn)
|
|
+ public String playerLoggedOut(EntityPlayerMP playerIn)
|
|
{
|
|
+ if (catserver.server.AsyncCatcher.checkAsync("kick player")) return catserver.server.AsyncCatcher.ensureExecuteOnPrimaryThread(() -> playerLoggedOut(playerIn)); // CatServer
|
|
+ String quitMessage = null;
|
|
+ net.minecraftforge.fml.common.FMLCommonHandler.instance().firePlayerLoggedOut(playerIn);
|
|
WorldServer worldserver = playerIn.getServerWorld();
|
|
playerIn.addStat(StatList.LEAVE_GAME);
|
|
+
|
|
+ // CraftBukkit start - Quitting must be before we do final save of data, in case plugins need to modify it
|
|
+ org.bukkit.craftbukkit.event.CraftEventFactory.handleInventoryCloseEvent(playerIn);
|
|
+ if(playerIn.connection != null) { // CatServer - fix crash when player is Forge Handshake
|
|
+ PlayerQuitEvent playerQuitEvent = new PlayerQuitEvent(cserver.getPlayer(playerIn), "\u00A7e" + playerIn.getName() + " left the game");
|
|
+ cserver.getPluginManager().callEvent(playerQuitEvent);
|
|
+ playerIn.getBukkitEntity().disconnect(playerQuitEvent.getQuitMessage());
|
|
+
|
|
+ playerIn.onUpdateEntity();// SPIGOT-924
|
|
+ quitMessage = playerQuitEvent.getQuitMessage();
|
|
+ }
|
|
+ // CraftBukkit end
|
|
+
|
|
this.writePlayerData(playerIn);
|
|
|
|
if (playerIn.isRiding())
|
|
@@ -376,6 +549,7 @@
|
|
worldserver.getChunkFromChunkCoords(playerIn.chunkCoordX, playerIn.chunkCoordZ).markDirty();
|
|
}
|
|
}
|
|
+ net.minecraftforge.common.chunkio.ChunkIOExecutor.adjustPoolSize(this.getCurrentPlayerCount());
|
|
|
|
worldserver.removeEntity(playerIn);
|
|
worldserver.getPlayerChunkMap().removePlayer(playerIn);
|
|
@@ -391,7 +565,23 @@
|
|
this.advancements.remove(uuid);
|
|
}
|
|
|
|
- this.sendPacketToAllPlayers(new SPacketPlayerListItem(SPacketPlayerListItem.Action.REMOVE_PLAYER, new EntityPlayerMP[] {playerIn}));
|
|
+ // this.sendPacketToAllPlayers(new SPacketPlayerListItem(SPacketPlayerListItem.Action.REMOVE_PLAYER, new EntityPlayerMP[] {playerIn}));
|
|
+ SPacketPlayerListItem packet = new SPacketPlayerListItem(SPacketPlayerListItem.Action.REMOVE_PLAYER, playerIn);
|
|
+ for (int i = 0; i < playerEntityList.size(); i++) {
|
|
+ EntityPlayerMP entityplayer2 = (EntityPlayerMP) this.playerEntityList.get(i);
|
|
+
|
|
+ if (entityplayer2.getBukkitEntity().canSee(playerIn.getBukkitEntity())) {
|
|
+ entityplayer2.connection.sendPacket(packet);
|
|
+ } else {
|
|
+ entityplayer2.getBukkitEntity().removeDisconnectingPlayer(playerIn.getBukkitEntity());
|
|
+ }
|
|
+ }
|
|
+ // This removes the scoreboard (and player reference) for the specific player in the manager
|
|
+ cserver.getScoreboardManager().removePlayer(playerIn.getBukkitEntity());
|
|
+
|
|
+ ChunkIOExecutor.adjustPoolSize(this.getCurrentPlayerCount());
|
|
+
|
|
+ return quitMessage;
|
|
}
|
|
|
|
public String allowUserToConnect(SocketAddress address, GameProfile profile)
|
|
@@ -430,6 +620,87 @@
|
|
}
|
|
}
|
|
|
|
+ @Nullable
|
|
+ public EntityPlayerMP allowUserToConnect(NetHandlerLoginServer loginServer, GameProfile profile, String hostname)
|
|
+ {
|
|
+ // Moved from processLogin
|
|
+ UUID uuid = EntityPlayer.getUUID(profile);
|
|
+ ArrayList<EntityPlayerMP> arraylist = Lists.newArrayList();
|
|
+
|
|
+ EntityPlayerMP entityplayer;
|
|
+
|
|
+ for (int i = 0; i < this.playerEntityList.size(); ++i) {
|
|
+ entityplayer = (EntityPlayerMP) this.playerEntityList.get(i);
|
|
+ if (entityplayer.getUniqueID().equals(uuid)) {
|
|
+ arraylist.add(entityplayer);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ Iterator<EntityPlayerMP> iterator = arraylist.iterator();
|
|
+
|
|
+ while (iterator.hasNext()) {
|
|
+ entityplayer = (EntityPlayerMP) iterator.next();
|
|
+ writePlayerData(entityplayer); // CraftBukkit - Force the player's inventory to be saved
|
|
+ entityplayer.connection.disconnect(new TextComponentTranslation("multiplayer.disconnect.duplicate_login", new Object[0]));
|
|
+ }
|
|
+
|
|
+ // Instead of kicking then returning, we need to store the kick reason
|
|
+ // in the event, check with plugins to see if it's ok, and THEN kick
|
|
+ // depending on the outcome.
|
|
+ SocketAddress socketaddress = loginServer.networkManager.getRemoteAddress();
|
|
+
|
|
+ EntityPlayerMP entity = new EntityPlayerMP(mcServer, mcServer.getWorldServer(0), profile, new PlayerInteractionManager(mcServer.getWorldServer(0)));
|
|
+ Player player = entity.getBukkitEntity();
|
|
+ //Spigot Start
|
|
+ PlayerLoginEvent event = new PlayerLoginEvent(player, hostname, ((java.net.InetSocketAddress) socketaddress).getAddress(), ((java.net.InetSocketAddress) loginServer.networkManager.getRawAddress()).getAddress());
|
|
+ //Spigot End
|
|
+ if (getBannedPlayers().isBanned(profile) && !getBannedPlayers().getEntry(profile).hasBanExpired())
|
|
+ {
|
|
+ UserListBansEntry userlistbansentry = (UserListBansEntry)this.bannedPlayers.getEntry(profile);
|
|
+ String s1 = "You are banned from this server!\nReason: " + userlistbansentry.getBanReason();
|
|
+
|
|
+ if (userlistbansentry.getBanEndDate() != null)
|
|
+ {
|
|
+ s1 = s1 + "\nYour ban will be removed on " + DATE_FORMAT.format(userlistbansentry.getBanEndDate());
|
|
+ }
|
|
+
|
|
+ // return s1;
|
|
+ event.disallow(PlayerLoginEvent.Result.KICK_BANNED, s1);
|
|
+ }
|
|
+ else if (!this.canJoin(profile))
|
|
+ {
|
|
+ // return "You are not white-listed on this server!";
|
|
+ event.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, org.spigotmc.SpigotConfig.whitelistMessage); // Spigot
|
|
+ }
|
|
+ else if (getBannedIPs().isBanned(socketaddress) && !getBannedIPs().getBanEntry(socketaddress).hasBanExpired())
|
|
+ {
|
|
+ UserListIPBansEntry userlistipbansentry = this.bannedIPs.getBanEntry(socketaddress);
|
|
+ String s = "Your IP address is banned from this server!\nReason: " + userlistipbansentry.getBanReason();
|
|
+
|
|
+ if (userlistipbansentry.getBanEndDate() != null)
|
|
+ {
|
|
+ s = s + "\nYour ban will be removed on " + DATE_FORMAT.format(userlistipbansentry.getBanEndDate());
|
|
+ }
|
|
+
|
|
+ // return s;
|
|
+ if (!userlistipbansentry.hasBanExpired()) event.disallow(PlayerLoginEvent.Result.KICK_BANNED, s);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ // return this.playerEntityList.size() >= this.maxPlayers && !this.bypassesPlayerLimit(profile) ? "The server is full!" : null;
|
|
+ if (this.playerEntityList.size() >= this.maxPlayers && !this.bypassesPlayerLimit(profile)) {
|
|
+ event.disallow(PlayerLoginEvent.Result.KICK_FULL, org.spigotmc.SpigotConfig.serverFullMessage); // Spigot
|
|
+ }
|
|
+ }
|
|
+
|
|
+ cserver.getPluginManager().callEvent(event);
|
|
+ if (event.getResult() != PlayerLoginEvent.Result.ALLOWED) {
|
|
+ loginServer.disconnect(event.getKickMessage());
|
|
+ return null;
|
|
+ }
|
|
+ return entity;
|
|
+ }
|
|
+
|
|
public EntityPlayerMP createPlayerForUser(GameProfile profile)
|
|
{
|
|
UUID uuid = EntityPlayer.getUUID(profile);
|
|
@@ -471,15 +742,99 @@
|
|
return new EntityPlayerMP(this.mcServer, this.mcServer.getWorld(0), profile, playerinteractionmanager);
|
|
}
|
|
|
|
+ public EntityPlayerMP createPlayerForUser(GameProfile profile, EntityPlayerMP entityPlayerMP)
|
|
+ {
|
|
+ /* CraftBukkit - Moved up
|
|
+ UUID uuid = EntityPlayer.getUUID(profile);
|
|
+ List<EntityPlayerMP> list = Lists.<EntityPlayerMP>newArrayList();
|
|
+
|
|
+ for (int i = 0; i < this.playerEntityList.size(); ++i)
|
|
+ {
|
|
+ EntityPlayerMP entityplayermp = this.playerEntityList.get(i);
|
|
+
|
|
+ if (entityplayermp.getUniqueID().equals(uuid))
|
|
+ {
|
|
+ list.add(entityplayermp);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ EntityPlayerMP entityplayermp2 = this.uuidToPlayerMap.get(profile.getId());
|
|
+
|
|
+ if (entityplayermp2 != null && !list.contains(entityplayermp2))
|
|
+ {
|
|
+ list.add(entityplayermp2);
|
|
+ }
|
|
+
|
|
+ for (EntityPlayerMP entityplayermp1 : list)
|
|
+ {
|
|
+ entityplayermp1.connection.disconnect(new TextComponentTranslation("multiplayer.disconnect.duplicate_login", new Object[0]));
|
|
+ }
|
|
+
|
|
+ PlayerInteractionManager playerinteractionmanager;
|
|
+
|
|
+ if (this.mcServer.isDemo())
|
|
+ {
|
|
+ playerinteractionmanager = new DemoPlayerInteractionManager(this.mcServer.getWorld(0));
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ playerinteractionmanager = new PlayerInteractionManager(this.mcServer.getWorld(0));
|
|
+ }
|
|
+
|
|
+ return new EntityPlayerMP(this.mcServer, this.mcServer.getWorld(0), profile, playerinteractionmanager);
|
|
+ */
|
|
+ return entityPlayerMP;
|
|
+ }
|
|
+
|
|
public EntityPlayerMP recreatePlayerEntity(EntityPlayerMP playerIn, int dimension, boolean conqueredEnd)
|
|
{
|
|
+ return this.moveToWorld(playerIn, dimension, conqueredEnd, null, true);
|
|
+ }
|
|
+
|
|
+ public EntityPlayerMP moveToWorld(EntityPlayerMP playerIn, int dimension, boolean conqueredEnd, Location location, boolean avoidSuffocation) {
|
|
+ playerIn.dismountRidingEntity(); // CraftBukkit
|
|
+ World world = mcServer.getWorld(dimension);
|
|
+ if (world == null)
|
|
+ {
|
|
+ dimension = playerIn.getSpawnDimension();
|
|
+ }
|
|
+ else if (location == null && !world.provider.canRespawnHere())
|
|
+ {
|
|
+ dimension = world.provider.getRespawnDimension(playerIn);
|
|
+ }
|
|
+ if (mcServer.getWorld(dimension) == null) dimension = 0;
|
|
+
|
|
+ // handle return from End
|
|
+ if (conqueredEnd && location == null)
|
|
+ {
|
|
+ WorldServer exitWorld = this.mcServer.getWorld(dimension);
|
|
+ Location enter = playerIn.getBukkitEntity().getLocation();
|
|
+ Location exit = null;
|
|
+ // THE_END -> NORMAL; use bed if available, otherwise default spawn
|
|
+ exit = playerIn.getBukkitEntity().getBedSpawnLocation();
|
|
+
|
|
+ if (exit == null || ((CraftWorld) exit.getWorld()).getHandle().dimension != 0)
|
|
+ {
|
|
+ exit = exitWorld.getWorld().getSpawnLocation();
|
|
+ }
|
|
+ PlayerPortalEvent event = new PlayerPortalEvent(playerIn.getBukkitEntity(), enter, exit, org.bukkit.craftbukkit.CraftTravelAgent.DEFAULT, PlayerPortalEvent.TeleportCause.END_PORTAL);
|
|
+ event.useTravelAgent(false);
|
|
+ Bukkit.getServer().getPluginManager().callEvent(event);
|
|
+ if (event.isCancelled() || event.getTo() == null)
|
|
+ {
|
|
+ return null;
|
|
+ }
|
|
+ location = event.getTo();
|
|
+ }
|
|
+
|
|
playerIn.getServerWorld().getEntityTracker().removePlayerFromTrackers(playerIn);
|
|
- playerIn.getServerWorld().getEntityTracker().untrack(playerIn);
|
|
+ // playerIn.getServerWorld().getEntityTracker().untrack(playerIn);
|
|
playerIn.getServerWorld().getPlayerChunkMap().removePlayer(playerIn);
|
|
this.playerEntityList.remove(playerIn);
|
|
this.mcServer.getWorld(playerIn.dimension).removeEntityDangerously(playerIn);
|
|
- BlockPos blockpos = playerIn.getBedLocation();
|
|
- boolean flag = playerIn.isSpawnForced();
|
|
+ BlockPos blockpos = playerIn.getBedLocation(dimension);
|
|
+ boolean flag1 = playerIn.isSpawnForced(dimension);
|
|
+ /* CraftBukkit start
|
|
playerIn.dimension = dimension;
|
|
PlayerInteractionManager playerinteractionmanager;
|
|
|
|
@@ -493,8 +848,20 @@
|
|
}
|
|
|
|
EntityPlayerMP entityplayermp = new EntityPlayerMP(this.mcServer, this.mcServer.getWorld(playerIn.dimension), playerIn.getGameProfile(), playerinteractionmanager);
|
|
+ */
|
|
+ EntityPlayerMP entityplayermp = playerIn;
|
|
+ // CatServer start - Call construct event and re-gather capabilities
|
|
+ if (catserver.server.CatServer.getConfig().callConstructCapabilityEventOnRespawn) {
|
|
+ net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.EntityEvent.EntityConstructing(entityplayermp));
|
|
+ ((Entity) entityplayermp).capabilities = net.minecraftforge.event.ForgeEventFactory.gatherCapabilities(entityplayermp);
|
|
+ }
|
|
+ // CatServer end - Call construct event and re-gather capabilities
|
|
+ org.bukkit.World fromWorld = playerIn.getBukkitEntity().getWorld();
|
|
+ playerIn.queuedEndExit = false;
|
|
+
|
|
entityplayermp.connection = playerIn.connection;
|
|
entityplayermp.copyFrom(playerIn, conqueredEnd);
|
|
+ entityplayermp.dimension = dimension;
|
|
entityplayermp.setEntityId(playerIn.getEntityId());
|
|
entityplayermp.setCommandStats(playerIn);
|
|
entityplayermp.setPrimaryHand(playerIn.getPrimaryHand());
|
|
@@ -504,44 +871,103 @@
|
|
entityplayermp.addTag(s);
|
|
}
|
|
|
|
- WorldServer worldserver = this.mcServer.getWorld(playerIn.dimension);
|
|
- this.setPlayerGameTypeBasedOnOther(entityplayermp, playerIn, worldserver);
|
|
+ // WorldServer worldserver = this.mcServer.getWorld(playerIn.dimension); // CraftBukkit - handled later
|
|
+ // this.setPlayerGameTypeBasedOnOther(entityplayermp, playerIn, worldserver);
|
|
+ BlockPos blockposition1;
|
|
+ // CraftBukkit start - fire PlayerRespawnEvent
|
|
+ if (location == null) {
|
|
+ boolean isBedSpawn = false;
|
|
+ CraftWorld cworld = (CraftWorld) this.mcServer.server.getWorld(playerIn.spawnWorld);
|
|
+ if (cworld != null && blockpos != null) {
|
|
+ blockposition1 = EntityPlayer.getBedSpawnLocation(cworld.getHandle(), blockpos, flag1);
|
|
+ if (blockposition1 != null) {
|
|
+ isBedSpawn = true;
|
|
+ location = new Location(cworld, (double) ((float) blockposition1.getX() + 0.5F), (double) ((float) blockposition1.getY() + 0.1F), (double) ((float) blockposition1.getZ() + 0.5F));
|
|
+ } else {
|
|
+ entityplayermp.setSpawnPoint(null, true);
|
|
+ entityplayermp.connection.sendPacket(new SPacketChangeGameState(0, 0.0F));
|
|
+ }
|
|
+ }
|
|
|
|
- if (blockpos != null)
|
|
- {
|
|
- BlockPos blockpos1 = EntityPlayer.getBedSpawnLocation(this.mcServer.getWorld(playerIn.dimension), blockpos, flag);
|
|
-
|
|
- if (blockpos1 != null)
|
|
- {
|
|
- entityplayermp.setLocationAndAngles((double)((float)blockpos1.getX() + 0.5F), (double)((float)blockpos1.getY() + 0.1F), (double)((float)blockpos1.getZ() + 0.5F), 0.0F, 0.0F);
|
|
- entityplayermp.setSpawnPoint(blockpos, flag);
|
|
+ if (location == null) {
|
|
+ cworld = (CraftWorld) this.mcServer.server.getWorlds().get(0);
|
|
+ blockpos = entityplayermp.getSpawnPoint(this.mcServer, cworld.getHandle());
|
|
+ location = new Location(cworld, (double) ((float) blockpos.getX() + 0.5F), (double) ((float) blockpos.getY() + 0.1F), (double) ((float) blockpos.getZ() + 0.5F));
|
|
}
|
|
- else
|
|
- {
|
|
- entityplayermp.connection.sendPacket(new SPacketChangeGameState(0, 0.0F));
|
|
+ Player respawnPlayer = cserver.getPlayer(entityplayermp);
|
|
+ PlayerRespawnEvent respawnEvent = new PlayerRespawnEvent(respawnPlayer, location, isBedSpawn);
|
|
+ cserver.getPluginManager().callEvent(respawnEvent);
|
|
+ // Spigot Start
|
|
+ if (playerIn.connection.isDisconnected()) {
|
|
+ return playerIn;
|
|
}
|
|
+ // Spigot End
|
|
+
|
|
+
|
|
+ location = respawnEvent.getRespawnLocation();
|
|
+ playerIn.reset();
|
|
+ } else {
|
|
+ location.setWorld(mcServer.getWorld(dimension).getWorld());
|
|
}
|
|
|
|
+ WorldServer worldserver = ((CraftWorld) location.getWorld()).getHandle();
|
|
+ entityplayermp.forceSetPositionRotation(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
|
|
+
|
|
worldserver.getChunkProvider().provideChunk((int)entityplayermp.posX >> 4, (int)entityplayermp.posZ >> 4);
|
|
|
|
- while (!worldserver.getCollisionBoxes(entityplayermp, entityplayermp.getEntityBoundingBox()).isEmpty() && entityplayermp.posY < 256.0D)
|
|
+ while (avoidSuffocation && !worldserver.getCollisionBoxes(entityplayermp, entityplayermp.getEntityBoundingBox()).isEmpty() && entityplayermp.posY < 256.0D)
|
|
{
|
|
entityplayermp.setPosition(entityplayermp.posX, entityplayermp.posY + 1.0D, entityplayermp.posZ);
|
|
}
|
|
|
|
- entityplayermp.connection.sendPacket(new SPacketRespawn(entityplayermp.dimension, entityplayermp.world.getDifficulty(), entityplayermp.world.getWorldInfo().getTerrainType(), entityplayermp.interactionManager.getGameType()));
|
|
+ int actualDimension = worldserver.provider.getDimension();
|
|
+ catserver.server.CatServerNetwork.registerBukkitWorldToClient(entityplayermp, actualDimension); // CatServer - change dim for bukkit added dimensions
|
|
+ // entityplayermp.connection.sendPacket(new SPacketRespawn(entityplayermp.dimension, entityplayermp.world.getDifficulty(), entityplayermp.world.getWorldInfo().getTerrainType(), entityplayermp.interactionManager.getGameType()));
|
|
+ entityplayermp.connection.sendPacket(new SPacketRespawn(actualDimension, worldserver.getDifficulty(), worldserver.getWorldInfo().getTerrainType(), entityplayermp.interactionManager.getGameType()));
|
|
+ entityplayermp.setWorld(worldserver);
|
|
+ entityplayermp.isDead = false;
|
|
+ entityplayermp.connection.teleport(new Location(worldserver.getWorld(), entityplayermp.posX, entityplayermp.posY, entityplayermp.posZ, entityplayermp.rotationYaw, entityplayermp.rotationPitch));
|
|
+ entityplayermp.setSneaking(false);
|
|
BlockPos blockpos2 = worldserver.getSpawnPoint();
|
|
- entityplayermp.connection.setPlayerLocation(entityplayermp.posX, entityplayermp.posY, entityplayermp.posZ, entityplayermp.rotationYaw, entityplayermp.rotationPitch);
|
|
+ // entityplayermp.connection.setPlayerLocation(entityplayermp.posX, entityplayermp.posY, entityplayermp.posZ, entityplayermp.rotationYaw, entityplayermp.rotationPitch);
|
|
entityplayermp.connection.sendPacket(new SPacketSpawnPosition(blockpos2));
|
|
entityplayermp.connection.sendPacket(new SPacketSetExperience(entityplayermp.experience, entityplayermp.experienceTotal, entityplayermp.experienceLevel));
|
|
this.updateTimeAndWeatherForPlayer(entityplayermp, worldserver);
|
|
this.updatePermissionLevel(entityplayermp);
|
|
- worldserver.getPlayerChunkMap().addPlayer(entityplayermp);
|
|
- worldserver.spawnEntity(entityplayermp);
|
|
- this.playerEntityList.add(entityplayermp);
|
|
- this.uuidToPlayerMap.put(entityplayermp.getUniqueID(), entityplayermp);
|
|
- entityplayermp.addSelfToInternalCraftingInventory();
|
|
+ if (!playerIn.connection.isDisconnected()) {
|
|
+ worldserver.getPlayerChunkMap().addPlayer(entityplayermp);
|
|
+ worldserver.spawnEntity(entityplayermp);
|
|
+ this.playerEntityList.add(entityplayermp);
|
|
+ this.uuidToPlayerMap.put(entityplayermp.getUniqueID(), entityplayermp);
|
|
+ }
|
|
+ // entityplayermp.addSelfToInternalCraftingInventory();
|
|
entityplayermp.setHealth(entityplayermp.getHealth());
|
|
+ // Added from changeDimension
|
|
+ syncPlayerInventory(playerIn); // Update health, etc...
|
|
+ playerIn.sendPlayerAbilities();
|
|
+ for (Object o1 : playerIn.getActivePotionEffects()) {
|
|
+ PotionEffect mobEffect = (PotionEffect) o1;
|
|
+ playerIn.connection.sendPacket(new SPacketEntityEffect(playerIn.getEntityId(), mobEffect));
|
|
+ }
|
|
+
|
|
+ // Fire advancement trigger
|
|
+ CriteriaTriggers.CHANGED_DIMENSION.trigger(playerIn, ((CraftWorld) fromWorld).getHandle().provider.getDimensionType(), worldserver.provider.getDimensionType());
|
|
+ if (((CraftWorld) fromWorld).getHandle().provider.getDimensionType() == DimensionType.NETHER && worldserver.provider.getDimensionType() == DimensionType.OVERWORLD && playerIn.getEnteredNetherPosition() != null) {
|
|
+ CriteriaTriggers.NETHER_TRAVEL.trigger(playerIn, playerIn.getEnteredNetherPosition());
|
|
+ }
|
|
+
|
|
+ // Don't fire on respawn
|
|
+ if (fromWorld != location.getWorld()) {
|
|
+ PlayerChangedWorldEvent event = new PlayerChangedWorldEvent(playerIn.getBukkitEntity(), fromWorld);
|
|
+ mcServer.server.getPluginManager().callEvent(event);
|
|
+ }
|
|
+
|
|
+ // Save player file again if they were disconnected
|
|
+ if (playerIn.connection.isDisconnected()) {
|
|
+ this.writePlayerData(playerIn);
|
|
+ }
|
|
+ // CraftBukkit end
|
|
+ net.minecraftforge.fml.common.FMLCommonHandler.instance().firePlayerRespawnEvent(entityplayermp, conqueredEnd);
|
|
return entityplayermp;
|
|
}
|
|
|
|
@@ -549,44 +975,125 @@
|
|
{
|
|
GameProfile gameprofile = player.getGameProfile();
|
|
int i = this.canSendCommands(gameprofile) ? this.ops.getPermissionLevel(gameprofile) : 0;
|
|
- i = this.mcServer.isSinglePlayer() && this.mcServer.worlds[0].getWorldInfo().areCommandsAllowed() ? 4 : i;
|
|
+ i = this.mcServer.isSinglePlayer() && this.mcServer.worldServerList.get(0).getWorldInfo().areCommandsAllowed() ? 4 : i;
|
|
i = this.commandsAllowedForAll ? 4 : i;
|
|
this.sendPlayerPermissionLevel(player, i);
|
|
}
|
|
|
|
public void changePlayerDimension(EntityPlayerMP player, int dimensionIn)
|
|
{
|
|
- int i = player.dimension;
|
|
- WorldServer worldserver = this.mcServer.getWorld(player.dimension);
|
|
+ transferPlayerToDimension(player, dimensionIn, mcServer.getWorld(dimensionIn).getDefaultTeleporter());
|
|
+ }
|
|
+
|
|
+ // TODO: Remove (1.13)
|
|
+ public void transferPlayerToDimension(EntityPlayerMP player, int dimensionIn, net.minecraft.world.Teleporter teleporter)
|
|
+ {
|
|
+ transferPlayerToDimension(player, dimensionIn, (net.minecraftforge.common.util.ITeleporter) teleporter);
|
|
+ }
|
|
+
|
|
+ // CatServer start - Replaced the standard handling of portals with a more customised method.
|
|
+ public void transferPlayerToDimension(EntityPlayerMP player, int dimensionIn, net.minecraftforge.common.util.ITeleporter teleporter) {
|
|
+ transferPlayerToDimension(player, dimensionIn, (net.minecraftforge.common.util.ITeleporter) teleporter, PlayerTeleportEvent.TeleportCause.MOD);
|
|
+ }
|
|
+
|
|
+ public void transferPlayerToDimension(EntityPlayerMP player, int dimensionIn, net.minecraftforge.common.util.ITeleporter teleporter, PlayerTeleportEvent.TeleportCause cause)
|
|
+ {
|
|
+ WorldServer fromWorld = this.mcServer.getWorld(player.dimension);
|
|
+ WorldServer exitWorld = this.mcServer.getWorld(dimensionIn);
|
|
+
|
|
+ Location enter = player.getBukkitEntity().getLocation();
|
|
+ Location exit = null;
|
|
+ boolean useTravelAgent = false;
|
|
+ if (exitWorld != null) {
|
|
+ exit = this.calculateTarget(enter, exitWorld);
|
|
+ if (cause != cause.MOD) // don't use travel agent for custom dimensions
|
|
+ {
|
|
+ useTravelAgent = true;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ TravelAgent agent = teleporter instanceof TravelAgent ? (TravelAgent)teleporter : org.bukkit.craftbukkit.CraftTravelAgent.DEFAULT; // return arbitrary TA to compensate for implementation dependent plugins
|
|
+
|
|
+ PlayerPortalEvent event = new PlayerPortalEvent(player.getBukkitEntity(), enter, exit, agent, cause);
|
|
+ event.useTravelAgent(useTravelAgent);
|
|
+ Bukkit.getServer().getPluginManager().callEvent(event);
|
|
+ if (event.isCancelled() || event.getTo() == null) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ exit = event.useTravelAgent() && cause != cause.MOD ? event.getPortalTravelAgent().findOrCreate(event.getTo()) : event.getTo();
|
|
+ if (exit == null) {
|
|
+ return;
|
|
+ }
|
|
+ exitWorld = ((CraftWorld) exit.getWorld()).getHandle();
|
|
+
|
|
+ org.bukkit.event.player.PlayerTeleportEvent tpEvent = new org.bukkit.event.player.PlayerTeleportEvent(player.getBukkitEntity(), enter, exit, cause);
|
|
+ Bukkit.getServer().getPluginManager().callEvent(tpEvent);
|
|
+ if (tpEvent.isCancelled() || tpEvent.getTo() == null) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ Vector velocity = player.getBukkitEntity().getVelocity();
|
|
+ exitWorld.getDefaultTeleporter().adjustExit(player, exit, velocity);
|
|
+
|
|
+ player.invulnerableDimensionChange = true; // CraftBukkit - Set teleport invulnerability only if player changing worlds
|
|
+
|
|
+ int fromDimension = player.dimension;
|
|
player.dimension = dimensionIn;
|
|
- WorldServer worldserver1 = this.mcServer.getWorld(player.dimension);
|
|
- player.connection.sendPacket(new SPacketRespawn(player.dimension, player.world.getDifficulty(), player.world.getWorldInfo().getTerrainType(), player.interactionManager.getGameType()));
|
|
+
|
|
+ catserver.server.CatServerNetwork.registerBukkitWorldToClient(player, player.dimension); // CatServer - change dim for bukkit added dimensions
|
|
+ player.connection.sendPacket(new SPacketRespawn(player.dimension, exitWorld.getDifficulty(), exitWorld.getWorldInfo().getTerrainType(), player.interactionManager.getGameType()));
|
|
this.updatePermissionLevel(player);
|
|
- worldserver.removeEntityDangerously(player);
|
|
+ fromWorld.removeEntityDangerously(player);
|
|
player.isDead = false;
|
|
- this.transferEntityToWorld(player, i, worldserver, worldserver1);
|
|
- this.preparePlayer(player, worldserver);
|
|
+ this.transferEntityToWorld(player, fromDimension, fromWorld, exitWorld, teleporter);
|
|
+ this.preparePlayer(player, fromWorld);
|
|
player.connection.setPlayerLocation(player.posX, player.posY, player.posZ, player.rotationYaw, player.rotationPitch);
|
|
- player.interactionManager.setWorld(worldserver1);
|
|
+ player.interactionManager.setWorld(exitWorld);
|
|
player.connection.sendPacket(new SPacketPlayerAbilities(player.capabilities));
|
|
- this.updateTimeAndWeatherForPlayer(player, worldserver1);
|
|
+ this.updateTimeAndWeatherForPlayer(player, exitWorld);
|
|
this.syncPlayerInventory(player);
|
|
|
|
for (PotionEffect potioneffect : player.getActivePotionEffects())
|
|
{
|
|
player.connection.sendPacket(new SPacketEntityEffect(player.getEntityId(), potioneffect));
|
|
}
|
|
+ // Fix MC-88179: on non-death SPacketRespawn, also resend attributes
|
|
+ net.minecraft.entity.ai.attributes.AttributeMap attributemap = (net.minecraft.entity.ai.attributes.AttributeMap) player.getAttributeMap();
|
|
+ java.util.Collection<net.minecraft.entity.ai.attributes.IAttributeInstance> watchedAttribs = attributemap.getWatchedAttributes();
|
|
+ if (!watchedAttribs.isEmpty()) player.connection.sendPacket(new net.minecraft.network.play.server.SPacketEntityProperties(player.getEntityId(), watchedAttribs));
|
|
+
|
|
+ net.minecraftforge.fml.common.FMLCommonHandler.instance().firePlayerChangedDimensionEvent(player, fromDimension, dimensionIn);
|
|
}
|
|
|
|
+ public void changeDimension(EntityPlayerMP player, int dimensionIn, PlayerTeleportEvent.TeleportCause cause) {
|
|
+ transferPlayerToDimension(player, dimensionIn, mcServer.getWorld(dimensionIn).getDefaultTeleporter(), cause);
|
|
+ }
|
|
+ // CatServer end
|
|
+
|
|
public void transferEntityToWorld(Entity entityIn, int lastDimension, WorldServer oldWorldIn, WorldServer toWorldIn)
|
|
{
|
|
- double d0 = entityIn.posX;
|
|
- double d1 = entityIn.posZ;
|
|
+ // transferEntityToWorld(entityIn, lastDimension, oldWorldIn, toWorldIn, toWorldIn.getDefaultTeleporter());
|
|
+ Location exit = this.calculateTarget(entityIn.getBukkitEntity().getLocation(), toWorldIn);
|
|
+ this.repositionEntity(entityIn, exit, true);
|
|
+ }
|
|
+
|
|
+ // TODO: Remove (1.13)
|
|
+ public void transferEntityToWorld(Entity entityIn, int lastDimension, WorldServer oldWorldIn, WorldServer toWorldIn, net.minecraft.world.Teleporter teleporter)
|
|
+ {
|
|
+ transferEntityToWorld(entityIn, lastDimension, oldWorldIn, toWorldIn, (net.minecraftforge.common.util.ITeleporter) teleporter);
|
|
+ }
|
|
+
|
|
+ public void transferEntityToWorld(Entity entityIn, int lastDimension, WorldServer oldWorldIn, WorldServer toWorldIn, net.minecraftforge.common.util.ITeleporter teleporter)
|
|
+ {
|
|
+ double moveFactor = oldWorldIn.provider.getMovementFactor() / toWorldIn.provider.getMovementFactor();
|
|
+ double d0 = MathHelper.clamp(entityIn.posX * moveFactor, toWorldIn.getWorldBorder().minX() + 16.0D, toWorldIn.getWorldBorder().maxX() - 16.0D);
|
|
+ double d1 = MathHelper.clamp(entityIn.posZ * moveFactor, toWorldIn.getWorldBorder().minZ() + 16.0D, toWorldIn.getWorldBorder().maxZ() - 16.0D);
|
|
double d2 = 8.0D;
|
|
float f = entityIn.rotationYaw;
|
|
oldWorldIn.profiler.startSection("moving");
|
|
|
|
- if (entityIn.dimension == -1)
|
|
+ if (false && entityIn.dimension == -1)
|
|
{
|
|
d0 = MathHelper.clamp(d0 / 8.0D, toWorldIn.getWorldBorder().minX() + 16.0D, toWorldIn.getWorldBorder().maxX() - 16.0D);
|
|
d1 = MathHelper.clamp(d1 / 8.0D, toWorldIn.getWorldBorder().minZ() + 16.0D, toWorldIn.getWorldBorder().maxZ() - 16.0D);
|
|
@@ -597,7 +1104,7 @@
|
|
oldWorldIn.updateEntityWithOptionalForce(entityIn, false);
|
|
}
|
|
}
|
|
- else if (entityIn.dimension == 0)
|
|
+ else if (false && entityIn.dimension == 0)
|
|
{
|
|
d0 = MathHelper.clamp(d0 * 8.0D, toWorldIn.getWorldBorder().minX() + 16.0D, toWorldIn.getWorldBorder().maxX() - 16.0D);
|
|
d1 = MathHelper.clamp(d1 * 8.0D, toWorldIn.getWorldBorder().minZ() + 16.0D, toWorldIn.getWorldBorder().maxZ() - 16.0D);
|
|
@@ -608,7 +1115,7 @@
|
|
oldWorldIn.updateEntityWithOptionalForce(entityIn, false);
|
|
}
|
|
}
|
|
- else
|
|
+ if (entityIn.dimension == 1 && teleporter.isVanilla())
|
|
{
|
|
BlockPos blockpos;
|
|
|
|
@@ -634,7 +1141,7 @@
|
|
|
|
oldWorldIn.profiler.endSection();
|
|
|
|
- if (lastDimension != 1)
|
|
+ if (lastDimension != 1 || !teleporter.isVanilla())
|
|
{
|
|
oldWorldIn.profiler.startSection("placing");
|
|
d0 = (double)MathHelper.clamp((int)d0, -29999872, 29999872);
|
|
@@ -643,7 +1150,8 @@
|
|
if (entityIn.isEntityAlive())
|
|
{
|
|
entityIn.setLocationAndAngles(d0, entityIn.posY, d1, entityIn.rotationYaw, entityIn.rotationPitch);
|
|
- toWorldIn.getDefaultTeleporter().placeInPortal(entityIn, f);
|
|
+ oldWorldIn.updateEntityWithOptionalForce(entityIn, false);
|
|
+ teleporter.placeEntity(toWorldIn, entityIn, f);
|
|
toWorldIn.spawnEntity(entityIn);
|
|
toWorldIn.updateEntityWithOptionalForce(entityIn, false);
|
|
}
|
|
@@ -654,11 +1162,155 @@
|
|
entityIn.setWorld(toWorldIn);
|
|
}
|
|
|
|
+ // Copy of original transferEntityToWorld(Entity, int, WorldServer, WorldServer) method with only location calculation logic
|
|
+ public Location calculateTarget(Location enter, World target) {
|
|
+ WorldServer worldserver = ((CraftWorld) enter.getWorld()).getHandle();
|
|
+ WorldServer worldserver1 = ((CraftWorld) target.getWorld()).getHandle();
|
|
+ int i = worldserver.dimension;
|
|
+
|
|
+ double y = enter.getY();
|
|
+ float yaw = enter.getYaw();
|
|
+ float pitch = enter.getPitch();
|
|
+ double d0 = enter.getX();
|
|
+ double d1 = enter.getZ();
|
|
+ double d2 = 8.0D;
|
|
+
|
|
+ worldserver.profiler.startSection("moving");
|
|
+ if (worldserver1.dimension == -1) {
|
|
+ d0 = MathHelper.clamp(d0 / d2, worldserver1.getWorldBorder().minX()+ 16.0D, worldserver1.getWorldBorder().maxX() - 16.0D);
|
|
+ d1 = MathHelper.clamp(d1 / d2, worldserver1.getWorldBorder().minZ() + 16.0D, worldserver1.getWorldBorder().maxZ() - 16.0D);
|
|
+ } else if (worldserver1.dimension == 0) {
|
|
+ d0 = MathHelper.clamp(d0 * d2, worldserver1.getWorldBorder().minX() + 16.0D, worldserver1.getWorldBorder().maxX() - 16.0D);
|
|
+ d1 = MathHelper.clamp(d1 * d2, worldserver1.getWorldBorder().minZ() + 16.0D, worldserver1.getWorldBorder().maxZ() - 16.0D);
|
|
+ } else {
|
|
+ BlockPos blockposition;
|
|
+
|
|
+ if (i == 1) {
|
|
+ // use default NORMAL world spawn instead of target
|
|
+ worldserver1 = this.mcServer.worldServerList.get(0);
|
|
+ blockposition = worldserver1.getSpawnPoint();
|
|
+ } else {
|
|
+ blockposition = worldserver1.getSpawnCoordinate();
|
|
+ }
|
|
+
|
|
+ // CatServer start - check null
|
|
+ if (blockposition != null)
|
|
+ {
|
|
+ d0 = (double) blockposition.getX();
|
|
+ y = (double) blockposition.getY();
|
|
+ d1 = (double) blockposition.getZ();
|
|
+ }
|
|
+ // CatServer end
|
|
+ }
|
|
+
|
|
+ worldserver.profiler.endSection();
|
|
+ if (i != 1) {
|
|
+ worldserver.profiler.startSection("placing");
|
|
+ d0 = (double) MathHelper.clamp((int) d0, -29999872, 29999872);
|
|
+ d1 = (double) MathHelper.clamp((int) d1, -29999872, 29999872);
|
|
+ worldserver.profiler.endSection();
|
|
+ }
|
|
+
|
|
+ return new Location(worldserver1.getWorld(), d0, y, d1, yaw, pitch);
|
|
+ }
|
|
+
|
|
+ // copy of original transferEntityToWorld(Entity, int, WorldServer, WorldServer) method with only entity repositioning logic
|
|
+ public void repositionEntity(Entity entity, Location exit, boolean portal) {
|
|
+ WorldServer worldserver = (WorldServer) entity.world;
|
|
+ WorldServer worldserver1 = ((CraftWorld) exit.getWorld()).getHandle();
|
|
+ int i = worldserver.dimension;
|
|
+
|
|
+ /*
|
|
+ double d0 = entity.locX;
|
|
+ double d1 = entity.locZ;
|
|
+ double d2 = 8.0D;
|
|
+ float f = entity.yaw;
|
|
+ */
|
|
+
|
|
+ worldserver.profiler.startSection("moving");
|
|
+ entity.setLocationAndAngles(exit.getX(), exit.getY(), exit.getZ(), exit.getYaw(), exit.getPitch());
|
|
+ if (entity.isEntityAlive()) {
|
|
+ worldserver.updateEntityWithOptionalForce(entity, false);
|
|
+ }
|
|
+ /*
|
|
+ if (entity.dimension == -1) {
|
|
+ d0 = MathHelper.a(d0 / 8.0D, worldserver1.getWorldBorder().b() + 16.0D, worldserver1.getWorldBorder().d() - 16.0D);
|
|
+ d1 = MathHelper.a(d1 / 8.0D, worldserver1.getWorldBorder().c() + 16.0D, worldserver1.getWorldBorder().e() - 16.0D);
|
|
+ entity.setPositionRotation(d0, entity.locY, d1, entity.yaw, entity.pitch);
|
|
+ if (entity.isAlive()) {
|
|
+ worldserver.entityJoinedWorld(entity, false);
|
|
+ }
|
|
+ } else if (entity.dimension == 0) {
|
|
+ d0 = MathHelper.a(d0 * 8.0D, worldserver1.getWorldBorder().b() + 16.0D, worldserver1.getWorldBorder().d() - 16.0D);
|
|
+ d1 = MathHelper.a(d1 * 8.0D, worldserver1.getWorldBorder().c() + 16.0D, worldserver1.getWorldBorder().e() - 16.0D);
|
|
+ entity.setPositionRotation(d0, entity.locY, d1, entity.yaw, entity.pitch);
|
|
+ if (entity.isAlive()) {
|
|
+ worldserver.entityJoinedWorld(entity, false);
|
|
+ }
|
|
+ } else {
|
|
+ BlockPosition blockposition;
|
|
+
|
|
+ if (i == 1) {
|
|
+ // use default NORMAL world spawn instead of target
|
|
+ worldserver1 = this.server.worlds.get(0);
|
|
+ blockposition = worldserver1.getSpawn();
|
|
+ } else {
|
|
+ blockposition = worldserver1.getDimensionSpawn();
|
|
+ }
|
|
+
|
|
+ d0 = (double) blockposition.getX();
|
|
+ entity.locY = (double) blockposition.getY();
|
|
+ d1 = (double) blockposition.getZ();
|
|
+ entity.setPositionRotation(d0, entity.locY, d1, 90.0F, 0.0F);
|
|
+ if (entity.isAlive()) {
|
|
+ worldserver.entityJoinedWorld(entity, false);
|
|
+ }
|
|
+ }
|
|
+ */
|
|
+
|
|
+ worldserver.profiler.endSection();
|
|
+ if (i != 1) {
|
|
+ worldserver.profiler.startSection("placing");
|
|
+ /*
|
|
+ d0 = (double) MathHelper.clamp((int) d0, -29999872, 29999872);
|
|
+ d1 = (double) MathHelper.clamp((int) d1, -29999872, 29999872);
|
|
+ */
|
|
+ if (entity.isEntityAlive()) {
|
|
+ // entity.setPositionRotation(d0, entity.locY, d1, entity.yaw, entity.pitch);
|
|
+ // worldserver1.getTravelAgent().a(entity, f);
|
|
+ if (portal) {
|
|
+ Vector velocity = entity.getBukkitEntity().getVelocity();
|
|
+ worldserver1.getDefaultTeleporter().adjustExit(entity, exit, velocity);
|
|
+ entity.setLocationAndAngles(exit.getX(), exit.getY(), exit.getZ(), exit.getYaw(), exit.getPitch());
|
|
+ if (entity.motionX != velocity.getX() || entity.motionY != velocity.getY() || entity.motionZ != velocity.getZ()) {
|
|
+ entity.getBukkitEntity().setVelocity(velocity);
|
|
+ }
|
|
+ }
|
|
+ // worldserver1.addEntity(entity);
|
|
+ worldserver1.updateEntityWithOptionalForce(entity, false);
|
|
+ }
|
|
+
|
|
+ worldserver.profiler.endSection();
|
|
+ }
|
|
+
|
|
+ entity.setWorld(worldserver1);
|
|
+ }
|
|
+
|
|
public void onTick()
|
|
{
|
|
if (++this.playerPingIndex > 600)
|
|
{
|
|
- this.sendPacketToAllPlayers(new SPacketPlayerListItem(SPacketPlayerListItem.Action.UPDATE_LATENCY, this.playerEntityList));
|
|
+ // this.sendPacketToAllPlayers(new SPacketPlayerListItem(SPacketPlayerListItem.Action.UPDATE_LATENCY, this.playerEntityList));
|
|
+ for (int i = 0; i < this.playerEntityList.size(); ++i) {
|
|
+ final EntityPlayerMP target = this.playerEntityList.get(i);
|
|
+
|
|
+ target.connection.sendPacket(new SPacketPlayerListItem(SPacketPlayerListItem.Action.UPDATE_LATENCY, Iterables.filter(this.playerEntityList, new Predicate<EntityPlayerMP>() {
|
|
+ @Override
|
|
+ public boolean apply(EntityPlayerMP input) {
|
|
+ return target.getBukkitEntity().canSee(input.getBukkitEntity());
|
|
+ }
|
|
+ })));
|
|
+ }
|
|
this.playerPingIndex = 0;
|
|
}
|
|
}
|
|
@@ -671,6 +1323,24 @@
|
|
}
|
|
}
|
|
|
|
+ // CraftBukkit start - add a world/entity limited version
|
|
+ public void sendAll(Packet packet, EntityPlayer entityhuman) {
|
|
+ for (int i = 0; i < this.playerEntityList.size(); ++i) {
|
|
+ EntityPlayerMP entityplayer = this.playerEntityList.get(i);
|
|
+ if (entityhuman != null && entityhuman instanceof EntityPlayerMP && !entityplayer.getBukkitEntity().canSee(((EntityPlayerMP) entityhuman).getBukkitEntity())) {
|
|
+ continue;
|
|
+ }
|
|
+ ((EntityPlayerMP) this.playerEntityList.get(i)).connection.sendPacket(packet);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public void sendAll(Packet packet, World world) {
|
|
+ for (int i = 0; i < world.playerEntities.size(); ++i) {
|
|
+ ((EntityPlayerMP) world.playerEntities.get(i)).connection.sendPacket(packet);
|
|
+ }
|
|
+ }
|
|
+ // CraftBukkit end
|
|
+
|
|
public void sendPacketToAllPlayersInDimension(Packet<?> packetIn, int dimension)
|
|
{
|
|
for (int i = 0; i < this.playerEntityList.size(); ++i)
|
|
@@ -786,12 +1456,20 @@
|
|
int i = this.mcServer.getOpPermissionLevel();
|
|
this.ops.addEntry(new UserListOpsEntry(profile, this.mcServer.getOpPermissionLevel(), this.ops.bypassesPlayerLimit(profile)));
|
|
this.sendPlayerPermissionLevel(this.getPlayerByUUID(profile.getId()), i);
|
|
+ Player player = mcServer.server.getPlayer(profile.getId());
|
|
+ if (player != null) {
|
|
+ player.recalculatePermissions();
|
|
+ }
|
|
}
|
|
|
|
public void removeOp(GameProfile profile)
|
|
{
|
|
this.ops.removeEntry(profile);
|
|
this.sendPlayerPermissionLevel(this.getPlayerByUUID(profile.getId()), 0);
|
|
+ Player player = mcServer.server.getPlayer(profile.getId());
|
|
+ if (player != null) {
|
|
+ player.recalculatePermissions();
|
|
+ }
|
|
}
|
|
|
|
private void sendPlayerPermissionLevel(EntityPlayerMP player, int permLevel)
|
|
@@ -824,7 +1502,7 @@
|
|
|
|
public boolean canSendCommands(GameProfile profile)
|
|
{
|
|
- return this.ops.hasEntry(profile) || this.mcServer.isSinglePlayer() && this.mcServer.worlds[0].getWorldInfo().areCommandsAllowed() && this.mcServer.getServerOwner().equalsIgnoreCase(profile.getName()) || this.commandsAllowedForAll;
|
|
+ return this.ops.hasEntry(profile) || this.mcServer.isSinglePlayer() && this.mcServer.worldServerList.get(0).getWorldInfo().areCommandsAllowed() && this.mcServer.getServerOwner().equalsIgnoreCase(profile.getName()) || this.commandsAllowedForAll;
|
|
}
|
|
|
|
@Nullable
|
|
@@ -847,6 +1525,12 @@
|
|
{
|
|
EntityPlayerMP entityplayermp = this.playerEntityList.get(i);
|
|
|
|
+ // CraftBukkit start - Test if player receiving packet can see the source of the packet
|
|
+ if (except != null && except instanceof EntityPlayerMP && !entityplayermp.getBukkitEntity().canSee(((EntityPlayerMP) except).getBukkitEntity())) {
|
|
+ continue;
|
|
+ }
|
|
+ // CraftBukkit end
|
|
+
|
|
if (entityplayermp != except && entityplayermp.dimension == dimension)
|
|
{
|
|
double d0 = x - entityplayermp.posX;
|
|
@@ -905,7 +1589,7 @@
|
|
|
|
public void updateTimeAndWeatherForPlayer(EntityPlayerMP playerIn, WorldServer worldIn)
|
|
{
|
|
- WorldBorder worldborder = this.mcServer.worlds[0].getWorldBorder();
|
|
+ WorldBorder worldborder = this.mcServer.worldServerList.get(0).getWorldBorder();
|
|
playerIn.connection.sendPacket(new SPacketWorldBorder(worldborder, SPacketWorldBorder.Action.INITIALIZE));
|
|
playerIn.connection.sendPacket(new SPacketTimeUpdate(worldIn.getTotalWorldTime(), worldIn.getWorldTime(), worldIn.getGameRules().getBoolean("doDaylightCycle")));
|
|
BlockPos blockpos = worldIn.getSpawnPoint();
|
|
@@ -913,16 +1597,21 @@
|
|
|
|
if (worldIn.isRaining())
|
|
{
|
|
- playerIn.connection.sendPacket(new SPacketChangeGameState(1, 0.0F));
|
|
- playerIn.connection.sendPacket(new SPacketChangeGameState(7, worldIn.getRainStrength(1.0F)));
|
|
- playerIn.connection.sendPacket(new SPacketChangeGameState(8, worldIn.getThunderStrength(1.0F)));
|
|
+ // CraftBukkit start - handle player weather
|
|
+ // playerIn.connection.sendPacket(new SPacketChangeGameState(1, 0.0F));
|
|
+ // playerIn.connection.sendPacket(new SPacketChangeGameState(7, worldIn.getRainStrength(1.0F)));
|
|
+ // playerIn.connection.sendPacket(new SPacketChangeGameState(8, worldIn.getThunderStrength(1.0F)));
|
|
+ playerIn.setPlayerWeather(org.bukkit.WeatherType.DOWNFALL, false);
|
|
+ playerIn.updateWeather(-worldIn.rainingStrength, worldIn.rainingStrength, -worldIn.thunderingStrength, worldIn.thunderingStrength);
|
|
+ // CraftBukkit end
|
|
}
|
|
}
|
|
|
|
public void syncPlayerInventory(EntityPlayerMP playerIn)
|
|
{
|
|
playerIn.sendContainerToPlayer(playerIn.inventoryContainer);
|
|
- playerIn.setPlayerHealthUpdated();
|
|
+ // playerIn.setPlayerHealthUpdated();
|
|
+ playerIn.getBukkitEntity().updateScaledHealth(); // CraftBukkit - Update scaled health on respawn and worldchange
|
|
playerIn.connection.sendPacket(new SPacketHeldItemChange(playerIn.inventory.currentItem));
|
|
}
|
|
|
|
@@ -938,7 +1627,7 @@
|
|
|
|
public String[] getAvailablePlayerDat()
|
|
{
|
|
- return this.mcServer.worlds[0].getSaveHandler().getPlayerNBTManager().getAvailablePlayerDat();
|
|
+ return this.mcServer.worldServerList.get(0).getSaveHandler().getPlayerNBTManager().getAvailablePlayerDat();
|
|
}
|
|
|
|
public void setWhiteListEnabled(boolean whitelistEnabled)
|
|
@@ -1004,17 +1693,26 @@
|
|
|
|
public void removeAllPlayers()
|
|
{
|
|
- for (int i = 0; i < this.playerEntityList.size(); ++i)
|
|
- {
|
|
- (this.playerEntityList.get(i)).connection.disconnect(new TextComponentTranslation("multiplayer.disconnect.server_shutdown", new Object[0]));
|
|
+ // CraftBukkit start - disconnect safely
|
|
+ for (EntityPlayerMP player : this.playerEntityList) {
|
|
+ player.connection.disconnect(this.mcServer.server.getShutdownMessage()); // CraftBukkit - add custom shutdown message
|
|
}
|
|
}
|
|
|
|
+ public void sendMessage(ITextComponent[] iChatBaseComponents) {
|
|
+ for (ITextComponent component : iChatBaseComponents) {
|
|
+ sendMessage(component, true);
|
|
+ }
|
|
+ }
|
|
+
|
|
public void sendMessage(ITextComponent component, boolean isSystem)
|
|
{
|
|
this.mcServer.sendMessage(component);
|
|
ChatType chattype = isSystem ? ChatType.SYSTEM : ChatType.CHAT;
|
|
- this.sendPacketToAllPlayers(new SPacketChat(component, chattype));
|
|
+ // this.sendPacketToAllPlayers(new SPacketChat(component, chattype));
|
|
+ // CraftBukkit start - we run this through our processor first so we can get web links etc
|
|
+ this.sendPacketToAllPlayers(new SPacketChat(CraftChatMessage.fixComponent(component), chattype));
|
|
+ // CraftBukkit end
|
|
}
|
|
|
|
public void sendMessage(ITextComponent component)
|
|
@@ -1022,6 +1720,7 @@
|
|
this.sendMessage(component, true);
|
|
}
|
|
|
|
+ @Nullable
|
|
public StatisticsManagerServer getPlayerStatsFile(EntityPlayer playerIn)
|
|
{
|
|
UUID uuid = playerIn.getUniqueID();
|
|
@@ -1050,6 +1749,8 @@
|
|
return statisticsmanagerserver;
|
|
}
|
|
|
|
+ public StatisticsManagerServer getStatisticManager(EntityPlayerMP playerIn) { return getPlayerStatsFile(playerIn); } // CatServer - Add CraftBukkit method
|
|
+
|
|
public PlayerAdvancements getPlayerAdvancements(EntityPlayerMP p_192054_1_)
|
|
{
|
|
UUID uuid = p_192054_1_.getUniqueID();
|
|
@@ -1073,7 +1774,7 @@
|
|
|
|
if (this.mcServer.worlds != null)
|
|
{
|
|
- for (WorldServer worldserver : this.mcServer.worlds)
|
|
+ for (WorldServer worldserver : this.mcServer.worldServerList)
|
|
{
|
|
if (worldserver != null)
|
|
{
|