mirror of
https://github.com/LeavesMC/Leaves.git
synced 2025-12-23 08:59:31 +00:00
213 lines
11 KiB
Diff
213 lines
11 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: violetc <58360096+s-yh-china@users.noreply.github.com>
|
|
Date: Thu, 2 Feb 2023 16:01:18 +0800
|
|
Subject: [PATCH] Leaves Extra Yggdrasil Service
|
|
|
|
|
|
diff --git a/src/main/java/com/destroystokyo/paper/profile/PaperAuthenticationService.java b/src/main/java/com/destroystokyo/paper/profile/PaperAuthenticationService.java
|
|
index 48e774677edf17d4a99ae9ed23d1b371dab41abb..21409ff86db65c00d92bff9eae8bdeb3a872a361 100644
|
|
--- a/src/main/java/com/destroystokyo/paper/profile/PaperAuthenticationService.java
|
|
+++ b/src/main/java/com/destroystokyo/paper/profile/PaperAuthenticationService.java
|
|
@@ -11,7 +11,7 @@ import java.net.Proxy;
|
|
|
|
public class PaperAuthenticationService extends YggdrasilAuthenticationService {
|
|
|
|
- private final Environment environment;
|
|
+ protected final Environment environment; // Leaves - private -> protected
|
|
|
|
public PaperAuthenticationService(Proxy proxy) {
|
|
super(proxy);
|
|
diff --git a/src/main/java/com/mojang/authlib/yggdrasil/YggdrasilMinecraftSessionService.java b/src/main/java/com/mojang/authlib/yggdrasil/YggdrasilMinecraftSessionService.java
|
|
index bfc1e27c37689c1fbb927404a7176780a439a057..bc8ab50ef1390a2c51110a89dc43db58215396a9 100644
|
|
--- a/src/main/java/com/mojang/authlib/yggdrasil/YggdrasilMinecraftSessionService.java
|
|
+++ b/src/main/java/com/mojang/authlib/yggdrasil/YggdrasilMinecraftSessionService.java
|
|
@@ -46,7 +46,7 @@ import java.util.stream.Collectors;
|
|
|
|
public class YggdrasilMinecraftSessionService implements MinecraftSessionService {
|
|
private static final Logger LOGGER = LoggerFactory.getLogger(YggdrasilMinecraftSessionService.class);
|
|
- private final MinecraftClient client;
|
|
+ protected final MinecraftClient client; // Leaves - private -> protected
|
|
private final ServicesKeySet servicesKeySet;
|
|
private final String baseUrl;
|
|
private final URL joinUrl;
|
|
diff --git a/src/main/java/net/minecraft/server/Main.java b/src/main/java/net/minecraft/server/Main.java
|
|
index 7573c12a77797146c51ef2dfe4b2a636df45e21a..458c69eee97a5284b8e7658450cbac32a52137fe 100644
|
|
--- a/src/main/java/net/minecraft/server/Main.java
|
|
+++ b/src/main/java/net/minecraft/server/Main.java
|
|
@@ -198,7 +198,7 @@ public class Main {
|
|
file = new File(bukkitConfiguration.getString("settings.world-container", "."));
|
|
}
|
|
// Paper end - fix SPIGOT-5824
|
|
- Services services = Services.create(new com.destroystokyo.paper.profile.PaperAuthenticationService(Proxy.NO_PROXY), file, userCacheFile, optionset); // Paper
|
|
+ Services services = Services.create(new top.leavesmc.leaves.profile.LeavesAuthenticationService(Proxy.NO_PROXY), file, userCacheFile, optionset); // Paper // Leaves - extra-yggdrasil-service
|
|
// CraftBukkit start
|
|
String s = (String) Optional.ofNullable((String) optionset.valueOf("world")).orElse(dedicatedserversettings.getProperties().levelName);
|
|
LevelStorageSource convertable = LevelStorageSource.createDefault(file.toPath());
|
|
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
|
index 89a50e07bc79cb0d5353f5a06fa037f3942c5940..760b1fb833fea279062965002686b57f967a5eaf 100644
|
|
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
|
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
|
@@ -260,7 +260,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
|
private boolean isDemo;
|
|
private volatile boolean isReady;
|
|
private long lastOverloadWarningNanos;
|
|
- protected final Services services;
|
|
+ public final Services services; // Leaves - protected -> public
|
|
private long lastServerStatus;
|
|
public final Thread serverThread;
|
|
private long nextTickTimeNanos;
|
|
diff --git a/src/main/java/top/leavesmc/leaves/LeavesConfig.java b/src/main/java/top/leavesmc/leaves/LeavesConfig.java
|
|
index dd8c222661a7facb6f9cd64e19676cfe4eee50a6..94beb47e3ebc5dca07b388ee856c1bfe820e2174 100644
|
|
--- a/src/main/java/top/leavesmc/leaves/LeavesConfig.java
|
|
+++ b/src/main/java/top/leavesmc/leaves/LeavesConfig.java
|
|
@@ -11,6 +11,7 @@ import org.bukkit.configuration.file.YamlConfiguration;
|
|
import top.leavesmc.leaves.command.LeavesCommand;
|
|
import top.leavesmc.leaves.bot.BotCommand;
|
|
import top.leavesmc.leaves.bot.agent.Actions;
|
|
+import top.leavesmc.leaves.profile.LeavesMinecraftSessionService;
|
|
import top.leavesmc.leaves.util.MathUtils;
|
|
|
|
import java.io.File;
|
|
@@ -529,6 +530,9 @@ public final class LeavesConfig {
|
|
extraYggdrasilLoginProtect = getBoolean("settings.misc.extra-yggdrasil-service.login-protect", extraYggdrasilLoginProtect);
|
|
extraYggdrasilServiceList = getList("settings.misc.extra-yggdrasil-service.urls", extraYggdrasilServiceList);
|
|
if (extraYggdrasilService) {
|
|
+ LeavesLogger.LOGGER.warning("extra-yggdrasil-service is an unofficial support. Enabling it may cause data security problems!");
|
|
+ GlobalConfiguration.get().unsupportedSettings.performUsernameValidation = true; // always check user name
|
|
+ LeavesMinecraftSessionService.initExtraYggdrasilList();
|
|
}
|
|
}
|
|
|
|
diff --git a/src/main/java/top/leavesmc/leaves/profile/LeavesAuthenticationService.java b/src/main/java/top/leavesmc/leaves/profile/LeavesAuthenticationService.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..3da207a13fce243bf880c8a4f7054cf20997991d
|
|
--- /dev/null
|
|
+++ b/src/main/java/top/leavesmc/leaves/profile/LeavesAuthenticationService.java
|
|
@@ -0,0 +1,18 @@
|
|
+package top.leavesmc.leaves.profile;
|
|
+
|
|
+import com.destroystokyo.paper.profile.PaperAuthenticationService;
|
|
+import com.mojang.authlib.minecraft.MinecraftSessionService;
|
|
+
|
|
+import java.net.Proxy;
|
|
+
|
|
+public class LeavesAuthenticationService extends PaperAuthenticationService {
|
|
+
|
|
+ public LeavesAuthenticationService(Proxy proxy) {
|
|
+ super(proxy);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public MinecraftSessionService createMinecraftSessionService() {
|
|
+ return new LeavesMinecraftSessionService(this.getServicesKeySet(), this.getProxy(), this.environment);
|
|
+ }
|
|
+}
|
|
diff --git a/src/main/java/top/leavesmc/leaves/profile/LeavesMinecraftSessionService.java b/src/main/java/top/leavesmc/leaves/profile/LeavesMinecraftSessionService.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..9bfa0d0c12ac2a44968cd39b6d9f406defb23c07
|
|
--- /dev/null
|
|
+++ b/src/main/java/top/leavesmc/leaves/profile/LeavesMinecraftSessionService.java
|
|
@@ -0,0 +1,102 @@
|
|
+package top.leavesmc.leaves.profile;
|
|
+
|
|
+import com.destroystokyo.paper.profile.PaperMinecraftSessionService;
|
|
+import com.mojang.authlib.Environment;
|
|
+import com.mojang.authlib.GameProfile;
|
|
+import com.mojang.authlib.HttpAuthenticationService;
|
|
+import com.mojang.authlib.exceptions.AuthenticationUnavailableException;
|
|
+import com.mojang.authlib.exceptions.MinecraftClientException;
|
|
+import com.mojang.authlib.yggdrasil.ProfileActionType;
|
|
+import com.mojang.authlib.yggdrasil.ProfileResult;
|
|
+import com.mojang.authlib.yggdrasil.ServicesKeySet;
|
|
+import com.mojang.authlib.yggdrasil.response.HasJoinedMinecraftServerResponse;
|
|
+import com.mojang.authlib.yggdrasil.response.ProfileAction;
|
|
+import net.minecraft.server.MinecraftServer;
|
|
+import net.minecraft.server.level.ServerPlayer;
|
|
+import org.jetbrains.annotations.Nullable;
|
|
+import top.leavesmc.leaves.LeavesConfig;
|
|
+import top.leavesmc.leaves.bot.ServerBot;
|
|
+
|
|
+import java.net.InetAddress;
|
|
+import java.net.Proxy;
|
|
+import java.net.URL;
|
|
+import java.util.ArrayList;
|
|
+import java.util.Collections;
|
|
+import java.util.HashMap;
|
|
+import java.util.List;
|
|
+import java.util.Map;
|
|
+import java.util.Set;
|
|
+import java.util.stream.Collectors;
|
|
+
|
|
+public class LeavesMinecraftSessionService extends PaperMinecraftSessionService {
|
|
+
|
|
+ protected LeavesMinecraftSessionService(ServicesKeySet keySet, Proxy authenticationService, Environment environment) {
|
|
+ super(keySet, authenticationService, environment);
|
|
+ }
|
|
+
|
|
+ private static List<URL> extraYggdrasilList = List.of();
|
|
+
|
|
+ public static void initExtraYggdrasilList() {
|
|
+ List<URL> list = new ArrayList<>();
|
|
+ for (String str : LeavesConfig.extraYggdrasilServiceList) {
|
|
+ list.add(HttpAuthenticationService.constantURL(str + "/sessionserver/session/minecraft/hasJoined"));
|
|
+ }
|
|
+ extraYggdrasilList = Collections.unmodifiableList(list);
|
|
+ }
|
|
+
|
|
+ @Nullable
|
|
+ @Override
|
|
+ public ProfileResult hasJoinedServer(String profileName, String serverId, @Nullable InetAddress address) throws AuthenticationUnavailableException {
|
|
+ ProfileResult result = super.hasJoinedServer(profileName, serverId, address); // mojang
|
|
+
|
|
+ ServerPlayer player = MinecraftServer.getServer().getPlayerList().getPlayerByName(profileName);
|
|
+ if (player != null && !(player instanceof ServerBot)) {
|
|
+ return null; // if it has same name, return null
|
|
+ }
|
|
+
|
|
+ if (LeavesConfig.extraYggdrasilService && result == null) {
|
|
+ final Map<String, Object> arguments = new HashMap<>();
|
|
+ arguments.put("username", profileName);
|
|
+ arguments.put("serverId", serverId);
|
|
+
|
|
+ if (address != null) {
|
|
+ arguments.put("ip", address.getHostAddress());
|
|
+ }
|
|
+
|
|
+ GameProfile cache = null;
|
|
+ if (LeavesConfig.extraYggdrasilLoginProtect) {
|
|
+ cache = MinecraftServer.getServer().services.profileCache().getProfileIfCached(profileName);
|
|
+ }
|
|
+
|
|
+ for (URL checkUrl : extraYggdrasilList) {
|
|
+ URL url = HttpAuthenticationService.concatenateURL(checkUrl, HttpAuthenticationService.buildQuery(arguments));
|
|
+ try {
|
|
+ final HasJoinedMinecraftServerResponse response = client.get(url, HasJoinedMinecraftServerResponse.class);
|
|
+ if (response != null && response.id() != null) {
|
|
+ if (LeavesConfig.extraYggdrasilLoginProtect && cache != null) {
|
|
+ if (response.id() != cache.getId()) {
|
|
+ continue;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ final GameProfile result1 = new GameProfile(response.id(), profileName);
|
|
+
|
|
+ if (response.properties() != null) {
|
|
+ result1.getProperties().putAll(response.properties());
|
|
+ }
|
|
+
|
|
+ final Set<ProfileActionType> profileActions = response.profileActions().stream()
|
|
+ .map(ProfileAction::type)
|
|
+ .collect(Collectors.toSet());
|
|
+ return new ProfileResult(result1, profileActions);
|
|
+ }
|
|
+ } catch (final MinecraftClientException e) {
|
|
+ if (e.toAuthenticationException() instanceof final AuthenticationUnavailableException unavailable) {
|
|
+ throw unavailable;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ return result;
|
|
+ }
|
|
+}
|