diff --git a/api/base/build.gradle.kts b/api/base/build.gradle.kts
index d7500fdaa..c9ddf4489 100644
--- a/api/base/build.gradle.kts
+++ b/api/base/build.gradle.kts
@@ -1 +1,5 @@
-provided("net.kyori", "event-api", Versions.eventVersion)
\ No newline at end of file
+dependencies {
+ api("org.geysermc.cumulus", "cumulus", Versions.cumulusVersion)
+}
+
+provided("net.kyori", "event-api", Versions.eventVersion)
diff --git a/api/base/src/main/java/org/geysermc/api/GeyserApiBase.java b/api/base/src/main/java/org/geysermc/api/GeyserApiBase.java
index e5105b1be..e9957e21c 100644
--- a/api/base/src/main/java/org/geysermc/api/GeyserApiBase.java
+++ b/api/base/src/main/java/org/geysermc/api/GeyserApiBase.java
@@ -25,9 +25,12 @@
package org.geysermc.api;
+import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
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.UUID;
@@ -37,52 +40,65 @@ import java.util.UUID;
*/
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.
*
- * @param uuid the UUID of the session
- * @return the session from the given UUID, if applicable
+ * @param uuid the UUID of the connection
+ * @return the connection from the given UUID, if applicable
*/
@Nullable
Connection connectionByUuid(@NonNull UUID uuid);
/**
- * Gets the session from the given
- * XUID, if applicable.
+ * Gets the connection from the given XUID, if applicable. This method only works for online connections.
*
* @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
Connection connectionByXuid(@NonNull String xuid);
/**
- * Gets the session from the given
- * name, if applicable.
+ * Method to determine if the given online player is a Bedrock player.
*
- * @param name the uuid of the session
- * @return the session from the given name, if applicable
+ * @param uuid the uuid of the online player
+ * @return true if the given online player is a Bedrock player
*/
- @Nullable
- Connection connectionByName(@NonNull String name);
+ boolean isBedrockPlayer(@NonNull UUID uuid);
+
+ 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.
- *
- * @return all the online sessions
+ * Returns all the online connections.
*/
@NonNull
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() {
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() {
return 0;
diff --git a/api/base/src/main/java/org/geysermc/api/connection/Connection.java b/api/base/src/main/java/org/geysermc/api/connection/Connection.java
index fc6cdae20..db09149e2 100644
--- a/api/base/src/main/java/org/geysermc/api/connection/Connection.java
+++ b/api/base/src/main/java/org/geysermc/api/connection/Connection.java
@@ -25,6 +25,7 @@
package org.geysermc.api.connection;
+import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.common.value.qual.IntRange;
@@ -33,27 +34,37 @@ import java.util.UUID;
/**
* Represents a player connection.
*/
-@NonNull
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.
*
* @return the UUID of the connection
*/
- UUID uuid();
+ @MonotonicNonNull
+ UUID javaUuid();
/**
* Gets the XUID of the connection.
*
* @return the XUID of the connection
*/
+ @NonNull
String xuid();
/**
diff --git a/api/geyser/src/main/java/org/geysermc/geyser/api/GeyserApi.java b/api/geyser/src/main/java/org/geysermc/geyser/api/GeyserApi.java
index 16bfe7070..9b584b985 100644
--- a/api/geyser/src/main/java/org/geysermc/geyser/api/GeyserApi.java
+++ b/api/geyser/src/main/java/org/geysermc/geyser/api/GeyserApi.java
@@ -59,7 +59,7 @@ public interface GeyserApi extends GeyserApiBase {
* {@inheritDoc}
*/
@Override
- @Nullable GeyserConnection connectionByName(@NonNull String name);
+ @Nullable GeyserConnection connectionByUsername(@NonNull String username);
/**
* {@inheritDoc}
diff --git a/core/src/main/java/org/geysermc/connector/network/session/GeyserSession.java b/core/src/main/java/org/geysermc/connector/network/session/GeyserSession.java
index 21aa35efc..258787e78 100644
--- a/core/src/main/java/org/geysermc/connector/network/session/GeyserSession.java
+++ b/core/src/main/java/org/geysermc/connector/network/session/GeyserSession.java
@@ -128,7 +128,7 @@ public class GeyserSession {
}
public String getName() {
- return this.handle.name();
+ return this.handle.bedrockUsername();
}
public boolean isConsole() {
diff --git a/core/src/main/java/org/geysermc/geyser/GeyserImpl.java b/core/src/main/java/org/geysermc/geyser/GeyserImpl.java
index 276c5328d..67a144f36 100644
--- a/core/src/main/java/org/geysermc/geyser/GeyserImpl.java
+++ b/core/src/main/java/org/geysermc/geyser/GeyserImpl.java
@@ -465,9 +465,10 @@ public class GeyserImpl implements GeyserApi {
}
@Override
- public @Nullable GeyserSession connectionByName(@NonNull String name) {
+ public @Nullable GeyserSession connectionByUsername(@NonNull String username) {
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;
}
}
@@ -477,7 +478,12 @@ public class GeyserImpl implements GeyserApi {
@Override
public @NonNull List onlineConnections() {
- return this.sessionManager.getAllSessions();
+ return sessionManager.getAllSessions();
+ }
+
+ @Override
+ public int onlineConnectionsCount() {
+ return sessionManager.size();
}
@Override
diff --git a/core/src/main/java/org/geysermc/geyser/command/defaults/ListCommand.java b/core/src/main/java/org/geysermc/geyser/command/defaults/ListCommand.java
index f911e431e..90446fbb6 100644
--- a/core/src/main/java/org/geysermc/geyser/command/defaults/ListCommand.java
+++ b/core/src/main/java/org/geysermc/geyser/command/defaults/ListCommand.java
@@ -47,7 +47,7 @@ public class ListCommand extends GeyserCommand {
public void execute(GeyserSession session, GeyserCommandSource sender, String[] args) {
String message = GeyserLocale.getPlayerLocaleString("geyser.commands.list.message", sender.locale(),
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);
}
diff --git a/core/src/main/java/org/geysermc/geyser/scoreboard/ScoreboardUpdater.java b/core/src/main/java/org/geysermc/geyser/scoreboard/ScoreboardUpdater.java
index 45ae7eff2..fed3054b4 100644
--- a/core/src/main/java/org/geysermc/geyser/scoreboard/ScoreboardUpdater.java
+++ b/core/src/main/java/org/geysermc/geyser/scoreboard/ScoreboardUpdater.java
@@ -118,7 +118,7 @@ public final class ScoreboardUpdater extends Thread {
FIRST_SCORE_PACKETS_PER_SECOND_THRESHOLD;
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))
);
diff --git a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java
index 031d8f7f5..c8ae4792b 100644
--- a/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java
+++ b/core/src/main/java/org/geysermc/geyser/session/GeyserSession.java
@@ -735,7 +735,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
try {
service.login();
} 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;
}
@@ -747,7 +747,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
}
protocol = new MinecraftProtocol(profile, service.getAccessToken());
- geyser.saveRefreshToken(name(), service.getRefreshToken());
+ geyser.saveRefreshToken(bedrockUsername(), service.getRefreshToken());
return Boolean.TRUE;
}).whenComplete((successful, ex) -> {
if (this.closed) {
@@ -838,7 +838,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
connectDownstream();
// Save our refresh token for later use
- geyser.saveRefreshToken(name(), service.getRefreshToken());
+ geyser.saveRefreshToken(bedrockUsername(), service.getRefreshToken());
return true;
}
}
@@ -1071,7 +1071,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
try {
runnable.run();
} 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 {
runnable.run();
} 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);
}
@@ -1326,13 +1326,13 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
}
@Override
- public String name() {
+ public String bedrockUsername() {
return authData.name();
}
@Override
- public UUID uuid() {
- return authData.uuid();
+ public UUID javaUuid() {
+
}
@Override
diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java
index ac0c93204..9cd5b2ef6 100644
--- a/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java
+++ b/core/src/main/java/org/geysermc/geyser/session/cache/TagCache.java
@@ -89,7 +89,7 @@ public class TagCache {
boolean emulatePost1_18Logic = convertableToMud != null && convertableToMud.length != 0;
session.setEmulatePost1_18Logic(emulatePost1_18Logic);
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 itemTags = packet.getTags().get("minecraft:item");
@@ -104,7 +104,7 @@ public class TagCache {
boolean emulatePost1_13Logic = itemTags.get("minecraft:signs").length > 1;
session.setEmulatePost1_13Logic(emulatePost1_13Logic);
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);
}
}
diff --git a/core/src/main/java/org/geysermc/geyser/skin/FloodgateSkinUploader.java b/core/src/main/java/org/geysermc/geyser/skin/FloodgateSkinUploader.java
index 4d0e98444..7b6dacd16 100644
--- a/core/src/main/java/org/geysermc/geyser/skin/FloodgateSkinUploader.java
+++ b/core/src/main/java/org/geysermc/geyser/skin/FloodgateSkinUploader.java
@@ -114,7 +114,7 @@ public final class FloodgateSkinUploader {
if (session != null) {
if (!node.get("success").asBoolean()) {
- logger.info("Failed to upload skin for " + session.name());
+ logger.info("Failed to upload skin for " + session.bedrockUsername());
return;
}
diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java
index 6f4ca7ee4..fc442c329 100644
--- a/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java
+++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/InventoryTranslator.java
@@ -201,7 +201,7 @@ public abstract class InventoryTranslator {
TransferStackRequestActionData transferAction = (TransferStackRequestActionData) action;
if (!(checkNetId(session, inventory, transferAction.getSource()) && checkNetId(session, inventory, transferAction.getDestination()))) {
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());
}
return rejectRequest(request);
@@ -292,7 +292,7 @@ public abstract class InventoryTranslator {
if (!(checkNetId(session, inventory, source) && checkNetId(session, inventory, destination))) {
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);
}
return rejectRequest(request);
diff --git a/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java
index e2349e5a5..ee7d6a7c6 100644
--- a/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java
+++ b/core/src/main/java/org/geysermc/geyser/translator/inventory/PlayerInventoryTranslator.java
@@ -371,7 +371,7 @@ public class PlayerInventoryTranslator extends InventoryTranslator {
}
}
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);
}
}
diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java
index 815456132..521adb687 100644
--- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java
+++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/BedrockInventoryTransactionTranslator.java
@@ -546,7 +546,7 @@ public class BedrockInventoryTransactionTranslator extends PacketTranslator 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);
return false;
diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetContentTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetContentTranslator.java
index 0775028fe..619825338 100644
--- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetContentTranslator.java
+++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetContentTranslator.java
@@ -48,7 +48,7 @@ public class JavaContainerSetContentTranslator extends PacketTranslator inventorySize) {
GeyserImpl geyser = session.getGeyser();
- geyser.getLogger().warning("ClientboundContainerSetContentPacket sent to " + session.name()
+ geyser.getLogger().warning("ClientboundContainerSetContentPacket sent to " + session.bedrockUsername()
+ " that exceeds inventory size!");
if (geyser.getConfig().isDebugMode()) {
geyser.getLogger().debug(packet);
diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetSlotTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetSlotTranslator.java
index aef8cf8b2..9a5569392 100644
--- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetSlotTranslator.java
+++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/inventory/JavaContainerSetSlotTranslator.java
@@ -76,7 +76,7 @@ public class JavaContainerSetSlotTranslator extends PacketTranslator= inventory.getSize()) {
GeyserImpl geyser = session.getGeyser();
- geyser.getLogger().warning("ClientboundContainerSetSlotPacket sent to " + session.name()
+ geyser.getLogger().warning("ClientboundContainerSetSlotPacket sent to " + session.bedrockUsername()
+ " that exceeds inventory size!");
if (geyser.getConfig().isDebugMode()) {
geyser.getLogger().debug(packet);