--- a/net/minecraft/server/level/ServerPlayer.java +++ b/net/minecraft/server/level/ServerPlayer.java @@ -393,6 +_,7 @@ public com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper - PlayerNaturallySpawnCreaturesEvent public @Nullable String clientBrandName = null; // Paper - Brand support public org.bukkit.event.player.PlayerQuitEvent.QuitReason quitReason = null; // Paper - Add API for quit reason; there are a lot of changes to do if we change all methods leading to the event + public boolean purpurClient = false; // Purpur - Purpur client support // Paper start - rewrite chunk system private ca.spottedleaf.moonrise.patches.chunk_system.player.RegionizedPlayerChunkLoader.PlayerChunkLoaderData chunkLoader; @@ -2014,6 +_,26 @@ this.lastSentExp = -1; // CraftBukkit - Added to reset } + // Purpur start - Component related conveniences + public void sendActionBarMessage(@Nullable String message) { + if (message != null && !message.isEmpty()) { + sendActionBarMessage(net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(message)); + } + } + + public void sendActionBarMessage(@Nullable net.kyori.adventure.text.Component message) { + if (message != null) { + sendActionBarMessage(io.papermc.paper.adventure.PaperAdventure.asVanilla(message)); + } + } + + public void sendActionBarMessage(@Nullable Component message) { + if (message != null) { + displayClientMessage(message, true); + } + } + // Purpur end - Component related conveniences + @Override public void displayClientMessage(Component chatComponent, boolean actionBar) { this.sendSystemMessage(chatComponent, actionBar); @@ -2235,6 +_,20 @@ ); } + // Purpur start - Component related conveniences + public void sendMiniMessage(@Nullable String message) { + if (message != null && !message.isEmpty()) { + this.sendMessage(net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(message)); + } + } + + public void sendMessage(@Nullable net.kyori.adventure.text.Component message) { + if (message != null) { + this.sendSystemMessage(io.papermc.paper.adventure.PaperAdventure.asVanilla(message)); + } + } + // Purpur end - Component related conveniences + public void sendSystemMessage(Component mesage) { this.sendSystemMessage(mesage, false); } @@ -2373,7 +_,67 @@ public void resetLastActionTime() { this.lastActionTime = Util.getMillis(); - } + this.setAfk(false); // Purpur - AFK API + } + + // Purpur start - AFK API + private boolean isAfk = false; + + @Override + public void setAfk(boolean afk) { + if (this.isAfk == afk) { + return; + } + + String msg = afk ? org.purpurmc.purpur.PurpurConfig.afkBroadcastAway : org.purpurmc.purpur.PurpurConfig.afkBroadcastBack; + + org.purpurmc.purpur.event.PlayerAFKEvent event = new org.purpurmc.purpur.event.PlayerAFKEvent(this.getBukkitEntity(), afk, this.level().purpurConfig.idleTimeoutKick, msg, !org.bukkit.Bukkit.isPrimaryThread()); + if (!event.callEvent() || event.shouldKick()) { + return; + } + + this.isAfk = afk; + + if (!afk) { + resetLastActionTime(); + } + + msg = event.getBroadcastMsg(); + if (msg != null && !msg.isEmpty()) { + String playerName = this.getGameProfile().getName(); + if (org.purpurmc.purpur.PurpurConfig.afkBroadcastUseDisplayName) { + net.kyori.adventure.text.Component playerDisplayNameComponent = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(this.getBukkitEntity().getDisplayName()); + playerName = net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer.plainText().serialize(playerDisplayNameComponent); + } + server.getPlayerList().broadcastMiniMessage(String.format(msg, playerName), false); + } + + if (this.level().purpurConfig.idleTimeoutUpdateTabList) { + String scoreboardName = getScoreboardName(); + String playerListName = net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().serialize(getBukkitEntity().playerListName()); + String[] split = playerListName.split(scoreboardName); + String prefix = (split.length > 0 ? split[0] : "").replace(org.purpurmc.purpur.PurpurConfig.afkTabListPrefix, ""); + String suffix = (split.length > 1 ? split[1] : "").replace(org.purpurmc.purpur.PurpurConfig.afkTabListSuffix, ""); + if (afk) { + getBukkitEntity().setPlayerListName(org.purpurmc.purpur.PurpurConfig.afkTabListPrefix + prefix + scoreboardName + suffix + org.purpurmc.purpur.PurpurConfig.afkTabListSuffix, true); + } else { + getBukkitEntity().setPlayerListName(prefix + scoreboardName + suffix, true); + } + } + + ((ServerLevel) this.level()).updateSleepingPlayerList(); + } + + @Override + public boolean isAfk() { + return this.isAfk; + } + + @Override + public boolean canBeCollidedWith() { + return !this.isAfk() && super.canBeCollidedWith(); + } + // Purpur end - AFK API public ServerStatsCounter getStats() { return this.stats; @@ -3077,4 +_,26 @@ return (org.bukkit.craftbukkit.entity.CraftPlayer) super.getBukkitEntity(); } // CraftBukkit end + + // Purpur start - Add option to teleport to spawn if outside world border + public void teleport(org.bukkit.Location to) { + this.ejectPassengers(); + this.stopRiding(true); + + if (this.isSleeping()) { + this.stopSleepInBed(true, false); + } + + if (this.containerMenu != this.inventoryMenu) { + this.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.TELEPORT); + } + + ServerLevel toLevel = ((org.bukkit.craftbukkit.CraftWorld) to.getWorld()).getHandle(); + if (this.level() == toLevel) { + this.connection.teleport(to); + } else { + this.server.getPlayerList().respawn(this, true, RemovalReason.KILLED, org.bukkit.event.player.PlayerRespawnEvent.RespawnReason.DEATH, to); + } + } + // Purpur end - Add option to teleport to spawn if outside world border }