diff --git a/MFML/Download/OptifineDownloader.cs b/MFML/Download/OptifineDownloader.cs index 344c763..75dd8f3 100644 --- a/MFML/Download/OptifineDownloader.cs +++ b/MFML/Download/OptifineDownloader.cs @@ -4,10 +4,13 @@ using MFML.Utils; using System; using System.Collections.Generic; +using System.Diagnostics; +using System.IO; using System.Linq; using System.Net; using System.Text; using System.Text.RegularExpressions; +using System.Threading; using System.Threading.Tasks; using System.Web.Script.Serialization; @@ -17,11 +20,13 @@ public class OptifineDownloader : Downloader { private class OptifineDownloadVersionInfo { - public string Name { get; set; } + public string MCVersion { get; set; } + public string Type { get; set; } + public string Patch { get; set; } public string Url { get; set; } public override string ToString() { - return string.Format("版本:{0}", Name); + return string.Format("Optifine {0} {1} {2}", MCVersion, Type.Replace('_', ' '), Patch); } } @@ -41,7 +46,53 @@ public OptifineDownloader(MinecraftVersion Version) public override void Download() { - throw new NotImplementedException(); + ServicePointManager.DefaultConnectionLimit = 1000; + Version.InstallLaunchWrapper(); + var item = downloadVersionInfos.Find((i) => i.ToString() == this.SelectedItem); + Debug.Assert(item != null); + var url = item.Url; + var versionText = string.Format("{0}_{1}_{2}", item.MCVersion, item.Type, item.Patch); + var jarname = "Optifine-" + versionText + ".jar"; + var dirpath = "optifine\\Optifine\\" + versionText + "\\"; + var downloadDirPath = LauncherMain.Instance.Settings.MinecraftFolderName + "libraries\\" + dirpath; + if (!Directory.Exists(downloadDirPath)) + { + Directory.CreateDirectory(downloadDirPath); + } + var path = dirpath + jarname; + var downloadPath = downloadDirPath + jarname; + var manifest = MinecraftManifest.AnalyzeFromVersion(this.Version); + using (var wc = new WebClient()) + { + OnProgressChanged("开始下载。。", 0); + wc.DownloadProgressChanged += + (sender, args) => OnProgressChanged(null, (int)(args.ProgressPercentage * 0.8)); + Task downloadTask = wc.DownloadFileTaskAsync(url, downloadPath); + while (!downloadTask.IsCompleted) + { + Thread.Sleep(500); + } + } + OnProgressChanged("正在添加依赖项。。。", 80); + var library = new MinecraftLibrary(); + library.name = dirpath.Substring(0, dirpath.Length - 1).Replace('\\', ':'); + library.downloads = new LibraryDownloads(); + library.downloads.artifact = new DownloadInfo(); + library.downloads.artifact.path = path.Replace('\\', '/'); + library.downloads.artifact.url = url; + manifest.libraries.Add(library); + if (manifest.minecraftArguments == null) + { + manifest.arguments.game.Add("--tweakClass"); + manifest.arguments.game.Add("optifine.OptiFineTweaker"); + } + else + { + manifest.minecraftArguments += " --tweakClass optifine.OptiFineTweaker"; + } + + OnProgressChanged(null, 100); + Version.SaveManifest(manifest); } public override List GetAllItemsToDownload() @@ -63,7 +114,9 @@ public override List GetAllItemsToDownload() foreach (var item in itemList) { var listItem = new OptifineDownloadVersionInfo(); - listItem.Name = item.type; + listItem.MCVersion = item.mcversion; + listItem.Type = item.type; + listItem.Patch = item.patch; listItem.Url = string.Format( "https://bmclapi2.bangbang93.com/optifine/{0}/{1}/{2}", item.mcversion, @@ -108,7 +161,10 @@ public override List GetAllItemsToDownload() uri = uri.Substring(0, uri.Length - 1); var url = "https://optifine.net/" + uri; var info = new OptifineDownloadVersionInfo(); - info.Name = name; + var args = name.Split(' '); + var mcversion = args[1]; + var type = args[2] + "_" + args[3]; + var patch = args[4]; info.Url = url; downloadVersionInfos.Add(info); list.Add(info.ToString()); diff --git a/MFML/Game/MinecraftVersion.cs b/MFML/Game/MinecraftVersion.cs index 2b9970c..a43c5df 100644 --- a/MFML/Game/MinecraftVersion.cs +++ b/MFML/Game/MinecraftVersion.cs @@ -1,8 +1,7 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using MFML.Core; +using MFML.Core; +using System.IO; +using System.Net; +using System.Web.Script.Serialization; namespace MFML.Game { @@ -31,6 +30,15 @@ public string GameNativesPath get { return NativesPath.Substring(NativesPath.IndexOf('\\') + 1); } } + public bool LaunchWithLaunchWrapper + { + get + { + var manifest = MinecraftManifest.AnalyzeFromVersion(this); + return manifest.mainClass == "net.minecraft.launchwrapper.Launch"; + } + } + public MinecraftVersion(string VersionName) { this.VersionName = VersionName; @@ -38,6 +46,53 @@ public MinecraftVersion(string VersionName) VersionDirectory = mcdir + "versions\\" + VersionName + "\\"; } + public void SaveManifest(MinecraftManifest manifest) + { + var seri = new JavaScriptSerializer(); + var text = seri.Serialize(manifest); + var sw = new StreamWriter(new FileStream(VersionManifestPath, FileMode.OpenOrCreate)); + sw.Write(text); + sw.Close(); + } + + public void InstallLaunchWrapper() + { + const string LAUNCHWRAPPER_VERSION = "1.12"; + if (!this.LaunchWithLaunchWrapper) + { + var mcdir = LauncherMain.Instance.Settings.MinecraftFolderName; + var libraryloc = mcdir + string.Format( + "libraries\\net\\minecraft\\launchwrapper\\{0}\\", LAUNCHWRAPPER_VERSION); + if (!Directory.Exists(libraryloc)) + { + Directory.CreateDirectory(libraryloc); + } + libraryloc += string.Format("launchwrapper-{0}.jar", LAUNCHWRAPPER_VERSION); + if (!File.Exists(libraryloc)) + { + using (var wc = new WebClient()) + { + string url = string.Format( + "https://libraries.minecraft.net/net/minecraft/launchwrapper/{0}/launchwrapper-{0}.jar", + LAUNCHWRAPPER_VERSION + ); + if (LauncherMain.Instance.Settings.UseBMCL) + { + url = url.Replace("libraries.minecraft.net", + "bmclapi2.bangbang93.com/libraries"); + } + wc.DownloadFile(url, libraryloc); + } + } + var manifest = MinecraftManifest.AnalyzeFromVersion(this); + manifest.mainClass = "net.minecraft.launchwrapper.Launch"; + var wrapperLibrary = new MinecraftLibrary(); + wrapperLibrary.name = string.Format("net.minecraft:launchwrapper:{0}", LAUNCHWRAPPER_VERSION); + manifest.libraries.Add(wrapperLibrary); + this.SaveManifest(manifest); + } + } + public override string ToString() { return VersionName; diff --git a/MFML/Launch/MinecraftLaunchMaker.cs b/MFML/Launch/MinecraftLaunchMaker.cs index c96aab2..f2581bf 100644 --- a/MFML/Launch/MinecraftLaunchMaker.cs +++ b/MFML/Launch/MinecraftLaunchMaker.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; +using System.Text; using System.Threading.Tasks; using System.Web.Script.Serialization; using System.Windows.Forms; @@ -224,7 +225,7 @@ private string GenerateClassPath() { cd += "\\"; } - var pathes = new List(); + var pathes = new StringBuilder(); var libraries = manifest.libraries; foreach (var lib in libraries) { @@ -243,16 +244,23 @@ private string GenerateClassPath() } if (NeedThisLib) { - if (lib.downloads.artifact != null) + if (lib != null) { - var artifact = lib.downloads.artifact; - var path = cd + LibRoot + artifact.path.Replace('/', '\\'); - pathes.Add(path); + var names = lib.name.Split(':'); + var ids = names.Skip(1); + var packages = names[0].Split('.'); + List dirs = new List(); + dirs.AddRange(packages); + dirs.AddRange(ids); + dirs.Add(string.Join("-", ids) + ".jar"); + var path = cd + LibRoot + string.Join("\\", dirs); + pathes.Append(path); + pathes.Append(';'); } } } - pathes.Add(cd + Version.JarPath); - return string.Join(";", pathes); + pathes.Append(cd + Version.JarPath); + return pathes.ToString(); } private string ProcessArgument(string str)