mirror of
https://github.com/MCCTeam/Minecraft-Console-Client
synced 2026-08-15 13:04:36 +00:00
Add configurable authlib-injector API path and HTTP support for Yggdrasil auth
Re-implements the changes from PR #2890, adapted for the current codebase which uses System.Text.Json.Nodes and HttpClient instead of the legacy Json.JSONData and hand-rolled SslStream HTTP client. Changes: - Settings.cs: Convert AuthlibServer from struct to class with [TomlDoNotInlineObject]; convert Host to a property that parses 'host:port' syntax; add AuthlibInjectorAPIPath (default '/api/yggdrasil') for servers that use a different prefix (e.g. Drasl uses '/authlib-injector'); add UseHttps (default true) so local/dev auth servers without TLS work. - ConfigComments.resx: Add descriptive inline comments for the new AuthlibServer fields (Host, Port, AuthlibInjectorAPIPath, UseHttps). - ProtocolHandler.cs: Replace three hardcoded '/api/yggdrasil/...' paths with AuthlibInjectorAPIPath-based paths (authenticate, refresh, join). Replace hand-rolled TcpClient+SslStream HTTP in DoHTTPSRequest with HttpClient+SocketsHttpHandler (ConnectCallback routes through ProxyHandler). Add useHttps parameter so HTTP-only auth servers are supported. - KeyUtils.cs: Add AuthServerSupportsProfileKeys() that fetches the authlib-injector metadata endpoint and checks feature.enable_profile_key. Update GetNewProfileKeys() to skip key fetch when the auth server does not support profile keys; build the cert URL dynamically using AuthlibInjectorAPIPath for Yggdrasil; always fetch real certs instead of returning a dummy response. Remove MakeDummyResponse() which is no longer needed. Tested against a local Drasl instance with authlib-injector 1.2.7 on a 1.21.11 Minecraft server — full auth flow (login, profile key fetch, session join) confirmed working end-to-end. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
parent
72ec3122ae
commit
ff9aa62702
4 changed files with 188 additions and 142 deletions
|
|
@ -2,7 +2,6 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Text.Json.Nodes;
|
||||
using MinecraftClient.Protocol.Handlers;
|
||||
using MinecraftClient.Protocol.Message;
|
||||
using static MinecraftClient.Protocol.Message.LastSeenMessageList;
|
||||
|
|
@ -13,42 +12,87 @@ namespace MinecraftClient.Protocol.ProfileKey
|
|||
{
|
||||
private static readonly SHA256 sha256Hash = SHA256.Create();
|
||||
|
||||
private static readonly string certificates = "https://api.minecraftservices.com/player/certificates";
|
||||
|
||||
public static PlayerKeyPair? GetNewProfileKeys(string accessToken, bool isYggdrasil)
|
||||
/// <summary>
|
||||
/// Check whether the authentication server supports player profile keys.
|
||||
/// For Yggdrasil servers, this fetches the authlib-injector metadata and checks the
|
||||
/// <c>feature.enable_profile_key</c> flag documented at
|
||||
/// https://github.com/yushijinhun/authlib-injector/wiki/Yggdrasil-%E6%9C%8D%E5%8A%A1%E7%AB%AF%E6%8A%80%E6%9C%AF%E8%A7%84%E8%8C%83
|
||||
/// </summary>
|
||||
public static bool AuthServerSupportsProfileKeys(bool isYggdrasil)
|
||||
{
|
||||
if (!isYggdrasil)
|
||||
return true;
|
||||
|
||||
ProxiedWebRequest.Response? response = null;
|
||||
try
|
||||
{
|
||||
if (!isYggdrasil && string.IsNullOrWhiteSpace(accessToken))
|
||||
return null;
|
||||
|
||||
if (!isYggdrasil)
|
||||
var authServer = Settings.Config.Main.General.AuthServer;
|
||||
var request = new ProxiedWebRequest(
|
||||
(authServer.UseHttps ? "https" : "http") + "://" + authServer.Host + ":" + authServer.Port + authServer.AuthlibInjectorAPIPath)
|
||||
{
|
||||
var request = new ProxiedWebRequest(certificates)
|
||||
{
|
||||
Accept = "application/json"
|
||||
};
|
||||
request.Headers.Add("Authorization", string.Format("Bearer {0}", accessToken));
|
||||
Accept = "application/json"
|
||||
};
|
||||
|
||||
response = request.Post("application/json", "");
|
||||
response = request.Get();
|
||||
if (Settings.Config.Logging.DebugMessages)
|
||||
ConsoleIO.WriteLine(response.Body.ToString());
|
||||
|
||||
if (Settings.Config.Logging.DebugMessages)
|
||||
{
|
||||
ConsoleIO.WriteLine(response.Body.ToString());
|
||||
}
|
||||
var json = Json.ParseJson(response.Body);
|
||||
bool enableProfileKey = json?["meta"]?["feature.enable_profile_key"]?.GetStringValue() == "true";
|
||||
return enableProfileKey;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
int code = response == null ? 0 : response.StatusCode;
|
||||
ConsoleIO.WriteLineFormatted("§cFetch authlib-injector metadata failed: HttpCode = " + code + ", Error = " + e.Message);
|
||||
if (Settings.Config.Logging.DebugMessages)
|
||||
ConsoleIO.WriteLineFormatted("§c" + e.StackTrace);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (response.StatusCode < 200 || response.StatusCode >= 300)
|
||||
{
|
||||
throw new InvalidOperationException(string.IsNullOrWhiteSpace(response.Body)
|
||||
? "Certificate endpoint returned an error response."
|
||||
: response.Body);
|
||||
}
|
||||
public static PlayerKeyPair? GetNewProfileKeys(string accessToken, bool isYggdrasil)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(accessToken))
|
||||
return null;
|
||||
|
||||
if (!AuthServerSupportsProfileKeys(isYggdrasil))
|
||||
{
|
||||
if (Settings.Config.Logging.DebugMessages)
|
||||
ConsoleIO.WriteLine("AuthServer does not support profile keys, will not attempt to fetch them.");
|
||||
return null;
|
||||
}
|
||||
|
||||
string certificatesURL = "https://api.minecraftservices.com/player/certificates";
|
||||
if (isYggdrasil)
|
||||
{
|
||||
var authServer = Settings.Config.Main.General.AuthServer;
|
||||
certificatesURL = (authServer.UseHttps ? "https" : "http") + "://" + authServer.Host + ":" + authServer.Port +
|
||||
authServer.AuthlibInjectorAPIPath + "/minecraftservices/player/certificates";
|
||||
}
|
||||
|
||||
ProxiedWebRequest.Response? response = null;
|
||||
try
|
||||
{
|
||||
var request = new ProxiedWebRequest(certificatesURL)
|
||||
{
|
||||
Accept = "application/json"
|
||||
};
|
||||
request.Headers.Add("Authorization", string.Format("Bearer {0}", accessToken));
|
||||
|
||||
response = request.Post("application/json", "");
|
||||
|
||||
if (Settings.Config.Logging.DebugMessages)
|
||||
ConsoleIO.WriteLine(response.Body.ToString());
|
||||
|
||||
if (response.StatusCode < 200 || response.StatusCode >= 300)
|
||||
{
|
||||
throw new InvalidOperationException(string.IsNullOrWhiteSpace(response.Body)
|
||||
? "Certificate endpoint returned an error response."
|
||||
: response.Body);
|
||||
}
|
||||
|
||||
// see https://github.com/yushijinhun/authlib-injector/blob/da910956eaa30d2f6c2c457222d188aeb53b0d1f/src/main/java/moe/yushi/authlibinjector/httpd/ProfileKeyFilter.java#L49
|
||||
// POST to "https://api.minecraftservices.com/player/certificates" with authlib-injector will get a dummy response
|
||||
var json = isYggdrasil ? MakeDummyResponse() : Json.ParseJson(response!.Body);
|
||||
var json = Json.ParseJson(response.Body);
|
||||
if (json?["keyPair"]?["publicKey"] == null
|
||||
|| json["keyPair"]?["privateKey"] == null
|
||||
|| json["publicKeySignature"] == null
|
||||
|
|
@ -59,7 +103,6 @@ namespace MinecraftClient.Protocol.ProfileKey
|
|||
throw new InvalidOperationException("Certificate endpoint returned an unexpected payload.");
|
||||
}
|
||||
|
||||
// Error here
|
||||
PublicKey publicKey = new(pemKey: json!["keyPair"]!["publicKey"]!.GetStringValue(),
|
||||
sig: json["publicKeySignature"]!.GetStringValue(),
|
||||
sigV2: json["publicKeySignatureV2"]!.GetStringValue());
|
||||
|
|
@ -75,9 +118,7 @@ namespace MinecraftClient.Protocol.ProfileKey
|
|||
int code = response == null ? 0 : response.StatusCode;
|
||||
ConsoleIO.WriteLineFormatted("§cFetch profile key failed: HttpCode = " + code + ", Error = " + e.Message);
|
||||
if (Settings.Config.Logging.DebugMessages)
|
||||
{
|
||||
ConsoleIO.WriteLineFormatted("§c" + e.StackTrace);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -214,31 +255,5 @@ namespace MinecraftClient.Protocol.ProfileKey
|
|||
|
||||
// Delegate to the shared Json.EscapeString backed by System.Text.Json
|
||||
public static string EscapeString(string src) => Json.EscapeString(src);
|
||||
|
||||
public static JsonNode MakeDummyResponse()
|
||||
{
|
||||
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(2048);
|
||||
var mimePublicKey = Convert.ToBase64String(rsa.ExportSubjectPublicKeyInfo());
|
||||
var mimePrivateKey = Convert.ToBase64String(rsa.ExportPkcs8PrivateKey());
|
||||
string publicKeyPEM = $"-----BEGIN RSA PUBLIC KEY-----\n{mimePublicKey}\n-----END RSA PUBLIC KEY-----\n";
|
||||
string privateKeyPEM = $"-----BEGIN RSA PRIVATE KEY-----\n{mimePrivateKey}\n-----END RSA PRIVATE KEY-----\n";
|
||||
DateTime now = DateTime.UtcNow;
|
||||
DateTime expiresAt = now.AddHours(48);
|
||||
DateTime refreshedAfter = now.AddHours(36);
|
||||
string format = "yyyy-MM-ddTHH:mm:ss.ffffffZ";
|
||||
|
||||
return new JsonObject
|
||||
{
|
||||
["keyPair"] = new JsonObject
|
||||
{
|
||||
["privateKey"] = privateKeyPEM,
|
||||
["publicKey"] = publicKeyPEM
|
||||
},
|
||||
["publicKeySignature"] = "AA==",
|
||||
["publicKeySignatureV2"] = "AA==",
|
||||
["expiresAt"] = expiresAt.ToString(format),
|
||||
["refreshedAfter"] = refreshedAfter.ToString(format)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,9 +3,8 @@ using System.Collections.Generic;
|
|||
using System.Data.Odbc;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Net.Security;
|
||||
using System.Net.Http;
|
||||
using System.Net.Sockets;
|
||||
using System.Security.Authentication;
|
||||
using System.Text;
|
||||
using DnsClient;
|
||||
using MinecraftClient.Protocol.Handlers;
|
||||
|
|
@ -657,7 +656,8 @@ namespace MinecraftClient.Protocol
|
|||
JsonEncode(user) + "\", \"password\": \"" + JsonEncode(pass) +
|
||||
"\", \"clientToken\": \"" + JsonEncode(session.ClientID) + "\" }";
|
||||
int code = DoHTTPSPost(Config.Main.General.AuthServer.Host, Config.Main.General.AuthServer.Port,
|
||||
"/api/yggdrasil/authserver/authenticate", json_request, ref result);
|
||||
Config.Main.General.AuthServer.AuthlibInjectorAPIPath + "/authserver/authenticate", json_request,
|
||||
Config.Main.General.AuthServer.UseHttps, ref result);
|
||||
if (code == 200)
|
||||
{
|
||||
if (result.Contains("availableProfiles\":[]}"))
|
||||
|
|
@ -972,7 +972,8 @@ namespace MinecraftClient.Protocol
|
|||
"\", \"selectedProfile\": { \"id\": \"" + JsonEncode(currentsession.PlayerID) +
|
||||
"\", \"name\": \"" + JsonEncode(currentsession.PlayerName) + "\" } }";
|
||||
int code = DoHTTPSPost(Config.Main.General.AuthServer.Host, Config.Main.General.AuthServer.Port,
|
||||
"/api/yggdrasil/authserver/refresh", json_request, ref result);
|
||||
Config.Main.General.AuthServer.AuthlibInjectorAPIPath + "/authserver/refresh", json_request,
|
||||
Config.Main.General.AuthServer.UseHttps, ref result);
|
||||
if (code == 200)
|
||||
{
|
||||
if (result == null)
|
||||
|
|
@ -1031,10 +1032,11 @@ namespace MinecraftClient.Protocol
|
|||
: "sessionserver.mojang.com";
|
||||
int port = type == LoginType.yggdrasil ? Config.Main.General.AuthServer.Port : 443;
|
||||
string endpoint = type == LoginType.yggdrasil
|
||||
? "/api/yggdrasil/sessionserver/session/minecraft/join"
|
||||
? Config.Main.General.AuthServer.AuthlibInjectorAPIPath + "/sessionserver/session/minecraft/join"
|
||||
: "/session/minecraft/join";
|
||||
|
||||
int code = DoHTTPSPost(host, port, endpoint, json_request, ref result);
|
||||
bool useHttps = type == LoginType.yggdrasil ? Config.Main.General.AuthServer.UseHttps : true;
|
||||
int code = DoHTTPSPost(host, port, endpoint, json_request, useHttps, ref result);
|
||||
return (code >= 200 && code < 300);
|
||||
}
|
||||
catch
|
||||
|
|
@ -1156,61 +1158,68 @@ namespace MinecraftClient.Protocol
|
|||
/// Make a HTTPS GET request to the specified endpoint of the Mojang API
|
||||
/// </summary>
|
||||
/// <param name="host">Host to connect to</param>
|
||||
/// <param name="endpoint">Endpoint for making the request</param>
|
||||
/// <param name="port">Port to connect on</param>
|
||||
/// <param name="path">Path for making the request</param>
|
||||
/// <param name="cookies">Cookies for making the request</param>
|
||||
/// <param name="result">Request result</param>
|
||||
/// <returns>HTTP Status code</returns>
|
||||
private static int DoHTTPSGet(string host, int port, string endpoint, string cookies, ref string result)
|
||||
private static int DoHTTPSGet(string host, int port, string path, string cookies, ref string result)
|
||||
{
|
||||
List<String> http_request = new()
|
||||
Dictionary<string, string> headers = new()
|
||||
{
|
||||
"GET " + endpoint + " HTTP/1.1",
|
||||
"Cookie: " + cookies,
|
||||
"Cache-Control: no-cache",
|
||||
"Pragma: no-cache",
|
||||
"Host: " + host,
|
||||
"User-Agent: Java/1.6.0_27",
|
||||
"Accept-Charset: ISO-8859-1,UTF-8;q=0.7,*;q=0.7",
|
||||
"Connection: close",
|
||||
"",
|
||||
""
|
||||
{ "Cookie", cookies },
|
||||
{ "Cache-Control", "no-cache" },
|
||||
{ "Pragma", "no-cache" },
|
||||
{ "User-Agent", "Java/1.6.0_27" }
|
||||
};
|
||||
return DoHTTPSRequest(http_request, host, port, ref result);
|
||||
return DoHTTPSRequest(HttpMethod.Get, host, port, path, headers, null, useHttps: true, ref result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Make a HTTPS POST request to the specified endpoint of the Mojang API
|
||||
/// Make a POST request to the specified endpoint of the Mojang API
|
||||
/// </summary>
|
||||
/// <param name="host">Host to connect to</param>
|
||||
/// <param name="endpoint">Endpoint for making the request</param>
|
||||
/// <param name="request">Request payload</param>
|
||||
/// <param name="port">Port to connect on</param>
|
||||
/// <param name="path">Path for making the request</param>
|
||||
/// <param name="body">Request payload</param>
|
||||
/// <param name="result">Request result</param>
|
||||
/// <returns>HTTP Status code</returns>
|
||||
private static int DoHTTPSPost(string host, int port, string endpoint, string request, ref string result)
|
||||
private static int DoHTTPSPost(string host, int port, string path, string body, ref string result)
|
||||
=> DoHTTPSPost(host, port, path, body, useHttps: true, ref result);
|
||||
|
||||
/// <summary>
|
||||
/// Make a POST request to the specified endpoint of the Mojang API
|
||||
/// </summary>
|
||||
/// <param name="host">Host to connect to</param>
|
||||
/// <param name="port">Port to connect on</param>
|
||||
/// <param name="path">Path for making the request</param>
|
||||
/// <param name="body">Request payload</param>
|
||||
/// <param name="useHttps">Whether to use HTTPS (true) or plain HTTP (false)</param>
|
||||
/// <param name="result">Request result</param>
|
||||
/// <returns>HTTP Status code</returns>
|
||||
private static int DoHTTPSPost(string host, int port, string path, string body, bool useHttps, ref string result)
|
||||
{
|
||||
List<String> http_request = new()
|
||||
Dictionary<string, string> headers = new()
|
||||
{
|
||||
"POST " + endpoint + " HTTP/1.1",
|
||||
"Host: " + host,
|
||||
"User-Agent: MCC/" + Program.Version,
|
||||
"Content-Type: application/json",
|
||||
"Content-Length: " + Encoding.ASCII.GetBytes(request).Length,
|
||||
"Connection: close",
|
||||
"",
|
||||
request
|
||||
{ "User-Agent", "MCC/" + Program.Version },
|
||||
{ "Content-Type", "application/json" }
|
||||
};
|
||||
return DoHTTPSRequest(http_request, host, port, ref result);
|
||||
return DoHTTPSRequest(HttpMethod.Post, host, port, path, headers, body, useHttps, ref result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Manual HTTPS request since we must directly use a TcpClient because of the proxy.
|
||||
/// This method connects to the server, enables SSL, do the request and read the response.
|
||||
/// This method connects to the server and performs an HTTP or HTTPS request via proxy if configured.
|
||||
/// </summary>
|
||||
/// <param name="headers">Request headers and optional body (POST)</param>
|
||||
/// <param name="method">HTTP method</param>
|
||||
/// <param name="host">Host to connect to</param>
|
||||
/// <param name="port">Port to connect on</param>
|
||||
/// <param name="path">Request path</param>
|
||||
/// <param name="headers">Request headers</param>
|
||||
/// <param name="body">Optional request body (POST)</param>
|
||||
/// <param name="useHttps">Whether to use HTTPS (true) or plain HTTP (false)</param>
|
||||
/// <param name="result">Request result</param>
|
||||
/// <returns>HTTP Status code</returns>
|
||||
private static int DoHTTPSRequest(List<string> headers, string host, int port, ref string result)
|
||||
private static int DoHTTPSRequest(HttpMethod method, string host, int port, string path, Dictionary<string, string> headers, string? body, bool useHttps, ref string result)
|
||||
{
|
||||
string? postResult = null;
|
||||
int statusCode = 520;
|
||||
|
|
@ -1222,40 +1231,45 @@ namespace MinecraftClient.Protocol
|
|||
if (Settings.Config.Logging.DebugMessages)
|
||||
ConsoleIO.WriteLineFormatted("§8" + string.Format(Translations.debug_request, host));
|
||||
|
||||
TcpClient client = ProxyHandler.NewTcpClient(host, port, true);
|
||||
SslStream stream = new(client.GetStream());
|
||||
stream.AuthenticateAsClient(host, null, SslProtocols.Tls12,
|
||||
true); // Enable TLS 1.2. Hotfix for #1780
|
||||
using SocketsHttpHandler handler = new SocketsHttpHandler();
|
||||
handler.ConnectCallback = async (ctx, ct) =>
|
||||
{
|
||||
TcpClient client = ProxyHandler.NewTcpClient(host, port, true);
|
||||
return client.GetStream();
|
||||
};
|
||||
|
||||
using HttpClient client = new HttpClient(handler);
|
||||
|
||||
string scheme = useHttps ? "https" : "http";
|
||||
var request = new HttpRequestMessage(method, scheme + "://" + host + ":" + port + path);
|
||||
|
||||
var contentType = "text/plain";
|
||||
foreach (var header in headers)
|
||||
{
|
||||
request.Headers.TryAddWithoutValidation(header.Key, header.Value);
|
||||
if (header.Key.Equals("Content-Type", StringComparison.OrdinalIgnoreCase))
|
||||
contentType = header.Value;
|
||||
}
|
||||
|
||||
if (body != null)
|
||||
request.Content = new StringContent(body, Encoding.UTF8, contentType);
|
||||
|
||||
if (Settings.Config.Logging.DebugMessages)
|
||||
foreach (string line in headers)
|
||||
ConsoleIO.WriteLineFormatted("§8> " + line);
|
||||
ConsoleIO.WriteLineFormatted("§8> " + request);
|
||||
|
||||
stream.Write(Encoding.ASCII.GetBytes(String.Join("\r\n", headers.ToArray())));
|
||||
System.IO.StreamReader sr = new(stream);
|
||||
string raw_result = sr.ReadToEnd();
|
||||
HttpResponseMessage response = client.SendAsync(request).GetAwaiter().GetResult();
|
||||
statusCode = (int)response.StatusCode;
|
||||
|
||||
postResult = statusCode == 204
|
||||
? "No Content"
|
||||
: response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
|
||||
|
||||
if (Settings.Config.Logging.DebugMessages)
|
||||
{
|
||||
ConsoleIO.WriteLine("");
|
||||
foreach (string line in raw_result.Split('\n'))
|
||||
foreach (string line in postResult.Split('\n'))
|
||||
ConsoleIO.WriteLineFormatted("§8< " + line);
|
||||
}
|
||||
|
||||
if (raw_result.StartsWith("HTTP/1.1"))
|
||||
{
|
||||
statusCode = int.Parse(raw_result.Split(' ')[1], NumberStyles.Any, CultureInfo.CurrentCulture);
|
||||
if (statusCode != 204)
|
||||
{
|
||||
var splited = raw_result[(raw_result.IndexOf("\r\n\r\n") + 4)..].Split("\r\n");
|
||||
postResult = splited[1] + splited[3];
|
||||
}
|
||||
else
|
||||
{
|
||||
postResult = "No Content";
|
||||
}
|
||||
}
|
||||
else statusCode = 520; //Web server is returning an unknown error
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -850,7 +850,19 @@ If the connection to the Minecraft game server is blocked by the firewall, set E
|
|||
<value>Ignore invalid player name</value>
|
||||
</data>
|
||||
<data name="Main.General.AuthlibServer" xml:space="preserve">
|
||||
<value>Yggdrasil authlib server domain name and port.</value>
|
||||
<value>authlib-injector authentication server to use for Yggdrasil accounts</value>
|
||||
</data>
|
||||
<data name="AuthlibServer.Host" xml:space="preserve">
|
||||
<value>Domain name or IP address</value>
|
||||
</data>
|
||||
<data name="AuthlibServer.Port" xml:space="preserve">
|
||||
<value>Port to connect on</value>
|
||||
</data>
|
||||
<data name="AuthlibServer.AuthlibInjectorAPIPath" xml:space="preserve">
|
||||
<value>Path component of the authlib-injector API location. Refer to the authlib-injector documentation for more info.</value>
|
||||
</data>
|
||||
<data name="AuthlibServer.UseHttps" xml:space="preserve">
|
||||
<value>Set to false if your authlib-injector server uses plain HTTP (e.g. for local testing without TLS).</value>
|
||||
</data>
|
||||
<data name="Main.Advanced.enable_sentry" xml:space="preserve">
|
||||
<value>Set to false to opt-out of Sentry error logging.</value>
|
||||
|
|
|
|||
|
|
@ -495,7 +495,7 @@ namespace MinecraftClient
|
|||
[TomlInlineComment("$Main.General.method$")]
|
||||
public LoginMethod Method = LoginMethod.mcc;
|
||||
[TomlInlineComment("$Main.General.AuthlibServer$")]
|
||||
public AuthlibServer AuthServer = new(string.Empty);
|
||||
public AuthlibServer AuthServer = new();
|
||||
|
||||
[TomlInlineComment("$Main.General.AuthlibUser$")]
|
||||
public string AuthUser = "";
|
||||
|
|
@ -709,34 +709,39 @@ namespace MinecraftClient
|
|||
this.Port = Port;
|
||||
}
|
||||
}
|
||||
public struct AuthlibServer
|
||||
[TomlDoNotInlineObject]
|
||||
public class AuthlibServer
|
||||
{
|
||||
public string Host = string.Empty;
|
||||
public int Port = 443;
|
||||
[NonSerialized]
|
||||
private string _host = string.Empty;
|
||||
|
||||
public AuthlibServer()
|
||||
[TomlInlineComment("$AuthlibServer.Host$")]
|
||||
public string Host
|
||||
{
|
||||
Host = string.Empty;
|
||||
Port = 443;
|
||||
}
|
||||
|
||||
public AuthlibServer(string Host)
|
||||
{
|
||||
string[] sip = Host.Split(new[] { ":", ":" }, StringSplitOptions.None);
|
||||
this.Host = sip[0];
|
||||
|
||||
if (sip.Length > 1)
|
||||
get => _host;
|
||||
set
|
||||
{
|
||||
try { this.Port = Convert.ToUInt16(sip[1]); }
|
||||
catch (FormatException) { }
|
||||
string[] split = value.Split(new[] { ":", ":" }, StringSplitOptions.None);
|
||||
if (split.Length >= 1)
|
||||
_host = split[0];
|
||||
if (split.Length >= 2)
|
||||
{
|
||||
try { Port = Convert.ToUInt16(split[1]); }
|
||||
catch (FormatException) { }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public AuthlibServer(string Host, ushort Port)
|
||||
{
|
||||
this.Host = Host.Split(new[] { ":", ":" }, StringSplitOptions.None)[0];
|
||||
this.Port = Port;
|
||||
}
|
||||
[TomlInlineComment("$AuthlibServer.Port$")]
|
||||
public int Port = 443;
|
||||
|
||||
[TomlInlineComment("$AuthlibServer.AuthlibInjectorAPIPath$")]
|
||||
public string AuthlibInjectorAPIPath = "/api/yggdrasil";
|
||||
|
||||
[TomlInlineComment("$AuthlibServer.UseHttps$")]
|
||||
public bool UseHttps = true;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue