mirror of
https://github.com/GeyserMC/Geyser.git
synced 2025-12-21 07:49:32 +00:00
Updated to MinecraftAuth 5 (#5989)
This commit is contained in:
@@ -38,6 +38,8 @@ import lombok.Getter;
|
|||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
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.raphimc.minecraftauth.msa.data.MsaConstants;
|
||||||
|
import net.raphimc.minecraftauth.msa.model.MsaApplicationConfig;
|
||||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
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;
|
||||||
@@ -145,9 +147,9 @@ public class GeyserImpl implements GeyserApi, EventRegistrar {
|
|||||||
public static final boolean IS_DEV = BuildData.isDevBuild();
|
public static final boolean IS_DEV = BuildData.isDevBuild();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Oauth client ID for Microsoft authentication
|
* Oauth config for Microsoft authentication
|
||||||
*/
|
*/
|
||||||
public static final String OAUTH_CLIENT_ID = "204cefd1-4818-4de1-b98d-513fae875d88";
|
public static final MsaApplicationConfig OAUTH_CONFIG = new MsaApplicationConfig("204cefd1-4818-4de1-b98d-513fae875d88", MsaConstants.SCOPE_OFFLINE_ACCESS);
|
||||||
|
|
||||||
private static final Pattern IP_REGEX = Pattern.compile("\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b");
|
private static final Pattern IP_REGEX = Pattern.compile("\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b");
|
||||||
|
|
||||||
|
|||||||
@@ -41,10 +41,11 @@ import lombok.Setter;
|
|||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
import net.kyori.adventure.key.Key;
|
import net.kyori.adventure.key.Key;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.raphimc.minecraftauth.responsehandler.exception.MinecraftRequestException;
|
import net.raphimc.minecraftauth.java.JavaAuthManager;
|
||||||
import net.raphimc.minecraftauth.step.java.StepMCProfile;
|
import net.raphimc.minecraftauth.java.exception.MinecraftProfileNotFoundException;
|
||||||
import net.raphimc.minecraftauth.step.java.StepMCToken;
|
import net.raphimc.minecraftauth.java.model.MinecraftProfile;
|
||||||
import net.raphimc.minecraftauth.step.java.session.StepFullJavaSession;
|
import net.raphimc.minecraftauth.java.model.MinecraftToken;
|
||||||
|
import net.raphimc.minecraftauth.util.MinecraftAuth4To5Migrator;
|
||||||
import org.checkerframework.checker.index.qual.NonNegative;
|
import org.checkerframework.checker.index.qual.NonNegative;
|
||||||
import org.checkerframework.checker.index.qual.Positive;
|
import org.checkerframework.checker.index.qual.Positive;
|
||||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||||
@@ -113,7 +114,6 @@ import org.geysermc.cumulus.form.util.FormBuilder;
|
|||||||
import org.geysermc.geyser.GeyserImpl;
|
import org.geysermc.geyser.GeyserImpl;
|
||||||
import org.geysermc.geyser.api.bedrock.camera.CameraData;
|
import org.geysermc.geyser.api.bedrock.camera.CameraData;
|
||||||
import org.geysermc.geyser.api.bedrock.camera.CameraShake;
|
import org.geysermc.geyser.api.bedrock.camera.CameraShake;
|
||||||
import org.geysermc.geyser.input.InputLocksFlag;
|
|
||||||
import org.geysermc.geyser.api.connection.GeyserConnection;
|
import org.geysermc.geyser.api.connection.GeyserConnection;
|
||||||
import org.geysermc.geyser.api.entity.EntityData;
|
import org.geysermc.geyser.api.entity.EntityData;
|
||||||
import org.geysermc.geyser.api.entity.type.GeyserEntity;
|
import org.geysermc.geyser.api.entity.type.GeyserEntity;
|
||||||
@@ -143,6 +143,7 @@ import org.geysermc.geyser.erosion.GeyserboundHandshakePacketHandler;
|
|||||||
import org.geysermc.geyser.event.type.SessionDisconnectEventImpl;
|
import org.geysermc.geyser.event.type.SessionDisconnectEventImpl;
|
||||||
import org.geysermc.geyser.impl.camera.CameraDefinitions;
|
import org.geysermc.geyser.impl.camera.CameraDefinitions;
|
||||||
import org.geysermc.geyser.impl.camera.GeyserCameraData;
|
import org.geysermc.geyser.impl.camera.GeyserCameraData;
|
||||||
|
import org.geysermc.geyser.input.InputLocksFlag;
|
||||||
import org.geysermc.geyser.inventory.Inventory;
|
import org.geysermc.geyser.inventory.Inventory;
|
||||||
import org.geysermc.geyser.inventory.InventoryHolder;
|
import org.geysermc.geyser.inventory.InventoryHolder;
|
||||||
import org.geysermc.geyser.inventory.LecternContainer;
|
import org.geysermc.geyser.inventory.LecternContainer;
|
||||||
@@ -196,7 +197,6 @@ import org.geysermc.geyser.util.EntityUtils;
|
|||||||
import org.geysermc.geyser.util.InventoryUtils;
|
import org.geysermc.geyser.util.InventoryUtils;
|
||||||
import org.geysermc.geyser.util.LoginEncryptionUtils;
|
import org.geysermc.geyser.util.LoginEncryptionUtils;
|
||||||
import org.geysermc.geyser.util.MathUtils;
|
import org.geysermc.geyser.util.MathUtils;
|
||||||
import org.geysermc.geyser.util.MinecraftAuthLogger;
|
|
||||||
import org.geysermc.mcprotocollib.auth.GameProfile;
|
import org.geysermc.mcprotocollib.auth.GameProfile;
|
||||||
import org.geysermc.mcprotocollib.network.BuiltinFlags;
|
import org.geysermc.mcprotocollib.network.BuiltinFlags;
|
||||||
import org.geysermc.mcprotocollib.network.ClientSession;
|
import org.geysermc.mcprotocollib.network.ClientSession;
|
||||||
@@ -925,23 +925,28 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
|||||||
loggingIn = true;
|
loggingIn = true;
|
||||||
|
|
||||||
CompletableFuture.supplyAsync(() -> {
|
CompletableFuture.supplyAsync(() -> {
|
||||||
StepFullJavaSession step = PendingMicrosoftAuthentication.AUTH_FLOW.apply(true, 30);
|
JavaAuthManager authManager;
|
||||||
StepFullJavaSession.FullJavaSession response;
|
MinecraftProfile mcProfile;
|
||||||
|
MinecraftToken mcToken;
|
||||||
try {
|
try {
|
||||||
response = step.refresh(MinecraftAuthLogger.INSTANCE, PendingMicrosoftAuthentication.AUTH_CLIENT, step.fromJson(GSON.fromJson(authChain, JsonObject.class)));
|
JsonObject parsedAuthChain = GSON.fromJson(authChain, JsonObject.class);
|
||||||
|
if (parsedAuthChain.has("mcProfile")) { // Old Minecraft v4 auth chain
|
||||||
|
parsedAuthChain = MinecraftAuth4To5Migrator.migrateJavaSave(parsedAuthChain, GeyserImpl.OAUTH_CONFIG);
|
||||||
|
}
|
||||||
|
|
||||||
|
authManager = JavaAuthManager.fromJson(PendingMicrosoftAuthentication.AUTH_CLIENT, parsedAuthChain);
|
||||||
|
mcProfile = authManager.getMinecraftProfile().getUpToDate();
|
||||||
|
mcToken = authManager.getMinecraftToken().getUpToDate();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
geyser.getLogger().error("Error while attempting to use auth chain for " + bedrockUsername() + "!", e);
|
geyser.getLogger().error("Error while attempting to use auth chain for " + bedrockUsername() + "!", e);
|
||||||
return Boolean.FALSE;
|
return Boolean.FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
StepMCProfile.MCProfile mcProfile = response.getMcProfile();
|
|
||||||
StepMCToken.MCToken mcToken = mcProfile.getMcToken();
|
|
||||||
|
|
||||||
protocol = new MinecraftProtocol(
|
protocol = new MinecraftProtocol(
|
||||||
new GameProfile(mcProfile.getId(), mcProfile.getName()),
|
new GameProfile(mcProfile.getId(), mcProfile.getName()),
|
||||||
mcToken.getAccessToken()
|
mcToken.getToken()
|
||||||
);
|
);
|
||||||
geyser.saveAuthChain(bedrockUsername(), GSON.toJson(step.toJson(response)));
|
geyser.saveAuthChain(bedrockUsername(), GSON.toJson(JavaAuthManager.toJson(authManager)));
|
||||||
return Boolean.TRUE;
|
return Boolean.TRUE;
|
||||||
}).whenComplete((successful, ex) -> {
|
}).whenComplete((successful, ex) -> {
|
||||||
if (this.closed) {
|
if (this.closed) {
|
||||||
@@ -1009,9 +1014,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
|||||||
return task.getAuthentication().handle((result, ex) -> {
|
return task.getAuthentication().handle((result, ex) -> {
|
||||||
if (ex != null) {
|
if (ex != null) {
|
||||||
geyser.getLogger().error("Failed to log in with Microsoft code!", ex);
|
geyser.getLogger().error("Failed to log in with Microsoft code!", ex);
|
||||||
if (ex instanceof CompletionException ce
|
if (ex instanceof CompletionException ce && ce.getCause() instanceof MinecraftProfileNotFoundException) {
|
||||||
&& ce.getCause() instanceof MinecraftRequestException mre
|
|
||||||
&& mre.getResponse().getStatusCode() == 404) {
|
|
||||||
// Player is trying to join with a Microsoft account that doesn't have Java Edition purchased
|
// Player is trying to join with a Microsoft account that doesn't have Java Edition purchased
|
||||||
disconnect(GeyserLocale.getPlayerLocaleString("geyser.network.remote.invalid_account", locale()));
|
disconnect(GeyserLocale.getPlayerLocaleString("geyser.network.remote.invalid_account", locale()));
|
||||||
} else {
|
} else {
|
||||||
@@ -1020,12 +1023,12 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
StepMCProfile.MCProfile mcProfile = result.session().getMcProfile();
|
MinecraftProfile mcProfile = result.getMinecraftProfile().getCached();
|
||||||
StepMCToken.MCToken mcToken = mcProfile.getMcToken();
|
MinecraftToken mcToken = result.getMinecraftToken().getCached();
|
||||||
|
|
||||||
this.protocol = new MinecraftProtocol(
|
this.protocol = new MinecraftProtocol(
|
||||||
new GameProfile(mcProfile.getId(), mcProfile.getName()),
|
new GameProfile(mcProfile.getId(), mcProfile.getName()),
|
||||||
mcToken.getAccessToken()
|
mcToken.getToken()
|
||||||
);
|
);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -1036,7 +1039,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Save our auth chain for later use
|
// Save our auth chain for later use
|
||||||
geyser.saveAuthChain(bedrockUsername(), GSON.toJson(result.step().toJson(result.session())));
|
geyser.saveAuthChain(bedrockUsername(), GSON.toJson(JavaAuthManager.toJson(result)));
|
||||||
return true;
|
return true;
|
||||||
}).getNow(false);
|
}).getNow(false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,20 +33,21 @@ import lombok.Setter;
|
|||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import net.lenni0451.commons.httpclient.HttpClient;
|
import net.lenni0451.commons.httpclient.HttpClient;
|
||||||
import net.raphimc.minecraftauth.MinecraftAuth;
|
import net.raphimc.minecraftauth.MinecraftAuth;
|
||||||
import net.raphimc.minecraftauth.step.java.session.StepFullJavaSession;
|
import net.raphimc.minecraftauth.java.JavaAuthManager;
|
||||||
import net.raphimc.minecraftauth.step.msa.StepMsaDeviceCode;
|
import net.raphimc.minecraftauth.msa.data.MsaConstants;
|
||||||
import net.raphimc.minecraftauth.util.MicrosoftConstants;
|
import net.raphimc.minecraftauth.msa.model.MsaApplicationConfig;
|
||||||
|
import net.raphimc.minecraftauth.msa.model.MsaDeviceCode;
|
||||||
|
import net.raphimc.minecraftauth.msa.model.MsaToken;
|
||||||
|
import net.raphimc.minecraftauth.msa.service.impl.DeviceCodeMsaAuthService;
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
import org.geysermc.geyser.GeyserImpl;
|
import org.geysermc.geyser.GeyserImpl;
|
||||||
import org.geysermc.geyser.GeyserLogger;
|
import org.geysermc.geyser.GeyserLogger;
|
||||||
import org.geysermc.geyser.util.MinecraftAuthLogger;
|
|
||||||
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.CompletionException;
|
import java.util.concurrent.CompletionException;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.function.BiFunction;
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -55,14 +56,6 @@ import java.util.function.Consumer;
|
|||||||
*/
|
*/
|
||||||
public class PendingMicrosoftAuthentication {
|
public class PendingMicrosoftAuthentication {
|
||||||
public static final HttpClient AUTH_CLIENT = MinecraftAuth.createHttpClient();
|
public static final HttpClient AUTH_CLIENT = MinecraftAuth.createHttpClient();
|
||||||
public static final BiFunction<Boolean, Integer, StepFullJavaSession> AUTH_FLOW = (offlineAccess, timeoutSec) -> MinecraftAuth.builder()
|
|
||||||
.withClientId(GeyserImpl.OAUTH_CLIENT_ID)
|
|
||||||
.withScope(offlineAccess ? "XboxLive.signin XboxLive.offline_access" : "XboxLive.signin")
|
|
||||||
.withTimeout(timeoutSec)
|
|
||||||
.deviceCode()
|
|
||||||
.withoutDeviceToken()
|
|
||||||
.regularAuthentication(MicrosoftConstants.JAVA_XSTS_RELYING_PARTY)
|
|
||||||
.buildMinecraftJavaProfileStep(false);
|
|
||||||
/**
|
/**
|
||||||
* For GeyserConnect usage.
|
* For GeyserConnect usage.
|
||||||
*/
|
*/
|
||||||
@@ -100,7 +93,7 @@ public class PendingMicrosoftAuthentication {
|
|||||||
private final String userKey;
|
private final String userKey;
|
||||||
private final int timeoutSec;
|
private final int timeoutSec;
|
||||||
@Getter
|
@Getter
|
||||||
private CompletableFuture<StepChainResult> authentication;
|
private CompletableFuture<JavaAuthManager> authentication;
|
||||||
|
|
||||||
private AuthenticationTask(String userKey, int timeoutSec) {
|
private AuthenticationTask(String userKey, int timeoutSec) {
|
||||||
this.userKey = userKey;
|
this.userKey = userKey;
|
||||||
@@ -124,11 +117,16 @@ public class PendingMicrosoftAuthentication {
|
|||||||
authentications.invalidate(userKey);
|
authentications.invalidate(userKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CompletableFuture<StepChainResult> performLoginAttempt(boolean offlineAccess, Consumer<StepMsaDeviceCode.MsaDeviceCode> deviceCodeConsumer) {
|
public CompletableFuture<JavaAuthManager> performLoginAttempt(boolean offlineAccess, Consumer<MsaDeviceCode> deviceCodeConsumer) {
|
||||||
|
MsaApplicationConfig applicationConfig = GeyserImpl.OAUTH_CONFIG.withScope(offlineAccess ? MsaConstants.SCOPE_OFFLINE_ACCESS : MsaConstants.SCOPE_NO_OFFLINE_ACCESS);
|
||||||
|
DeviceCodeMsaAuthService authService = new DeviceCodeMsaAuthService(AUTH_CLIENT, applicationConfig, deviceCodeConsumer, timeoutSec * 1000);
|
||||||
return authentication = CompletableFuture.supplyAsync(() -> {
|
return authentication = CompletableFuture.supplyAsync(() -> {
|
||||||
try {
|
try {
|
||||||
StepFullJavaSession step = AUTH_FLOW.apply(offlineAccess, timeoutSec);
|
MsaToken msaToken = authService.acquireToken();
|
||||||
return new StepChainResult(step, step.getFromInput(MinecraftAuthLogger.INSTANCE, AUTH_CLIENT, new StepMsaDeviceCode.MsaDeviceCodeCallback(deviceCodeConsumer)));
|
JavaAuthManager authManager = JavaAuthManager.create(AUTH_CLIENT).msaApplicationConfig(applicationConfig).login(msaToken);
|
||||||
|
authManager.getMinecraftToken().refresh(); // Preload the Minecraft token
|
||||||
|
authManager.getMinecraftProfile().refresh(); // Preload the Minecraft profile
|
||||||
|
return authManager;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new CompletionException(e);
|
throw new CompletionException(e);
|
||||||
}
|
}
|
||||||
@@ -154,7 +152,4 @@ public class PendingMicrosoftAuthentication {
|
|||||||
super(userKey, timeoutSec);
|
super(userKey, timeoutSec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public record StepChainResult(StepFullJavaSession step, StepFullJavaSession.FullJavaSession session) {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ package org.geysermc.geyser.util;
|
|||||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import net.raphimc.minecraftauth.step.msa.StepMsaDeviceCode;
|
import net.raphimc.minecraftauth.msa.model.MsaDeviceCode;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.auth.AuthPayload;
|
import org.cloudburstmc.protocol.bedrock.data.auth.AuthPayload;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.auth.CertificateChainPayload;
|
import org.cloudburstmc.protocol.bedrock.data.auth.CertificateChainPayload;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.auth.TokenPayload;
|
import org.cloudburstmc.protocol.bedrock.data.auth.TokenPayload;
|
||||||
@@ -215,7 +215,7 @@ public class LoginEncryptionUtils {
|
|||||||
/**
|
/**
|
||||||
* Shows the code that a user must input into their browser
|
* Shows the code that a user must input into their browser
|
||||||
*/
|
*/
|
||||||
public static void buildAndShowMicrosoftCodeWindow(GeyserSession session, StepMsaDeviceCode.MsaDeviceCode msCode) {
|
public static void buildAndShowMicrosoftCodeWindow(GeyserSession session, MsaDeviceCode msCode) {
|
||||||
String locale = session.locale();
|
String locale = session.locale();
|
||||||
|
|
||||||
StringBuilder message = new StringBuilder("%xbox.signin.website\n")
|
StringBuilder message = new StringBuilder("%xbox.signin.website\n")
|
||||||
|
|||||||
@@ -1,49 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2024 GeyserMC. http://geysermc.org
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*
|
|
||||||
* @author GeyserMC
|
|
||||||
* @link https://github.com/GeyserMC/Geyser
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.geysermc.geyser.util;
|
|
||||||
|
|
||||||
import net.raphimc.minecraftauth.util.logging.ILogger;
|
|
||||||
import org.geysermc.geyser.GeyserImpl;
|
|
||||||
|
|
||||||
public class MinecraftAuthLogger implements ILogger {
|
|
||||||
|
|
||||||
public static final MinecraftAuthLogger INSTANCE = new MinecraftAuthLogger();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void info(String message) {
|
|
||||||
GeyserImpl.getInstance().getLogger().debug(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void warn(String message) {
|
|
||||||
GeyserImpl.getInstance().getLogger().warning(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void error(String message) {
|
|
||||||
GeyserImpl.getInstance().getLogger().error(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -13,7 +13,7 @@ protocol-connection = "3.0.0.Beta10-20251014.180344-2"
|
|||||||
protocol-common = "3.0.0.Beta10-20251014.180344-2"
|
protocol-common = "3.0.0.Beta10-20251014.180344-2"
|
||||||
protocol-codec = "3.0.0.Beta10-20251014.180344-2"
|
protocol-codec = "3.0.0.Beta10-20251014.180344-2"
|
||||||
raknet = "1.0.0.CR3-20250811.214335-20"
|
raknet = "1.0.0.CR3-20250811.214335-20"
|
||||||
minecraftauth = "4.1.1"
|
minecraftauth = "5.0.0"
|
||||||
mcprotocollib = "1.21.9-20251029.184056-18"
|
mcprotocollib = "1.21.9-20251029.184056-18"
|
||||||
adventure = "4.25.0"
|
adventure = "4.25.0"
|
||||||
adventure-platform = "4.4.1"
|
adventure-platform = "4.4.1"
|
||||||
|
|||||||
Reference in New Issue
Block a user