mirror of
https://github.com/barkeser2002/CatServer.git
synced 2026-09-25 09:26:08 +03:00
1262 lines
64 KiB
Diff
1262 lines
64 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,14 @@
|
|
}
|
|
|
|
EntityPlayerMP entityplayermp = new EntityPlayerMP(this.mcServer, this.mcServer.getWorld(playerIn.dimension), playerIn.getGameProfile(), playerinteractionmanager);
|
|
+ */
|
|
+ EntityPlayerMP entityplayermp = playerIn;
|
|
+ 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 +865,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 +969,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 +1098,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 +1109,7 @@
|
|
oldWorldIn.updateEntityWithOptionalForce(entityIn, false);
|
|
}
|
|
}
|
|
- else
|
|
+ if (entityIn.dimension == 1 && teleporter.isVanilla())
|
|
{
|
|
BlockPos blockpos;
|
|
|
|
@@ -634,7 +1135,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 +1144,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 +1156,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 +1317,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 +1450,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 +1496,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 +1519,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 +1583,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 +1591,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 +1621,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 +1687,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 +1714,7 @@
|
|
this.sendMessage(component, true);
|
|
}
|
|
|
|
+ @Nullable
|
|
public StatisticsManagerServer getPlayerStatsFile(EntityPlayer playerIn)
|
|
{
|
|
UUID uuid = playerIn.getUniqueID();
|
|
@@ -1050,6 +1743,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 +1768,7 @@
|
|
|
|
if (this.mcServer.worlds != null)
|
|
{
|
|
- for (WorldServer worldserver : this.mcServer.worlds)
|
|
+ for (WorldServer worldserver : this.mcServer.worldServerList)
|
|
{
|
|
if (worldserver != null)
|
|
{
|