use of net.minecraft.world.WorldServer in project SpongeCommon by SpongePowered.
the class MixinNetHandlerPlayServer method processUseEntity.
/**
* @author blood - April 5th, 2016
*
* @reason Due to all the changes we now do for this packet, it is much easier
* to read it all with an overwrite. Information detailing on why each change
* was made can be found in comments below.
*
* @param packetIn The entity use packet
*/
@Overwrite
public void processUseEntity(CPacketUseEntity packetIn) {
// All packets received by server are handled first on the Netty Thread
if (!SpongeImpl.getServer().isCallingFromMinecraftThread()) {
if (packetIn.getAction() == CPacketUseEntity.Action.INTERACT) {
// when INTERACT_AT does not return a successful result.
return;
} else {
// queue packet for main thread
PacketThreadUtil.checkThreadAndEnqueue(packetIn, (NetHandlerPlayServer) (Object) this, this.player.getServerWorld());
return;
}
}
// Sponge end
WorldServer worldserver = this.serverController.getWorld(this.player.dimension);
Entity entity = packetIn.getEntityFromWorld(worldserver);
this.player.markPlayerActive();
if (entity != null) {
boolean flag = this.player.canEntityBeSeen(entity);
// 6 blocks
double d0 = 36.0D;
if (!flag) {
// 1.5 blocks
d0 = 9.0D;
}
if (this.player.getDistanceSq(entity) < d0) {
if (packetIn.getAction() == CPacketUseEntity.Action.INTERACT_AT) {
// Sponge start - Fire interact events
EnumHand hand = packetIn.getHand();
ItemStack itemstack = hand != null ? this.player.getHeldItem(hand) : ItemStack.EMPTY;
Sponge.getCauseStackManager().addContext(EventContextKeys.USED_ITEM, ItemStackUtil.snapshotOf(itemstack));
SpongeCommonEventFactory.lastSecondaryPacketTick = this.serverController.getTickCounter();
// Is interaction allowed with item in hand
if (SpongeCommonEventFactory.callInteractItemEventSecondary(this.player, itemstack, hand, VecHelper.toVector3d(packetIn.getHitVec()), entity).isCancelled() || SpongeCommonEventFactory.callInteractEntityEventSecondary(this.player, entity, hand, VecHelper.toVector3d(entity.getPositionVector().add(packetIn.getHitVec()))).isCancelled()) {
// Restore held item in hand
int index = ((IMixinInventoryPlayer) this.player.inventory).getHeldItemIndex(hand);
Slot slot = this.player.openContainer.getSlotFromInventory(this.player.inventory, index);
sendPacket(new SPacketSetSlot(this.player.openContainer.windowId, slot.slotNumber, itemstack));
// which means that we need to force an update
if (itemstack.getItem() == Items.LEAD) {
// Detach entity again
sendPacket(new SPacketEntityAttach(entity, null));
} else {
// Other cases may involve a specific DataParameter of the entity
// We fix the client state by marking it as dirty so it will be updated on the client the next tick
DataParameter<?> parameter = findModifiedEntityInteractDataParameter(itemstack, entity);
if (parameter != null) {
entity.getDataManager().setDirty(parameter);
}
}
return;
}
// If INTERACT_AT is not successful, run the INTERACT logic
if (entity.applyPlayerInteraction(this.player, packetIn.getHitVec(), hand) != EnumActionResult.SUCCESS) {
this.player.interactOn(entity, hand);
}
// Sponge end
} else if (packetIn.getAction() == CPacketUseEntity.Action.ATTACK) {
// Sponge start - Call interact event
// Will be null in the packet during ATTACK
EnumHand hand = EnumHand.MAIN_HAND;
ItemStack itemstack = this.player.getHeldItem(hand);
SpongeCommonEventFactory.lastPrimaryPacketTick = this.serverController.getTickCounter();
Vector3d hitVec = null;
if (packetIn.getHitVec() == null) {
final RayTraceResult result = SpongeImplHooks.rayTraceEyes(player, SpongeImplHooks.getBlockReachDistance(player));
hitVec = result == null ? null : VecHelper.toVector3d(result.hitVec);
}
if (SpongeCommonEventFactory.callInteractItemEventPrimary(this.player, itemstack, hand, hitVec, entity).isCancelled()) {
((IMixinEntityPlayerMP) this.player).restorePacketItem(hand);
return;
}
if (entity instanceof EntityItem || entity instanceof EntityXPOrb || entity instanceof EntityArrow || entity == this.player) {
this.disconnect(new TextComponentTranslation("multiplayer.disconnect.invalid_entity_attacked"));
this.serverController.logWarning("Player " + this.player.getName() + " tried to attack an invalid entity");
return;
}
// Sponge start
if (entity instanceof Player && !((World) this.player.world).getProperties().isPVPEnabled()) {
// PVP is disabled, ignore
return;
}
if (SpongeCommonEventFactory.callInteractEntityEventPrimary(this.player, entity, hand, hitVec).isCancelled()) {
((IMixinEntityPlayerMP) this.player).restorePacketItem(hand);
return;
}
// Sponge end
this.player.attackTargetEntityWithCurrentItem(entity);
}
}
}
}
use of net.minecraft.world.WorldServer in project SpongeCommon by SpongePowered.
the class MixinMinecraftServer method onUpdateTimeLightAndEntitiesHead.
// All chunk unload queuing needs to be processed BEFORE the future tasks are run as mods/plugins may have tasks that request chunks.
// This prevents a situation where a chunk is requested to load then unloads at end of tick.
@Inject(method = "updateTimeLightAndEntities", at = @At("HEAD"))
public void onUpdateTimeLightAndEntitiesHead(CallbackInfo ci) {
for (int i = 0; i < this.worlds.length; ++i) {
WorldServer worldServer = this.worlds[i];
// ChunkGC needs to be processed before a world tick in order to guarantee any chunk queued for unload
// can still be marked active and avoid unload if accessed during the same tick.
// Note: This injection must come before Forge's pre world tick event or it will cause issues with mods.
IMixinWorldServer spongeWorld = (IMixinWorldServer) worldServer;
if (spongeWorld.getChunkGCTickInterval() > 0) {
spongeWorld.doChunkGC();
}
// Moved from PlayerChunkMap to avoid chunks from unloading after being requested in same tick
if (worldServer.getPlayerChunkMap().players.isEmpty()) {
WorldProvider worldprovider = worldServer.provider;
if (!worldprovider.canRespawnHere()) {
worldServer.getChunkProvider().queueUnloadAll();
}
}
}
}
use of net.minecraft.world.WorldServer in project SpongeCommon by SpongePowered.
the class MixinPlayerList method playerLoggedIn2.
@Inject(method = "playerLoggedIn", at = @At(value = "INVOKE", target = SERVER_SEND_PACKET_TO_ALL_PLAYERS, shift = At.Shift.BEFORE), cancellable = true)
public void playerLoggedIn2(EntityPlayerMP player, CallbackInfo ci) {
// Create a packet to be used for players without context data
SPacketPlayerListItem noSpecificViewerPacket = new SPacketPlayerListItem(SPacketPlayerListItem.Action.ADD_PLAYER, player);
for (EntityPlayerMP viewer : this.playerEntityList) {
if (((Player) viewer).canSee((Player) player)) {
viewer.connection.sendPacket(noSpecificViewerPacket);
}
if (((Player) player).canSee((Player) viewer)) {
player.connection.sendPacket(new SPacketPlayerListItem(SPacketPlayerListItem.Action.ADD_PLAYER, viewer));
}
}
// Spawn player into level
WorldServer level = this.mcServer.getWorld(player.dimension);
// TODO direct this appropriately
level.spawnEntity(player);
this.preparePlayer(player, null);
// We always want to cancel.
ci.cancel();
}
use of net.minecraft.world.WorldServer in project SpongeCommon by SpongePowered.
the class MixinPlayerList method initializeConnectionToPlayer.
public void initializeConnectionToPlayer(NetworkManager netManager, EntityPlayerMP playerIn, @Nullable NetHandlerPlayServer handler) {
GameProfile gameprofile = playerIn.getGameProfile();
PlayerProfileCache playerprofilecache = this.mcServer.getPlayerProfileCache();
GameProfile gameprofile1 = playerprofilecache.getProfileByUUID(gameprofile.getId());
String s = gameprofile1 == null ? gameprofile.getName() : gameprofile1.getName();
playerprofilecache.addEntry(gameprofile);
// Sponge start - save changes to offline User before reading player data
SpongeUser user = (SpongeUser) ((IMixinEntityPlayerMP) playerIn).getUserObject();
if (SpongeUser.dirtyUsers.contains(user)) {
user.save();
}
// Sponge end
NBTTagCompound nbttagcompound = this.readPlayerDataFromFile(playerIn);
WorldServer worldServer = this.mcServer.getWorld(playerIn.dimension);
int actualDimensionId = ((IMixinWorldServer) worldServer).getDimensionId();
BlockPos spawnPos = null;
// Join data
Optional<Instant> firstJoined = SpongePlayerDataHandler.getFirstJoined(playerIn.getUniqueID());
Instant lastJoined = Instant.now();
SpongePlayerDataHandler.setPlayerInfo(playerIn.getUniqueID(), firstJoined.orElse(lastJoined), lastJoined);
if (actualDimensionId != playerIn.dimension) {
SpongeImpl.getLogger().warn("Player [{}] has attempted to login to unloaded world [{}]. This is not safe so we have moved them to " + "the default world's spawn point.", playerIn.getName(), playerIn.dimension);
if (!firstJoined.isPresent()) {
spawnPos = SpongeImplHooks.getRandomizedSpawnPoint(worldServer);
} else {
spawnPos = worldServer.getSpawnPoint();
}
playerIn.dimension = actualDimensionId;
playerIn.setPosition(spawnPos.getX(), spawnPos.getY(), spawnPos.getZ());
}
// Sponge start - fire login event
@Nullable String kickReason = allowUserToConnect(netManager.getRemoteAddress(), gameprofile);
Text disconnectMessage;
if (kickReason != null) {
disconnectMessage = SpongeTexts.fromLegacy(kickReason);
} else {
disconnectMessage = Text.of("You are not allowed to log in to this server.");
}
Player player = (Player) playerIn;
Transform<World> fromTransform = player.getTransform().setExtent((World) worldServer);
Sponge.getCauseStackManager().pushCause(player);
ClientConnectionEvent.Login loginEvent = SpongeEventFactory.createClientConnectionEventLogin(Sponge.getCauseStackManager().getCurrentCause(), fromTransform, fromTransform, (RemoteConnection) netManager, new MessageEvent.MessageFormatter(disconnectMessage), (org.spongepowered.api.profile.GameProfile) gameprofile, player, false);
if (kickReason != null) {
loginEvent.setCancelled(true);
}
if (SpongeImpl.postEvent(loginEvent)) {
Sponge.getCauseStackManager().popCause();
disconnectClient(netManager, loginEvent.isMessageCancelled() ? Optional.empty() : Optional.of(loginEvent.getMessage()), gameprofile);
return;
}
Sponge.getCauseStackManager().popCause();
// Sponge end
worldServer = (WorldServer) loginEvent.getToTransform().getExtent();
double x = loginEvent.getToTransform().getPosition().getX();
double y = loginEvent.getToTransform().getPosition().getY();
double z = loginEvent.getToTransform().getPosition().getZ();
float pitch = (float) loginEvent.getToTransform().getPitch();
float yaw = (float) loginEvent.getToTransform().getYaw();
playerIn.dimension = ((IMixinWorldServer) worldServer).getDimensionId();
playerIn.setWorld(worldServer);
playerIn.interactionManager.setWorld((WorldServer) playerIn.world);
playerIn.setPositionAndRotation(x, y, z, yaw, pitch);
// make sure the chunk is loaded for login
worldServer.getChunkProvider().loadChunk(loginEvent.getToTransform().getLocation().getChunkPosition().getX(), loginEvent.getToTransform().getLocation().getChunkPosition().getZ());
// Sponge end
String s1 = "local";
if (netManager.getRemoteAddress() != null) {
s1 = netManager.getRemoteAddress().toString();
}
final WorldInfo worldinfo = worldServer.getWorldInfo();
final BlockPos spawnBlockPos = worldServer.getSpawnPoint();
this.setPlayerGameTypeBasedOnOther(playerIn, null, worldServer);
// Sponge start
if (handler == null) {
// Create the handler here (so the player's gets set)
handler = new NetHandlerPlayServer(this.mcServer, netManager, playerIn);
}
playerIn.connection = handler;
// Sponge end
// Support vanilla clients logging into custom dimensions
final int dimensionId = WorldManager.getClientDimensionId(playerIn, worldServer);
// Send dimension registration
WorldManager.sendDimensionRegistration(playerIn, worldServer.provider);
handler.sendPacket(new SPacketJoinGame(playerIn.getEntityId(), playerIn.interactionManager.getGameType(), worldinfo.isHardcoreModeEnabled(), dimensionId, worldServer.getDifficulty(), this.getMaxPlayers(), worldinfo.getTerrainType(), worldServer.getGameRules().getBoolean("reducedDebugInfo")));
handler.sendPacket(new SPacketCustomPayload("MC|Brand", (new PacketBuffer(Unpooled.buffer())).writeString(this.getServerInstance().getServerModName())));
handler.sendPacket(new SPacketServerDifficulty(worldinfo.getDifficulty(), worldinfo.isDifficultyLocked()));
handler.sendPacket(new SPacketSpawnPosition(spawnBlockPos));
handler.sendPacket(new SPacketPlayerAbilities(playerIn.capabilities));
handler.sendPacket(new SPacketHeldItemChange(playerIn.inventory.currentItem));
this.updatePermissionLevel(playerIn);
playerIn.getStatFile().markAllDirty();
playerIn.getRecipeBook().init(playerIn);
this.mcServer.refreshStatusNextTick();
handler.setPlayerLocation(x, y, z, yaw, pitch);
this.playerLoggedIn(playerIn);
// Sponge start - add world name to message
LOGGER.info(playerIn.getName() + "[" + s1 + "] logged in with entity id " + playerIn.getEntityId() + " in " + worldServer.getWorldInfo().getWorldName() + "(" + ((IMixinWorldServer) worldServer).getDimensionId() + ") at (" + playerIn.posX + ", " + playerIn.posY + ", " + playerIn.posZ + ")");
// Sponge end
this.updateTimeAndWeatherForPlayer(playerIn, worldServer);
// Sponge Start - Use the server's ResourcePack object
Optional<ResourcePack> pack = ((Server) this.mcServer).getDefaultResourcePack();
if (pack.isPresent()) {
((Player) playerIn).sendResourcePack(pack.get());
}
// Sponge End
// Sponge Start
//
// This sends the objective/score creation packets
// to the player, without attempting to remove them from their
// previous scoreboard (which is set in a field initializer).
// This allows #getWorldScoreboard to function
// as normal, without causing issues when it is initialized on the client.
((IMixinEntityPlayerMP) playerIn).initScoreboard();
for (PotionEffect potioneffect : playerIn.getActivePotionEffects()) {
handler.sendPacket(new SPacketEntityEffect(playerIn.getEntityId(), potioneffect));
}
if (nbttagcompound != null) {
if (nbttagcompound.hasKey("RootVehicle", 10)) {
NBTTagCompound nbttagcompound1 = nbttagcompound.getCompoundTag("RootVehicle");
Entity entity2 = AnvilChunkLoader.readWorldEntity(nbttagcompound1.getCompoundTag("Entity"), worldServer, true);
if (entity2 != null) {
UUID uuid = nbttagcompound1.getUniqueId("Attach");
if (entity2.getUniqueID().equals(uuid)) {
playerIn.startRiding(entity2, true);
} else {
for (Entity entity : entity2.getRecursivePassengers()) {
if (entity.getUniqueID().equals(uuid)) {
playerIn.startRiding(entity, true);
break;
}
}
}
if (!playerIn.isRiding()) {
LOGGER.warn("Couldn\'t reattach entity to player");
worldServer.removeEntityDangerously(entity2);
for (Entity entity3 : entity2.getRecursivePassengers()) {
worldServer.removeEntityDangerously(entity3);
}
}
}
} else if (nbttagcompound.hasKey("Riding", 10)) {
Entity entity1 = AnvilChunkLoader.readWorldEntity(nbttagcompound.getCompoundTag("Riding"), worldServer, true);
if (entity1 != null) {
playerIn.startRiding(entity1, true);
}
}
}
playerIn.addSelfToInternalCraftingInventory();
TextComponentTranslation chatcomponenttranslation;
if (!playerIn.getName().equalsIgnoreCase(s)) {
chatcomponenttranslation = new TextComponentTranslation("multiplayer.player.joined.renamed", playerIn.getDisplayName(), s);
} else {
chatcomponenttranslation = new TextComponentTranslation("multiplayer.player.joined", playerIn.getDisplayName());
}
chatcomponenttranslation.getStyle().setColor(TextFormatting.YELLOW);
// Fire PlayerJoinEvent
Text originalMessage = SpongeTexts.toText(chatcomponenttranslation);
MessageChannel originalChannel = player.getMessageChannel();
Sponge.getCauseStackManager().pushCause(player);
final ClientConnectionEvent.Join event = SpongeEventFactory.createClientConnectionEventJoin(Sponge.getCauseStackManager().getCurrentCause(), originalChannel, Optional.of(originalChannel), new MessageEvent.MessageFormatter(originalMessage), player, false);
SpongeImpl.postEvent(event);
Sponge.getCauseStackManager().popCause();
// Send to the channel
if (!event.isMessageCancelled()) {
event.getChannel().ifPresent(channel -> channel.send(player, event.getMessage()));
}
// Sponge end
}
use of net.minecraft.world.WorldServer in project SpongeCommon by SpongePowered.
the class MixinPlayerList method recreatePlayerEntity.
/**
* @author Zidane - June 13th, 2015
* @author simon816 - June 24th, 2015
* @author Zidane - March 29th, 2016
* @author gabizou - June 5th, 2016 - Update for teleportation changes to keep the same player.
*
* @reason - Direct respawning players to use Sponge events
* and process appropriately.
*
* @param playerIn The player being respawned/created
* @param targetDimension The target dimension
* @param conqueredEnd Whether the end was conquered
* @return The new player
*/
@Overwrite
public EntityPlayerMP recreatePlayerEntity(EntityPlayerMP playerIn, int targetDimension, boolean conqueredEnd) {
// UNLESS comming back from the end.
if (!conqueredEnd && targetDimension == 0) {
targetDimension = playerIn.dimension;
}
if (playerIn.isBeingRidden()) {
playerIn.removePassengers();
}
if (playerIn.isRiding()) {
playerIn.dismountRidingEntity();
}
final Player player = (Player) playerIn;
final Transform<World> fromTransform = player.getTransform();
WorldServer worldServer = this.mcServer.getWorld(targetDimension);
Transform<World> toTransform = new Transform<>(EntityUtil.getPlayerRespawnLocation(playerIn, worldServer), Vector3d.ZERO, Vector3d.ZERO);
targetDimension = ((IMixinWorldServer) toTransform.getExtent()).getDimensionId();
Location<World> location = toTransform.getLocation();
// If coming from end, fire a teleport event for plugins
if (conqueredEnd) {
// When leaving the end, players are never placed inside the teleporter but instead "respawned" in the target world
MoveEntityEvent.Teleport teleportEvent = EntityUtil.handleDisplaceEntityTeleportEvent(playerIn, location);
if (teleportEvent.isCancelled()) {
playerIn.queuedEndExit = false;
return playerIn;
}
toTransform = teleportEvent.getToTransform();
location = toTransform.getLocation();
}
// Keep players out of blocks
Vector3d tempPos = player.getLocation().getPosition();
playerIn.setPosition(location.getX(), location.getY(), location.getZ());
while (!((WorldServer) location.getExtent()).getCollisionBoxes(playerIn, playerIn.getEntityBoundingBox()).isEmpty()) {
playerIn.setPosition(playerIn.posX, playerIn.posY + 1.0D, playerIn.posZ);
location = location.add(0, 1, 0);
}
playerIn.setPosition(tempPos.getX(), tempPos.getY(), tempPos.getZ());
// ### PHASE 2 ### Remove player from current dimension
playerIn.getServerWorld().getEntityTracker().removePlayerFromTrackers(playerIn);
playerIn.getServerWorld().getEntityTracker().untrack(playerIn);
playerIn.getServerWorld().getPlayerChunkMap().removePlayer(playerIn);
this.playerEntityList.remove(playerIn);
this.mcServer.getWorld(playerIn.dimension).removeEntityDangerously(playerIn);
final BlockPos bedPos = SpongeImplHooks.getBedLocation(playerIn, targetDimension);
// ### PHASE 3 ### Reset player (if applicable)
// Recreate the player object in order to support Forge's PlayerEvent.Clone
PlayerInteractionManager playerinteractionmanager;
if (this.mcServer.isDemo()) {
playerinteractionmanager = new DemoPlayerInteractionManager(this.mcServer.getWorld(targetDimension));
} else {
playerinteractionmanager = new PlayerInteractionManager(this.mcServer.getWorld(targetDimension));
}
EntityPlayerMP newPlayer = new EntityPlayerMP(SpongeImpl.getServer(), worldServer, playerIn.getGameProfile(), playerinteractionmanager);
newPlayer.connection = playerIn.connection;
newPlayer.copyFrom(playerIn, conqueredEnd);
// set player dimension for RespawnPlayerEvent
newPlayer.dimension = targetDimension;
newPlayer.setEntityId(playerIn.getEntityId());
newPlayer.setCommandStats(playerIn);
newPlayer.setPrimaryHand(playerIn.getPrimaryHand());
// over to the new player
if (bedPos != null) {
newPlayer.setSpawnPoint(bedPos, playerIn.isSpawnForced());
}
for (String s : playerIn.getTags()) {
newPlayer.addTag(s);
}
this.setPlayerGameTypeBasedOnOther(newPlayer, playerIn, worldServer);
newPlayer.setSneaking(false);
// update to safe location
toTransform = toTransform.setLocation(location);
// ### PHASE 4 ### Fire event and set new location on the player
Sponge.getCauseStackManager().pushCause(newPlayer);
final RespawnPlayerEvent event = SpongeEventFactory.createRespawnPlayerEvent(Sponge.getCauseStackManager().getCurrentCause(), fromTransform, toTransform, (Player) playerIn, (Player) newPlayer, EntityUtil.tempIsBedSpawn, !conqueredEnd);
EntityUtil.tempIsBedSpawn = false;
SpongeImpl.postEvent(event);
Sponge.getCauseStackManager().popCause();
((IMixinEntity) player).setLocationAndAngles(event.getToTransform());
toTransform = event.getToTransform();
location = toTransform.getLocation();
if (!(location.getExtent() instanceof WorldServer)) {
SpongeImpl.getLogger().warn("Location set in PlayerRespawnEvent was invalid, using original location instead");
location = event.getFromTransform().getLocation();
}
worldServer = (WorldServer) location.getExtent();
final IMixinWorldServer mixinWorldServer = (IMixinWorldServer) worldServer;
// Set the dimension again in case a plugin changed the target world during RespawnPlayerEvent
newPlayer.dimension = mixinWorldServer.getDimensionId();
newPlayer.setWorld(worldServer);
newPlayer.interactionManager.setWorld(worldServer);
worldServer.getChunkProvider().loadChunk((int) location.getX() >> 4, (int) location.getZ() >> 4);
// ### PHASE 5 ### Respawn player in new world
// Support vanilla clients logging into custom dimensions
final int dimensionId = WorldManager.getClientDimensionId(newPlayer, worldServer);
// Send dimension registration
if (((IMixinEntityPlayerMP) newPlayer).usesCustomClient()) {
WorldManager.sendDimensionRegistration(newPlayer, worldServer.provider);
} else {
// Force vanilla client to refresh its chunk cache if same dimension type
if (fromTransform.getExtent() != worldServer && fromTransform.getExtent().getDimension().getType() == toTransform.getExtent().getDimension().getType()) {
newPlayer.connection.sendPacket(new SPacketRespawn((dimensionId >= 0 ? -1 : 0), worldServer.getDifficulty(), worldServer.getWorldInfo().getTerrainType(), newPlayer.interactionManager.getGameType()));
}
}
newPlayer.connection.sendPacket(new SPacketRespawn(dimensionId, worldServer.getDifficulty(), worldServer.getWorldInfo().getTerrainType(), newPlayer.interactionManager.getGameType()));
newPlayer.connection.setPlayerLocation(location.getX(), location.getY(), location.getZ(), (float) toTransform.getYaw(), (float) toTransform.getPitch());
final BlockPos spawnLocation = worldServer.getSpawnPoint();
newPlayer.connection.sendPacket(new SPacketSpawnPosition(spawnLocation));
newPlayer.connection.sendPacket(new SPacketSetExperience(newPlayer.experience, newPlayer.experienceTotal, newPlayer.experienceLevel));
this.updateTimeAndWeatherForPlayer(newPlayer, worldServer);
this.updatePermissionLevel(newPlayer);
worldServer.getPlayerChunkMap().addPlayer(newPlayer);
org.spongepowered.api.entity.Entity spongeEntity = (org.spongepowered.api.entity.Entity) newPlayer;
((org.spongepowered.api.world.World) worldServer).spawnEntity(spongeEntity);
this.playerEntityList.add(newPlayer);
this.uuidToPlayerMap.put(newPlayer.getUniqueID(), newPlayer);
newPlayer.addSelfToInternalCraftingInventory();
// Update reducedDebugInfo game rule
newPlayer.connection.sendPacket(new SPacketEntityStatus(newPlayer, worldServer.getGameRules().getBoolean(DefaultGameRules.REDUCED_DEBUG_INFO) ? (byte) 22 : 23));
for (PotionEffect potioneffect : newPlayer.getActivePotionEffects()) {
newPlayer.connection.sendPacket(new SPacketEntityEffect(newPlayer.getEntityId(), potioneffect));
}
((IMixinEntityPlayerMP) newPlayer).refreshScaledHealth();
return newPlayer;
}
Aggregations