Initial API changes

This commit is contained in:
Tim203 2022-08-09 20:06:53 +02:00
parent 9412458f4a
commit 80588a07bd
No known key found for this signature in database
GPG key ID: 064EE9F5BF7C3EE8
18 changed files with 87 additions and 50 deletions

View file

@ -1 +1,5 @@
provided("net.kyori", "event-api", Versions.eventVersion) dependencies {
api("org.geysermc.cumulus", "cumulus", Versions.cumulusVersion)
}
provided("net.kyori", "event-api", Versions.eventVersion)

View file

@ -25,9 +25,12 @@
package org.geysermc.api; package org.geysermc.api;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
import org.geysermc.api.connection.Connection; import org.geysermc.api.connection.Connection;
import org.geysermc.cumulus.form.Form;
import org.geysermc.cumulus.form.util.FormBuilder;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
@ -37,52 +40,65 @@ import java.util.UUID;
*/ */
public interface GeyserApiBase { public interface GeyserApiBase {
/** /**
* Gets the session from the given UUID, if applicable. The player must be logged in to the Java server * Gets the connection from the given UUID, if applicable. The player must be logged in to the Java server
* for this to return a non-null value. * for this to return a non-null value.
* *
* @param uuid the UUID of the session * @param uuid the UUID of the connection
* @return the session from the given UUID, if applicable * @return the connection from the given UUID, if applicable
*/ */
@Nullable @Nullable
Connection connectionByUuid(@NonNull UUID uuid); Connection connectionByUuid(@NonNull UUID uuid);
/** /**
* Gets the session from the given * Gets the connection from the given XUID, if applicable. This method only works for online connections.
* XUID, if applicable.
* *
* @param xuid the XUID of the session * @param xuid the XUID of the session
* @return the session from the given UUID, if applicable * @return the connection from the given UUID, if applicable
*/ */
@Nullable @Nullable
Connection connectionByXuid(@NonNull String xuid); Connection connectionByXuid(@NonNull String xuid);
/** /**
* Gets the session from the given * Method to determine if the given <b>online</b> player is a Bedrock player.
* name, if applicable.
* *
* @param name the uuid of the session * @param uuid the uuid of the online player
* @return the session from the given name, if applicable * @return true if the given online player is a Bedrock player
*/ */
@Nullable boolean isBedrockPlayer(@NonNull UUID uuid);
Connection connectionByName(@NonNull String name);
boolean sendForm(UUID uuid, Form form);
boolean sendForm(UUID uuid, FormBuilder<?, ?, ?> formBuilder);
boolean transfer(UUID uuid, String address, int port);
/** /**
* Gets all the online sessions. * Returns all the online connections.
*
* @return all the online sessions
*/ */
@NonNull @NonNull
List<? extends Connection> onlineConnections(); List<? extends Connection> onlineConnections();
/** /**
* @return the major API version. Bumped whenever a significant breaking change or feature addition is added. * Returns the amount of online connections.
*/
int onlineConnectionsCount();
/**
* Returns the prefix used by Floodgate. Will be null when the auth-type isn't Floodgate.
*/
@MonotonicNonNull
String usernamePrefix();
/**
* Returns the major API version. Bumped whenever a significant breaking change or feature addition is added.
*/ */
default int majorApiVersion() { default int majorApiVersion() {
return 1; return 1;
} }
/** /**
* @return the minor API version. May be bumped for new API additions. * Returns the minor API version. May be bumped for new API additions.
*/ */
default int minorApiVersion() { default int minorApiVersion() {
return 0; return 0;

View file

@ -25,6 +25,7 @@
package org.geysermc.api.connection; package org.geysermc.api.connection;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.common.value.qual.IntRange; import org.checkerframework.common.value.qual.IntRange;
@ -33,27 +34,37 @@ import java.util.UUID;
/** /**
* Represents a player connection. * Represents a player connection.
*/ */
@NonNull
public interface Connection { public interface Connection {
/** /**
* Gets the name of the connection. * Gets the bedrock name of the connection.
* *
* @return the name of the connection * @return the bedrock name of the connection
*/ */
String name(); @NonNull
String bedrockUsername();
/**
* Gets the java name of the connection.
*
* @return the java name of the connection
*/
@MonotonicNonNull
String javaUsername();
/** /**
* Gets the {@link UUID} of the connection. * Gets the {@link UUID} of the connection.
* *
* @return the UUID of the connection * @return the UUID of the connection
*/ */
UUID uuid(); @MonotonicNonNull
UUID javaUuid();
/** /**
* Gets the XUID of the connection. * Gets the XUID of the connection.
* *
* @return the XUID of the connection * @return the XUID of the connection
*/ */
@NonNull
String xuid(); String xuid();
/** /**

View file

@ -59,7 +59,7 @@ public interface GeyserApi extends GeyserApiBase {
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override @Override
@Nullable GeyserConnection connectionByName(@NonNull String name); @Nullable GeyserConnection connectionByUsername(@NonNull String username);
/** /**
* {@inheritDoc} * {@inheritDoc}

View file

@ -128,7 +128,7 @@ public class GeyserSession {
} }
public String getName() { public String getName() {
return this.handle.name(); return this.handle.bedrockUsername();
} }
public boolean isConsole() { public boolean isConsole() {

View file

@ -465,9 +465,10 @@ public class GeyserImpl implements GeyserApi {
} }
@Override @Override
public @Nullable GeyserSession connectionByName(@NonNull String name) { public @Nullable GeyserSession connectionByUsername(@NonNull String username) {
for (GeyserSession session : sessionManager.getAllSessions()) { for (GeyserSession session : sessionManager.getAllSessions()) {
if (session.name().equals(name) || session.getProtocol().getProfile().getName().equals(name)) { if (session.bedrockUsername().equals(username) || session.getProtocol().getProfile().getName().equals(
username)) {
return session; return session;
} }
} }
@ -477,7 +478,12 @@ public class GeyserImpl implements GeyserApi {
@Override @Override
public @NonNull List<GeyserSession> onlineConnections() { public @NonNull List<GeyserSession> onlineConnections() {
return this.sessionManager.getAllSessions(); return sessionManager.getAllSessions();
}
@Override
public int onlineConnectionsCount() {
return sessionManager.size();
} }
@Override @Override

View file

@ -47,7 +47,7 @@ public class ListCommand extends GeyserCommand {
public void execute(GeyserSession session, GeyserCommandSource sender, String[] args) { public void execute(GeyserSession session, GeyserCommandSource sender, String[] args) {
String message = GeyserLocale.getPlayerLocaleString("geyser.commands.list.message", sender.locale(), String message = GeyserLocale.getPlayerLocaleString("geyser.commands.list.message", sender.locale(),
geyser.getSessionManager().size(), geyser.getSessionManager().size(),
geyser.getSessionManager().getAllSessions().stream().map(GeyserSession::name).collect(Collectors.joining(" "))); geyser.getSessionManager().getAllSessions().stream().map(GeyserSession::bedrockUsername).collect(Collectors.joining(" ")));
sender.sendMessage(message); sender.sendMessage(message);
} }

View file

@ -118,7 +118,7 @@ public final class ScoreboardUpdater extends Thread {
FIRST_SCORE_PACKETS_PER_SECOND_THRESHOLD; FIRST_SCORE_PACKETS_PER_SECOND_THRESHOLD;
geyser.getLogger().info( geyser.getLogger().info(
GeyserLocale.getLocaleStringLog("geyser.scoreboard.updater.threshold_reached.log", session.name(), threshold, pps) + GeyserLocale.getLocaleStringLog("geyser.scoreboard.updater.threshold_reached.log", session.bedrockUsername(), threshold, pps) +
GeyserLocale.getLocaleStringLog("geyser.scoreboard.updater.threshold_reached", (millisBetweenUpdates / 1000.0)) GeyserLocale.getLocaleStringLog("geyser.scoreboard.updater.threshold_reached", (millisBetweenUpdates / 1000.0))
); );

View file

@ -735,7 +735,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
try { try {
service.login(); service.login();
} catch (RequestException e) { } catch (RequestException e) {
geyser.getLogger().error("Error while attempting to use refresh token for " + name() + "!", e); geyser.getLogger().error("Error while attempting to use refresh token for " + bedrockUsername() + "!", e);
return Boolean.FALSE; return Boolean.FALSE;
} }
@ -747,7 +747,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
} }
protocol = new MinecraftProtocol(profile, service.getAccessToken()); protocol = new MinecraftProtocol(profile, service.getAccessToken());
geyser.saveRefreshToken(name(), service.getRefreshToken()); geyser.saveRefreshToken(bedrockUsername(), service.getRefreshToken());
return Boolean.TRUE; return Boolean.TRUE;
}).whenComplete((successful, ex) -> { }).whenComplete((successful, ex) -> {
if (this.closed) { if (this.closed) {
@ -838,7 +838,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
connectDownstream(); connectDownstream();
// Save our refresh token for later use // Save our refresh token for later use
geyser.saveRefreshToken(name(), service.getRefreshToken()); geyser.saveRefreshToken(bedrockUsername(), service.getRefreshToken());
return true; return true;
} }
} }
@ -1071,7 +1071,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
try { try {
runnable.run(); runnable.run();
} catch (Throwable e) { } catch (Throwable e) {
geyser.getLogger().error("Error thrown in " + this.name() + "'s event loop!", e); geyser.getLogger().error("Error thrown in " + this.bedrockUsername() + "'s event loop!", e);
} }
}); });
} }
@ -1084,7 +1084,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
try { try {
runnable.run(); runnable.run();
} catch (Throwable e) { } catch (Throwable e) {
geyser.getLogger().error("Error thrown in " + this.name() + "'s event loop!", e); geyser.getLogger().error("Error thrown in " + this.bedrockUsername() + "'s event loop!", e);
} }
}, duration, timeUnit); }, duration, timeUnit);
} }
@ -1326,13 +1326,13 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
} }
@Override @Override
public String name() { public String bedrockUsername() {
return authData.name(); return authData.name();
} }
@Override @Override
public UUID uuid() { public UUID javaUuid() {
return authData.uuid();
} }
@Override @Override

View file

@ -89,7 +89,7 @@ public class TagCache {
boolean emulatePost1_18Logic = convertableToMud != null && convertableToMud.length != 0; boolean emulatePost1_18Logic = convertableToMud != null && convertableToMud.length != 0;
session.setEmulatePost1_18Logic(emulatePost1_18Logic); session.setEmulatePost1_18Logic(emulatePost1_18Logic);
if (logger.isDebug()) { if (logger.isDebug()) {
logger.debug("Emulating post 1.18 block predication logic for " + session.name() + "? " + emulatePost1_18Logic); logger.debug("Emulating post 1.18 block predication logic for " + session.bedrockUsername() + "? " + emulatePost1_18Logic);
} }
Map<String, int[]> itemTags = packet.getTags().get("minecraft:item"); Map<String, int[]> itemTags = packet.getTags().get("minecraft:item");
@ -104,7 +104,7 @@ public class TagCache {
boolean emulatePost1_13Logic = itemTags.get("minecraft:signs").length > 1; boolean emulatePost1_13Logic = itemTags.get("minecraft:signs").length > 1;
session.setEmulatePost1_13Logic(emulatePost1_13Logic); session.setEmulatePost1_13Logic(emulatePost1_13Logic);
if (logger.isDebug()) { if (logger.isDebug()) {
logger.debug("Emulating post 1.13 villager logic for " + session.name() + "? " + emulatePost1_13Logic); logger.debug("Emulating post 1.13 villager logic for " + session.bedrockUsername() + "? " + emulatePost1_13Logic);
} }
} }

View file

@ -114,7 +114,7 @@ public final class FloodgateSkinUploader {
if (session != null) { if (session != null) {
if (!node.get("success").asBoolean()) { if (!node.get("success").asBoolean()) {
logger.info("Failed to upload skin for " + session.name()); logger.info("Failed to upload skin for " + session.bedrockUsername());
return; return;
} }

View file

@ -201,7 +201,7 @@ public abstract class InventoryTranslator {
TransferStackRequestActionData transferAction = (TransferStackRequestActionData) action; TransferStackRequestActionData transferAction = (TransferStackRequestActionData) action;
if (!(checkNetId(session, inventory, transferAction.getSource()) && checkNetId(session, inventory, transferAction.getDestination()))) { if (!(checkNetId(session, inventory, transferAction.getSource()) && checkNetId(session, inventory, transferAction.getDestination()))) {
if (session.getGeyser().getConfig().isDebugMode()) { if (session.getGeyser().getConfig().isDebugMode()) {
session.getGeyser().getLogger().error("DEBUG: About to reject TAKE/PLACE request made by " + session.name()); session.getGeyser().getLogger().error("DEBUG: About to reject TAKE/PLACE request made by " + session.bedrockUsername());
dumpStackRequestDetails(session, inventory, transferAction.getSource(), transferAction.getDestination()); dumpStackRequestDetails(session, inventory, transferAction.getSource(), transferAction.getDestination());
} }
return rejectRequest(request); return rejectRequest(request);
@ -292,7 +292,7 @@ public abstract class InventoryTranslator {
if (!(checkNetId(session, inventory, source) && checkNetId(session, inventory, destination))) { if (!(checkNetId(session, inventory, source) && checkNetId(session, inventory, destination))) {
if (session.getGeyser().getConfig().isDebugMode()) { if (session.getGeyser().getConfig().isDebugMode()) {
session.getGeyser().getLogger().error("DEBUG: About to reject SWAP request made by " + session.name()); session.getGeyser().getLogger().error("DEBUG: About to reject SWAP request made by " + session.bedrockUsername());
dumpStackRequestDetails(session, inventory, source, destination); dumpStackRequestDetails(session, inventory, source, destination);
} }
return rejectRequest(request); return rejectRequest(request);

View file

@ -371,7 +371,7 @@ public class PlayerInventoryTranslator extends InventoryTranslator {
} }
} }
default -> { default -> {
session.getGeyser().getLogger().error("Unknown crafting state induced by " + session.name()); session.getGeyser().getLogger().error("Unknown crafting state induced by " + session.bedrockUsername());
return rejectRequest(request); return rejectRequest(request);
} }
} }

View file

@ -546,7 +546,7 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator<Inve
int heldItemId = packet.getItemInHand() == null ? ItemData.AIR.getId() : packet.getItemInHand().getId(); int heldItemId = packet.getItemInHand() == null ? ItemData.AIR.getId() : packet.getItemInHand().getId();
if (expectedItemId != heldItemId) { if (expectedItemId != heldItemId) {
session.getGeyser().getLogger().debug(session.name() + "'s held item has desynced! Expected: " + expectedItemId + " Received: " + heldItemId); session.getGeyser().getLogger().debug(session.bedrockUsername() + "'s held item has desynced! Expected: " + expectedItemId + " Received: " + heldItemId);
session.getGeyser().getLogger().debug("Packet: " + packet); session.getGeyser().getLogger().debug("Packet: " + packet);
return true; return true;
} }

View file

@ -43,8 +43,8 @@ public class BedrockSetLocalPlayerAsInitializedTranslator extends PacketTranslat
if (session.remoteServer().authType() == AuthType.ONLINE) { if (session.remoteServer().authType() == AuthType.ONLINE) {
if (!session.isLoggedIn()) { if (!session.isLoggedIn()) {
if (session.getGeyser().getConfig().getSavedUserLogins().contains(session.name())) { if (session.getGeyser().getConfig().getSavedUserLogins().contains(session.bedrockUsername())) {
if (session.getGeyser().refreshTokenFor(session.name()) == null) { if (session.getGeyser().refreshTokenFor(session.bedrockUsername()) == null) {
LoginEncryptionUtils.buildAndShowConsentWindow(session); LoginEncryptionUtils.buildAndShowConsentWindow(session);
} else { } else {
// If the refresh token is not null and we're here, then the refresh token expired // If the refresh token is not null and we're here, then the refresh token expired

View file

@ -175,7 +175,7 @@ public class BedrockMovePlayerTranslator extends PacketTranslator<MovePlayerPack
return false; return false;
} }
if (currentPosition.distanceSquared(newPosition) > 300) { if (currentPosition.distanceSquared(newPosition) > 300) {
session.getGeyser().getLogger().debug(ChatColor.RED + session.name() + " moved too quickly." + session.getGeyser().getLogger().debug(ChatColor.RED + session.bedrockUsername() + " moved too quickly." +
" current position: " + currentPosition + ", new position: " + newPosition); " current position: " + currentPosition + ", new position: " + newPosition);
return false; return false;

View file

@ -48,7 +48,7 @@ public class JavaContainerSetContentTranslator extends PacketTranslator<Clientbo
for (int i = 0; i < packet.getItems().length; i++) { for (int i = 0; i < packet.getItems().length; i++) {
if (i > inventorySize) { if (i > inventorySize) {
GeyserImpl geyser = session.getGeyser(); GeyserImpl geyser = session.getGeyser();
geyser.getLogger().warning("ClientboundContainerSetContentPacket sent to " + session.name() geyser.getLogger().warning("ClientboundContainerSetContentPacket sent to " + session.bedrockUsername()
+ " that exceeds inventory size!"); + " that exceeds inventory size!");
if (geyser.getConfig().isDebugMode()) { if (geyser.getConfig().isDebugMode()) {
geyser.getLogger().debug(packet); geyser.getLogger().debug(packet);

View file

@ -76,7 +76,7 @@ public class JavaContainerSetSlotTranslator extends PacketTranslator<Clientbound
int slot = packet.getSlot(); int slot = packet.getSlot();
if (slot >= inventory.getSize()) { if (slot >= inventory.getSize()) {
GeyserImpl geyser = session.getGeyser(); GeyserImpl geyser = session.getGeyser();
geyser.getLogger().warning("ClientboundContainerSetSlotPacket sent to " + session.name() geyser.getLogger().warning("ClientboundContainerSetSlotPacket sent to " + session.bedrockUsername()
+ " that exceeds inventory size!"); + " that exceeds inventory size!");
if (geyser.getConfig().isDebugMode()) { if (geyser.getConfig().isDebugMode()) {
geyser.getLogger().debug(packet); geyser.getLogger().debug(packet);