mirror of
https://github.com/LeavesMC/Leaves.git
synced 2025-12-19 14:59:32 +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 f1e7c7f0fa1d6a8f61de4215eabc121ab2a0b67f..91e07f127361bd573ccd59f37fcba93b300c289a 100644
|
|
--- a/src/main/java/com/mojang/authlib/yggdrasil/YggdrasilMinecraftSessionService.java
|
|
+++ b/src/main/java/com/mojang/authlib/yggdrasil/YggdrasilMinecraftSessionService.java
|
|
@@ -44,7 +44,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 ec268189b19b6fa5c4521f96ce211a531db35ec5..24376290ac1d5f5e140ff06b23f9711b38de362e 100644
|
|
--- a/src/main/java/net/minecraft/server/Main.java
|
|
+++ b/src/main/java/net/minecraft/server/Main.java
|
|
@@ -201,7 +201,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 3f4b4d905ff440eaf4a66b10ad85933c0b07dc58..7dec27260fce938f5d1e5c437f564ed9cee575f3 100644
|
|
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
|
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
|
@@ -253,7 +253,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
|
private boolean isDemo;
|
|
private volatile boolean isReady;
|
|
private long lastOverloadWarning;
|
|
- protected final Services services;
|
|
+ public final Services services; // Leaves - protected -> public
|
|
private long lastServerStatus;
|
|
public final Thread serverThread;
|
|
private long nextTickTime;
|
|
diff --git a/src/main/java/top/leavesmc/leaves/LeavesConfig.java b/src/main/java/top/leavesmc/leaves/LeavesConfig.java
|
|
index fccce21591136beac85a41bd1b4df3cc5569faf0..517e0c8d362bf6004e51109dfcb20562d00d4903 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;
|
|
@@ -527,6 +528,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;
|
|
+ }
|
|
+}
|