Implement extended PaperServerListPingEvent
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
package com.destroystokyo.paper.network;
|
||||
|
||||
import com.destroystokyo.paper.event.server.PaperServerListPingEvent;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.CachedServerIcon;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
class PaperServerListPingEventImpl extends PaperServerListPingEvent {
|
||||
|
||||
private final MinecraftServer server;
|
||||
|
||||
PaperServerListPingEventImpl(MinecraftServer server, StatusClient client, int protocolVersion, @Nullable CachedServerIcon icon) {
|
||||
super(client, server.motd(), server.getPlayerCount(), server.getMaxPlayers(),
|
||||
server.getServerModName() + ' ' + server.getServerVersion(), protocolVersion, icon);
|
||||
this.server = server;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final Object[] getOnlinePlayers() {
|
||||
return this.server.getPlayerList().players.toArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final Player getBukkitPlayer(Object player) {
|
||||
return ((ServerPlayer) player).getBukkitEntity();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.destroystokyo.paper.network;
|
||||
|
||||
import net.minecraft.network.Connection;
|
||||
|
||||
class PaperStatusClient extends PaperNetworkClient implements StatusClient {
|
||||
|
||||
PaperStatusClient(Connection networkManager) {
|
||||
super(networkManager);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
package com.destroystokyo.paper.network;
|
||||
|
||||
import com.destroystokyo.paper.profile.PlayerProfile;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import io.papermc.paper.adventure.AdventureComponent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import javax.annotation.Nonnull;
|
||||
import net.minecraft.network.Connection;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.protocol.status.ClientboundStatusResponsePacket;
|
||||
import net.minecraft.network.protocol.status.ServerStatus;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import org.bukkit.craftbukkit.util.CraftIconCache;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public final class StandardPaperServerListPingEventImpl extends PaperServerListPingEventImpl {
|
||||
|
||||
private List<GameProfile> originalSample;
|
||||
|
||||
private StandardPaperServerListPingEventImpl(MinecraftServer server, Connection networkManager, ServerStatus ping) {
|
||||
super(server, new PaperStatusClient(networkManager), ping.version().map(ServerStatus.Version::protocol).orElse(-1), server.server.getServerIcon());
|
||||
this.originalSample = ping.players().map(ServerStatus.Players::sample).orElse(null); // GH-1473 - pre-tick race condition NPE
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public List<ListedPlayerInfo> getListedPlayers() {
|
||||
List<ListedPlayerInfo> sample = super.getListedPlayers();
|
||||
|
||||
if (this.originalSample != null) {
|
||||
for (GameProfile profile : this.originalSample) {
|
||||
sample.add(new ListedPlayerInfo(profile.getName(), profile.getId()));
|
||||
}
|
||||
this.originalSample = null;
|
||||
}
|
||||
|
||||
return sample;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull List<PlayerProfile> getPlayerSample() {
|
||||
this.getListedPlayers(); // Populate the backing list for the transforming view, and null out originalSample (see getListedPlayers and processRequest)
|
||||
return super.getPlayerSample();
|
||||
}
|
||||
|
||||
private List<GameProfile> getPlayerSampleHandle() {
|
||||
if (this.originalSample != null) {
|
||||
return this.originalSample;
|
||||
}
|
||||
|
||||
List<ListedPlayerInfo> entries = super.getListedPlayers();
|
||||
if (entries.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
final List<GameProfile> profiles = new ArrayList<>();
|
||||
for (ListedPlayerInfo playerInfo : entries) {
|
||||
profiles.add(new GameProfile(playerInfo.id(), playerInfo.name()));
|
||||
}
|
||||
return profiles;
|
||||
}
|
||||
|
||||
public static void processRequest(MinecraftServer server, Connection networkManager) {
|
||||
StandardPaperServerListPingEventImpl event = new StandardPaperServerListPingEventImpl(server, networkManager, server.getStatus());
|
||||
server.server.getPluginManager().callEvent(event);
|
||||
|
||||
// Close connection immediately if event is cancelled
|
||||
if (event.isCancelled()) {
|
||||
networkManager.disconnect((Component) null);
|
||||
return;
|
||||
}
|
||||
|
||||
// Setup response
|
||||
|
||||
// Description
|
||||
final Component description = new AdventureComponent(event.motd());
|
||||
|
||||
// Players
|
||||
final Optional<ServerStatus.Players> players;
|
||||
if (!event.shouldHidePlayers()) {
|
||||
players = Optional.of(new ServerStatus.Players(event.getMaxPlayers(), event.getNumPlayers(), event.getPlayerSampleHandle()));
|
||||
} else {
|
||||
players = Optional.empty();
|
||||
}
|
||||
|
||||
// Version
|
||||
final ServerStatus.Version version = new ServerStatus.Version(event.getVersion(), event.getProtocolVersion());
|
||||
|
||||
// Favicon
|
||||
final Optional<ServerStatus.Favicon> favicon;
|
||||
if (event.getServerIcon() != null) {
|
||||
favicon = Optional.of(new ServerStatus.Favicon(((CraftIconCache) event.getServerIcon()).value));
|
||||
} else {
|
||||
favicon = Optional.empty();
|
||||
}
|
||||
final ServerStatus ping = new ServerStatus(description, players, Optional.of(version), favicon, server.enforceSecureProfile());
|
||||
|
||||
// Send response
|
||||
networkManager.send(new ClientboundStatusResponsePacket(ping));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -285,7 +285,7 @@ public class SpigotConfig
|
||||
public static int playerSample;
|
||||
private static void playerSample()
|
||||
{
|
||||
SpigotConfig.playerSample = SpigotConfig.getInt( "settings.sample-count", 12 );
|
||||
SpigotConfig.playerSample = Math.max( SpigotConfig.getInt( "settings.sample-count", 12 ), 0 ); // Paper - Avoid negative counts
|
||||
Bukkit.getLogger().log( Level.INFO, "Server Ping Player Sample Count: {0}", playerSample ); // Paper - Use logger
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user