mirror of
https://github.com/Minestom/Minestom.git
synced 2025-01-06 16:37:38 +01:00
Merge pull request #316 from thiccaxe/server-list-ping-update
Updated Server List Ping
This commit is contained in:
commit
6cd3952fb5
@ -0,0 +1,128 @@
|
|||||||
|
package net.minestom.server.event.server;
|
||||||
|
|
||||||
|
import net.minestom.server.event.CancellableEvent;
|
||||||
|
import net.minestom.server.event.Event;
|
||||||
|
import net.minestom.server.network.player.PlayerConnection;
|
||||||
|
import net.minestom.server.utils.time.TimeUnit;
|
||||||
|
import net.minestom.server.utils.time.UpdateOption;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when a {@link PlayerConnection} sends a ping packet,
|
||||||
|
* usually after the status packet. Only used in versions since the netty rewrite; 1.7+
|
||||||
|
*
|
||||||
|
* @see ServerListPingEvent
|
||||||
|
*/
|
||||||
|
public class ClientPingServerEvent extends Event implements CancellableEvent {
|
||||||
|
private static final UpdateOption DEFAULT_DELAY = new UpdateOption(0, TimeUnit.MILLISECOND);
|
||||||
|
|
||||||
|
private final PlayerConnection connection;
|
||||||
|
private long payload;
|
||||||
|
|
||||||
|
private boolean cancelled = false;
|
||||||
|
private UpdateOption delay;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new client ping server event with 0 delay
|
||||||
|
*
|
||||||
|
* @param connection the player connection
|
||||||
|
* @param payload the payload the client sent
|
||||||
|
*/
|
||||||
|
public ClientPingServerEvent(@NotNull PlayerConnection connection, long payload) {
|
||||||
|
this.connection = connection;
|
||||||
|
this.payload = payload;
|
||||||
|
this.delay = DEFAULT_DELAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new client ping server event with 0 delay
|
||||||
|
*
|
||||||
|
* @param connection the player connection
|
||||||
|
* @param payload the payload the client sent
|
||||||
|
*/
|
||||||
|
public ClientPingServerEvent(@NotNull PlayerConnection connection, long payload, UpdateOption delay) {
|
||||||
|
this.connection = connection;
|
||||||
|
this.payload = payload;
|
||||||
|
this.delay = delay;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PlayerConnection of received packet. Note that the player has not joined the server
|
||||||
|
* at this time.
|
||||||
|
*
|
||||||
|
* @return the connection.
|
||||||
|
*/
|
||||||
|
public @NotNull PlayerConnection getConnection() {
|
||||||
|
return connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Payload of received packet. May be any number; vanilla uses a system dependant time value.
|
||||||
|
*
|
||||||
|
* @return the payload
|
||||||
|
*/
|
||||||
|
public long getPayload() {
|
||||||
|
return payload;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the payload to respond with.
|
||||||
|
*
|
||||||
|
* Note: This should be the same as the client sent, however vanilla 1.17 seems to be OK with a different payload.
|
||||||
|
* @param payload the payload
|
||||||
|
*/
|
||||||
|
public void setPayload(long payload) {
|
||||||
|
this.payload = payload;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the delay until minestom will send the ping response packet.
|
||||||
|
*
|
||||||
|
* @return the delay
|
||||||
|
*/
|
||||||
|
public @NotNull UpdateOption getDelay() {
|
||||||
|
return delay;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds to the delay until minestom will send the ping response packet.
|
||||||
|
*
|
||||||
|
* @param delay the delay
|
||||||
|
*/
|
||||||
|
public void addDelay(@NotNull UpdateOption delay) {
|
||||||
|
this.delay = new UpdateOption(this.delay.toMilliseconds() + delay.toMilliseconds(), TimeUnit.MILLISECOND);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the delay until minestom will send the ping response packet.
|
||||||
|
*
|
||||||
|
* @param delay the delay
|
||||||
|
*/
|
||||||
|
public void setDelay(@NotNull UpdateOption delay) {
|
||||||
|
this.delay = delay;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears the delay until minestom will send the ping response packet.
|
||||||
|
*/
|
||||||
|
public void noDelay() {
|
||||||
|
this.delay = DEFAULT_DELAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCancelled() {
|
||||||
|
return cancelled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancelling this event will cause the server to appear offline in the vanilla server list.
|
||||||
|
*
|
||||||
|
* @param cancel true if the event should be cancelled, false otherwise
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setCancelled(boolean cancel) {
|
||||||
|
this.cancelled = cancel;
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,8 @@
|
|||||||
package net.minestom.server.network.packet.client.status;
|
package net.minestom.server.network.packet.client.status;
|
||||||
|
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.minestom.server.MinecraftServer;
|
||||||
|
import net.minestom.server.event.server.ClientPingServerEvent;
|
||||||
import net.minestom.server.network.packet.client.ClientPreplayPacket;
|
import net.minestom.server.network.packet.client.ClientPreplayPacket;
|
||||||
import net.minestom.server.network.packet.server.status.PongPacket;
|
import net.minestom.server.network.packet.server.status.PongPacket;
|
||||||
import net.minestom.server.network.player.PlayerConnection;
|
import net.minestom.server.network.player.PlayerConnection;
|
||||||
@ -15,9 +18,22 @@ public class PingPacket implements ClientPreplayPacket {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void process(@NotNull PlayerConnection connection) {
|
public void process(@NotNull PlayerConnection connection) {
|
||||||
PongPacket pongPacket = new PongPacket(number);
|
final ClientPingServerEvent clientPingEvent = new ClientPingServerEvent(connection, number);
|
||||||
connection.sendPacket(pongPacket);
|
MinecraftServer.getGlobalEventHandler().callEvent(ClientPingServerEvent.class, clientPingEvent);
|
||||||
connection.disconnect();
|
|
||||||
|
if (clientPingEvent.isCancelled()) {
|
||||||
|
connection.disconnect();
|
||||||
|
} else {
|
||||||
|
if (clientPingEvent.getDelay().toMilliseconds() == 0) {
|
||||||
|
connection.sendPacket(new PongPacket(clientPingEvent.getPayload()));
|
||||||
|
connection.disconnect();
|
||||||
|
} else {
|
||||||
|
MinecraftServer.getSchedulerManager().buildTask(() -> {
|
||||||
|
connection.sendPacket(new PongPacket(clientPingEvent.getPayload()));
|
||||||
|
connection.disconnect();
|
||||||
|
}).delay(clientPingEvent.getDelay()).schedule();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -29,6 +29,7 @@ public class ResponseData {
|
|||||||
private int online;
|
private int online;
|
||||||
private Component description;
|
private Component description;
|
||||||
private String favicon;
|
private String favicon;
|
||||||
|
private boolean playersHidden;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new {@link ResponseData}.
|
* Constructs a new {@link ResponseData}.
|
||||||
@ -41,6 +42,7 @@ public class ResponseData {
|
|||||||
this.maxPlayer = this.online + 1;
|
this.maxPlayer = this.online + 1;
|
||||||
this.description = DEFAULT_DESCRIPTION;
|
this.description = DEFAULT_DESCRIPTION;
|
||||||
this.favicon = "";
|
this.favicon = "";
|
||||||
|
this.playersHidden = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -294,6 +296,25 @@ public class ResponseData {
|
|||||||
return this.entries;
|
return this.entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether the players are hidden or not.
|
||||||
|
* In the vanilla client, `???` will be displayed where the online and maximum players would be.
|
||||||
|
*
|
||||||
|
* @param playersHidden if the players are hidden
|
||||||
|
*/
|
||||||
|
public void setPlayersHidden(boolean playersHidden) {
|
||||||
|
this.playersHidden = playersHidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns if the players are hidden or not.
|
||||||
|
*
|
||||||
|
* @return if the players are hidden
|
||||||
|
*/
|
||||||
|
public boolean arePlayersHidden() {
|
||||||
|
return playersHidden;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts the response data into a {@link JsonObject}.
|
* Converts the response data into a {@link JsonObject}.
|
||||||
*
|
*
|
||||||
|
@ -109,22 +109,25 @@ public enum ServerListPingType {
|
|||||||
versionObject.addProperty("name", data.getVersion());
|
versionObject.addProperty("name", data.getVersion());
|
||||||
versionObject.addProperty("protocol", data.getProtocol());
|
versionObject.addProperty("protocol", data.getProtocol());
|
||||||
|
|
||||||
// players info
|
JsonObject playersObject = null;
|
||||||
final JsonObject playersObject = new JsonObject();
|
if (!data.arePlayersHidden()) {
|
||||||
playersObject.addProperty("max", data.getMaxPlayer());
|
// players info
|
||||||
playersObject.addProperty("online", data.getOnline());
|
playersObject = new JsonObject();
|
||||||
|
playersObject.addProperty("max", data.getMaxPlayer());
|
||||||
|
playersObject.addProperty("online", data.getOnline());
|
||||||
|
|
||||||
// individual players
|
// individual players
|
||||||
final JsonArray sampleArray = new JsonArray();
|
final JsonArray sampleArray = new JsonArray();
|
||||||
for (NamedAndIdentified entry : data.getEntries()) {
|
for (NamedAndIdentified entry : data.getEntries()) {
|
||||||
JsonObject playerObject = new JsonObject();
|
JsonObject playerObject = new JsonObject();
|
||||||
playerObject.addProperty("name", SECTION.serialize(entry.getName()));
|
playerObject.addProperty("name", SECTION.serialize(entry.getName()));
|
||||||
playerObject.addProperty("id", entry.getUuid().toString());
|
playerObject.addProperty("id", entry.getUuid().toString());
|
||||||
sampleArray.add(playerObject);
|
sampleArray.add(playerObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
playersObject.add("sample", sampleArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
playersObject.add("sample", sampleArray);
|
|
||||||
|
|
||||||
final JsonObject jsonObject = new JsonObject();
|
final JsonObject jsonObject = new JsonObject();
|
||||||
jsonObject.add("version", versionObject);
|
jsonObject.add("version", versionObject);
|
||||||
jsonObject.add("players", playersObject);
|
jsonObject.add("players", playersObject);
|
||||||
|
@ -6,6 +6,7 @@ import demo.blocks.UpdatableBlockDemo;
|
|||||||
import demo.commands.*;
|
import demo.commands.*;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
|
import net.kyori.adventure.text.format.Style;
|
||||||
import net.kyori.adventure.text.format.TextColor;
|
import net.kyori.adventure.text.format.TextColor;
|
||||||
import net.kyori.adventure.text.format.TextDecoration;
|
import net.kyori.adventure.text.format.TextDecoration;
|
||||||
import net.minestom.server.MinecraftServer;
|
import net.minestom.server.MinecraftServer;
|
||||||
@ -86,6 +87,9 @@ public class Main {
|
|||||||
.append(Component.text(" VERSION: ", NamedTextColor.GRAY))
|
.append(Component.text(" VERSION: ", NamedTextColor.GRAY))
|
||||||
.append(Component.text(event.getConnection().getProtocolVersion()))));
|
.append(Component.text(event.getConnection().getProtocolVersion()))));
|
||||||
}
|
}
|
||||||
|
responseData.addEntry(NamedAndIdentified.named(Component.text("Time", NamedTextColor.YELLOW)
|
||||||
|
.append(Component.text(": ", NamedTextColor.GRAY))
|
||||||
|
.append(Component.text(System.currentTimeMillis(), Style.style(TextDecoration.ITALIC)))));
|
||||||
|
|
||||||
// components will be converted the legacy section sign format so they are displayed in the client
|
// components will be converted the legacy section sign format so they are displayed in the client
|
||||||
responseData.addEntry(NamedAndIdentified.named(Component.text("You can use ").append(Component.text("styling too!", NamedTextColor.RED, TextDecoration.BOLD))));
|
responseData.addEntry(NamedAndIdentified.named(Component.text("You can use ").append(Component.text("styling too!", NamedTextColor.RED, TextDecoration.BOLD))));
|
||||||
@ -93,6 +97,7 @@ public class Main {
|
|||||||
// the data will be automatically converted to the correct format on response, so you can do RGB and it'll be downsampled!
|
// the data will be automatically converted to the correct format on response, so you can do RGB and it'll be downsampled!
|
||||||
// on legacy versions, colors will be converted to the section format so it'll work there too
|
// on legacy versions, colors will be converted to the section format so it'll work there too
|
||||||
responseData.setDescription(Component.text("This is a Minestom Server", TextColor.color(0x66b3ff)));
|
responseData.setDescription(Component.text("This is a Minestom Server", TextColor.color(0x66b3ff)));
|
||||||
|
//responseData.setPlayersHidden(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
PlayerInit.init();
|
PlayerInit.init();
|
||||||
|
Loading…
Reference in New Issue
Block a user