public static VersionLibrary FromJSON(JObject json, MinecraftProfile profile) { VersionLibrary lib = new VersionLibrary(); lib.JSON = json; lib.LibraryName = LibraryName.Parse(json["name"].ToString()); lib.Downloads = new LibraryDownloads(json, profile, lib); return(lib); }
public override void Install(DownloadingEventHandler dlevent) { Forge forgeType = GetDownloadAPI(); Logger.LogInfo("Start to Install Forge " + forgeType.VersionName); string installerFilePath = Path.Combine(@"OMCLC\Plugins\Data\EDGW\Downloader-Temps", Guid.NewGuid().ToString()) + "-forge-installer.jar"; string installerDirectoryPath = Path.Combine(@"OMCLC\Plugins\Data\EDGW\Downloader-Temps", Guid.NewGuid().ToString()); //Install Jar { Logger.LogInfo("Install Forge JAR"); var jarList = new Dictionary <NeedDownloadFile, string>() { }; jarList.Add(new NeedDownloadFile() { FileName = AddrTranslater.TranslateURL(forgeType.DownloadAddr), FileName2 = forgeType.DownloadAddr, Hash = "" }, installerFilePath); DownloadTask jarDownloadTask = new DownloadTask(jarList); var downloadFaiures = jarDownloadTask.Download((float percent) => { }); if (downloadFaiures.Count > 0) { foreach (var failure in downloadFaiures) { Logger.LogError("Failed to Download File:" + failure.Value); } throw downloadFaiures.First().Value; } dlevent(0.2f); } //Resolve Jar { Logger.LogInfo("Resolve Installer"); var installerJAR = ZipFile.Open(installerFilePath, ZipArchiveMode.Update); Directory.CreateDirectory(installerDirectoryPath + "-extract"); installerJAR.ExtractToDirectory(installerDirectoryPath + "-extract"); { var profileEntry = installerJAR.GetEntry("install_profile.json"); profileEntry.ExtractToFile(installerFilePath + "-profile.tmp"); } { var versionEntry = installerJAR.GetEntry("version.json"); versionEntry.ExtractToFile(installerFilePath + "-version.tmp"); } JObject profile = JObject.Parse(File.ReadAllText(installerFilePath + "-profile.tmp")); JObject injectData = JObject.Parse(File.ReadAllText(installerFilePath + "-version.tmp")); Logger.LogInfo("Resolve Install-Profile"); if (profile["install"] == null) { //>=1.12.2 version switch ((int)profile["spec"]) { case 1: { //>=1.17 { Logger.LogInfo("Download Necessary Libraries"); VersionLibraries libraries = new VersionLibraries(); foreach (JObject libJSON in profile["libraries"] as JArray) { VersionLibrary library = VersionLibrary.FromJSON(libJSON, GameProfile); if (libJSON["downloads"]["artifact"]["url"].ToString() == "") { Logger.LogInfo("Extract Maven"); { var mavenEntry = installerJAR.GetEntry("maven/" + libJSON["downloads"]["artifact"]["path"].ToString()); Directory.CreateDirectory(Path.Combine(GameSettings.SelectedGameDirectory.FullName , "libraries" , Path.GetDirectoryName(libJSON["downloads"]["artifact"]["path"].ToString()))); mavenEntry.ExtractToFile(Path.Combine(GameSettings.SelectedGameDirectory.FullName , "libraries" , libJSON["downloads"]["artifact"]["path"].ToString())); } Logger.LogInfo("Extract Maven Successfully"); } else { libraries.Add(library); } } //Download JARs; { DownloadTask jarDownloadTask = new DownloadTask(libraries.GetNeedToInstallFiles()); var failures = jarDownloadTask.Download((float percent) => { dlevent(0.2f + (0.5f * percent)); }); if (failures.Count > 0) { foreach (var failure in failures) { Logger.LogError("Failed to Download File:" + failure.Value); } throw failures.First().Value; } } //Run Mappings { Logger.LogInfo("Start Mapping Process"); JObject dataKeys = profile["data"] as JObject; dataKeys["MINECRAFT_VERSION"] = new JObject(); dataKeys["INSTALLER"] = new JObject(); dataKeys["SIDE"] = new JObject(); dataKeys["MINECRAFT_JAR"] = new JObject(); dataKeys["ROOT"] = new JObject(); dataKeys["MINECRAFT_VERSION"]["client"] = GameProfile.VersionName; dataKeys["INSTALLER"]["client"] = installerFilePath; dataKeys["SIDE"]["client"] = "client"; dataKeys["MINECRAFT_JAR"]["client"] = GameProfile.JARPath; dataKeys["ROOT"]["client"] = GameSettings.SelectedGameDirectory.FullName; foreach (JObject precessorObject in profile["processors"]) { Logger.LogInfo("Run Processor " + precessorObject); if (precessorObject["sides"] == null) { precessorObject["sides"] = new JArray(); (precessorObject["sides"] as JArray).Add("client"); } if (precessorObject["sides"] != null) { Logger.LogInfo("Check Side"); string mainClass = ""; bool isClient = false; foreach (string side in precessorObject["sides"] as JArray) { if (side == "client") { isClient = true; } } if (isClient) { var javainstance = JavaInstance.CreateInstance(Java.JavaList[0]); var classpathArgs = new ClasspathArgument(); //Add MainJAR foreach (var library in libraries) { if (library.LibraryName.ToString() == precessorObject["jar"].ToString()) { Logger.LogInfo("Get MainClass"); ZipArchive libJAR = ZipFile.OpenRead((library.Downloads.First() as ArtifactLibrary).GetLocalAbsolutePath()); var manifest = libJAR.GetEntry("META-INF/MANIFEST.MF"); var stream = manifest.Open(); StreamReader reader = new StreamReader(stream); string manifestText = reader.ReadToEnd(); foreach (var manifestLine in manifestText.Split('\n')) { if (manifestLine.StartsWith("Main-Class:")) { string mainClassData = manifestLine.Substring("Main-Class:".Length, manifestLine.Length - "Main-Class:".Length - 1); mainClass = mainClassData.Replace("\n", ""); } } classpathArgs.AddClasspath((library.Downloads.First() as ArtifactLibrary).GetLocalAbsolutePath()); } } //Add ClassPaths foreach (string classpath in precessorObject["classpath"] as JArray) { Logger.LogInfo("Add ClassPath: " + classpath); classpathArgs.AddClasspath(new ArtifactLibrary() { LibraryName = LibraryName.Parse(classpath) }.GetLocalAbsolutePath()); } //Add ProcessorArgs javainstance.Arguments.AddArgument(classpathArgs); javainstance.Arguments.AddArgument(new StringArgument(mainClass)); foreach (string a in precessorObject["args"] as JArray) { string argument = a; List <string> replaces = new List <string>(); string replacingText = ""; bool needCollect = false; foreach (var character in argument) { if (character == '{') { needCollect = true; } else if (character == '}') { needCollect = false; replaces.Add(replacingText); replacingText = ""; } else if (needCollect) { replacingText += character; } } foreach (var replaceObject in replaces) { string replacedData = dataKeys[replaceObject]["client"].ToString(); if (replacedData.StartsWith("[") && replacedData.EndsWith("]")) { string libName = replacedData.Substring(1, replacedData.Length - 2); replacedData = "\"" + new ArtifactLibrary() { LibraryName = LibraryName.Parse(libName) }.GetLocalAbsolutePath() + "\""; } if (argument.StartsWith("/data/")) { argument = installerDirectoryPath + "-extract" + argument; } argument = argument.Replace("{" + replaceObject + "}", replacedData); } if (argument.StartsWith("[") && argument.EndsWith("]")) { string libname = argument.Substring(1, argument.Length - 2); argument = "\"" + new ArtifactLibrary() { LibraryName = LibraryName.Parse(libname) }.GetLocalAbsolutePath() + "\""; } if (argument.StartsWith("/data/")) { argument = installerDirectoryPath + "-extract" + argument; } javainstance.Arguments.AddArgument(new StringArgument(argument)); Logger.LogInfo("Add Argument: " + argument); } javainstance.Launch(); javainstance.JavaProcess.WaitForExit(); Logger.LogInfo("Processor Completed with ExitCode " + javainstance.JavaProcess.ExitCode.ToString()); if (javainstance.JavaProcess.ExitCode != 0) { throw new Exception("Run Processor Failed"); } } } } } //Inject Profile { Logger.LogInfo("Inject Forge Profile into Version Profile"); foreach (var jvmArg in injectData["arguments"]["jvm"] as JArray) { (GameProfile.JSON["arguments"]["jvm"] as JArray).Add(jvmArg); Logger.LogInfo("Inject JVM Argument:" + jvmArg + " Successfully"); } foreach (var gameArg in injectData["arguments"]["game"] as JArray) { (GameProfile.JSON["arguments"]["game"] as JArray).Add(gameArg); Logger.LogInfo("Inject Game Argument:" + gameArg + " Successfully"); } foreach (var libArg in injectData["libraries"] as JArray) { (GameProfile.JSON["libraries"] as JArray).Add(libArg); Logger.LogInfo("Inject Library:" + libArg + " Successfully"); } GameProfile.JSON["mainClass"] = injectData["mainClass"]; Logger.LogInfo("Inject MainClass:" + injectData["mainClass"] + " Successfully"); GameProfile.JSON["id"] = injectData["id"]; Logger.LogInfo("Inject GameID:" + injectData["id"] + " Successfully"); GameProfile.SaveToLocalPath(); Logger.LogInfo("Save Inject Profile Successfully"); Logger.LogInfo("Injected Profile!"); Logger.LogInfo("Installed Forge!"); } } break; } case 0: { //1.13-1.16.5 { Logger.LogInfo("Download Necessary Libraries"); VersionLibraries libraries = new VersionLibraries(); foreach (JObject libJSON in profile["libraries"] as JArray) { VersionLibrary library = VersionLibrary.FromJSON(libJSON, GameProfile); if (libJSON["downloads"]["artifact"]["url"].ToString() == "") { Logger.LogInfo("Extract Maven"); { var mavenEntry = installerJAR.GetEntry("maven/" + libJSON["downloads"]["artifact"]["path"].ToString()); Directory.CreateDirectory(Path.Combine(GameSettings.SelectedGameDirectory.FullName , "libraries" , Path.GetDirectoryName(libJSON["downloads"]["artifact"]["path"].ToString()))); mavenEntry.ExtractToFile(Path.Combine(GameSettings.SelectedGameDirectory.FullName , "libraries" , libJSON["downloads"]["artifact"]["path"].ToString())); } Logger.LogInfo("Extract Maven Successfully"); } else { libraries.Add(library); } } //Download JARs; { DownloadTask jarDownloadTask = new DownloadTask(libraries.GetNeedToInstallFiles()); var failures = jarDownloadTask.Download((float percent) => { dlevent(0.2f + (0.5f * percent)); }); if (failures.Count > 0) { foreach (var failure in failures) { Logger.LogError("Failed to Download File:" + failure.Value); } throw failures.First().Value; } } //Run Mappings { Logger.LogInfo("Start Mapping Process"); JObject dataKeys = profile["data"] as JObject; dataKeys["MINECRAFT_VERSION"] = new JObject(); dataKeys["INSTALLER"] = new JObject(); dataKeys["SIDE"] = new JObject(); dataKeys["MINECRAFT_JAR"] = new JObject(); dataKeys["ROOT"] = new JObject(); dataKeys["MINECRAFT_VERSION"]["client"] = GameProfile.VersionName; dataKeys["INSTALLER"]["client"] = installerFilePath; dataKeys["SIDE"]["client"] = "client"; dataKeys["MINECRAFT_JAR"]["client"] = GameProfile.JARPath; dataKeys["ROOT"]["client"] = GameSettings.SelectedGameDirectory.FullName; foreach (JObject precessorObject in profile["processors"]) { Logger.LogInfo("Run Processor " + precessorObject); if (precessorObject["sides"] == null) { precessorObject["sides"] = new JArray(); (precessorObject["sides"] as JArray).Add("client"); } if (precessorObject["sides"] != null) { Logger.LogInfo("Check Side"); string mainClass = ""; bool isClient = false; foreach (string side in precessorObject["sides"] as JArray) { if (side == "client") { isClient = true; } } if (isClient) { var javainstance = JavaInstance.CreateInstance(Java.JavaList[0]); var classpathArgs = new ClasspathArgument(); //Add MainJAR foreach (var library in libraries) { if (library.LibraryName.ToString() == precessorObject["jar"].ToString()) { Logger.LogInfo("Get MainClass"); ZipArchive libJAR = ZipFile.OpenRead((library.Downloads.First() as ArtifactLibrary).GetLocalAbsolutePath()); var manifest = libJAR.GetEntry("META-INF/MANIFEST.MF"); var stream = manifest.Open(); StreamReader reader = new StreamReader(stream); string manifestText = reader.ReadToEnd(); foreach (var manifestLine in manifestText.Split('\n')) { if (manifestLine.StartsWith("Main-Class:")) { string mainClassData = manifestLine.Substring("Main-Class:".Length, manifestLine.Length - "Main-Class:".Length - 1); mainClass = mainClassData.Replace("\n", ""); } } classpathArgs.AddClasspath((library.Downloads.First() as ArtifactLibrary).GetLocalAbsolutePath()); } } //Add ClassPaths foreach (string classpath in precessorObject["classpath"] as JArray) { Logger.LogInfo("Add ClassPath: " + classpath); classpathArgs.AddClasspath(new ArtifactLibrary() { LibraryName = LibraryName.Parse(classpath) }.GetLocalAbsolutePath()); } //Add ProcessorArgs javainstance.Arguments.AddArgument(classpathArgs); javainstance.Arguments.AddArgument(new StringArgument(mainClass)); foreach (string a in precessorObject["args"] as JArray) { string argument = a; List <string> replaces = new List <string>(); string replacingText = ""; bool needCollect = false; foreach (var character in argument) { if (character == '{') { needCollect = true; } else if (character == '}') { needCollect = false; replaces.Add(replacingText); replacingText = ""; } else if (needCollect) { replacingText += character; } } foreach (var replaceObject in replaces) { string replacedData = dataKeys[replaceObject]["client"].ToString(); if (replacedData.StartsWith("[") && replacedData.EndsWith("]")) { string libName = replacedData.Substring(1, replacedData.Length - 2); replacedData = "\"" + new ArtifactLibrary() { LibraryName = LibraryName.Parse(libName) }.GetLocalAbsolutePath() + "\""; } if (argument.StartsWith("/data/")) { argument = installerDirectoryPath + "-extract" + argument; } argument = argument.Replace("{" + replaceObject + "}", replacedData); } if (argument.StartsWith("[") && argument.EndsWith("]")) { string libname = argument.Substring(1, argument.Length - 2); argument = "\"" + new ArtifactLibrary() { LibraryName = LibraryName.Parse(libname) }.GetLocalAbsolutePath() + "\""; } if (argument.StartsWith("/data/")) { argument = installerDirectoryPath + "-extract" + argument; } javainstance.Arguments.AddArgument(new StringArgument(argument)); Logger.LogInfo("Add Argument: " + argument); } javainstance.Launch(); javainstance.JavaProcess.WaitForExit(); Logger.LogInfo("Processor Completed with ExitCode " + javainstance.JavaProcess.ExitCode.ToString()); if (javainstance.JavaProcess.ExitCode != 0) { throw new Exception("Run Processor Failed"); } } } } } //Inject Profile { Logger.LogInfo("Inject Forge Profile into Version Profile"); foreach (var jvmArg in injectData["arguments"]["jvm"] as JArray) { (GameProfile.JSON["arguments"]["jvm"] as JArray).Add(jvmArg); Logger.LogInfo("Inject JVM Argument:" + jvmArg + " Successfully"); } foreach (var gameArg in injectData["arguments"]["game"] as JArray) { (GameProfile.JSON["arguments"]["game"] as JArray).Add(gameArg); Logger.LogInfo("Inject Game Argument:" + gameArg + " Successfully"); } foreach (var libArg in injectData["libraries"] as JArray) { (GameProfile.JSON["libraries"] as JArray).Add(libArg); Logger.LogInfo("Inject Library:" + libArg + " Successfully"); } GameProfile.JSON["mainClass"] = injectData["mainClass"]; Logger.LogInfo("Inject MainClass:" + injectData["mainClass"] + " Successfully"); GameProfile.JSON["id"] = injectData["id"]; Logger.LogInfo("Inject GameID:" + injectData["id"] + " Successfully"); GameProfile.SaveToLocalPath(); Logger.LogInfo("Save Inject Profile Successfully"); Logger.LogInfo("Injected Profile!"); Logger.LogInfo("Installed Forge!"); } } break; } } } else { //<=1.12.2 Version } } }