using System.Net; using System.Security.Cryptography; using System.Text.Json; using System.Text.Json.Nodes; using System.Xml; const string mavenMetadataUrl = "https://maven.ely.by/releases/by/ely/authlib/maven-metadata.xml"; const string authlibInjectorUrl = "https://github.com/yushijinhun/authlib-injector/releases/download/v1.2.5/authlib-injector-1.2.5.jar"; const string metadataOutputFile = "epl_metadata.json"; Console.WriteLine($"Using Authlib metadata from: {mavenMetadataUrl}"); Console.WriteLine($"Will insert authlib-injector link: {authlibInjectorUrl}"); var client = new HttpClient(); var metadataXml = await client.GetStringAsync(mavenMetadataUrl); var document = new XmlDocument(); document.LoadXml(metadataXml); var versioning = document["metadata"]!["versioning"]; var versions = versioning!["versions"]!.GetElementsByTagName("version"); var versionsDict = new Dictionary(); foreach (var versionObject in versions) { var versionElement = versionObject as XmlElement; var fullVersion = versionElement!.InnerText; var authlibVersion = fullVersion.Split('-').First(); if (versionsDict.TryGetValue(authlibVersion, out var existing)) { var newElyPatchNumber = Convert.ToInt32(fullVersion.Split('.').Last()); var existingElyPatchNumber = Convert.ToInt32(existing.Split('.').Last()); if (newElyPatchNumber > existingElyPatchNumber) { versionsDict.Remove(authlibVersion); Console.WriteLine($"Discarded patched version '{existing}'"); } else { continue; } } versionsDict.Add(authlibVersion, fullVersion); Console.WriteLine($"Mapped Authlib version '{authlibVersion}' to patched version '{fullVersion}'"); } versionsDict = versionsDict.OrderByDescending(kvp => { var versionNumbers = kvp.Key.Split('.'); var score = 0; if (versionNumbers.Length > 0) { score += 1_000_000 * Convert.ToInt32(versionNumbers[0]); } if (versionNumbers.Length > 1) { score += 1_000 * Convert.ToInt32(versionNumbers[1]); } if (versionNumbers.Length > 2) { score += Convert.ToInt32(versionNumbers[2]); } return score; }).ToDictionary(); var overrides = new JsonObject(); foreach (var version in versionsDict) { var downloadUrl = $"https://llaun.ch/repo/libraries/by/ely/authlib/{version.Value}/authlib-{version.Value}.jar"; var (success, result) = await TryDownload(downloadUrl); if (!success) { downloadUrl = $"https://x.mctaylors.ru/epl/authlib/authlib-{version.Value}.jar"; (success, result) = await TryDownload(downloadUrl); if (success) { Console.Error.WriteLine($"Using x.mctaylors.ru for authlib '{version.Value}'"); } else { Console.Error.WriteLine($"Unable to find authlib '{version.Value}'"); continue; } } else { Console.WriteLine($"Using llaun.ch for authlib '{version.Value}'"); } var sha1 = Convert.ToHexStringLower(SHA1.HashData(result!)); var size = result!.Length; overrides[version.Key] = new JsonObject { ["url"] = downloadUrl, ["sha1"] = sha1, ["size"] = size }; } var root = new JsonObject { ["overrides"] = new JsonObject { ["com.mojang:authlib"] = overrides }, ["extras"] = new JsonObject { ["authlib-injector"] = authlibInjectorUrl } }; await using var output = File.Create(metadataOutputFile); Console.WriteLine($"Writing metadata to '{Path.GetFullPath(metadataOutputFile)}'"); await JsonSerializer.SerializeAsync(output, root, new JsonSerializerOptions { WriteIndented = true }); Console.WriteLine("Complete!"); return; async Task<(bool success, byte[]? output)> TryDownload(string url) { try { return (true, await client.GetByteArrayAsync(url)); } catch (HttpRequestException e) { if (e.StatusCode != HttpStatusCode.NotFound) throw; return (false, null); } }