minecraft吧 关注:2,568,809贴子:32,084,370

回复:我的世界启动器制作教程

只看楼主收藏回复

当然喽,显示下载进度还可以鼓励用户耐心地等下去。


来自Android客户端193楼2016-07-04 22:12
回复
    首先,我们添加一个窗口,命名为ShowDownload。


    194楼2016-07-05 15:47
    回复
      2026-01-14 15:02:09
      广告
      不感兴趣
      开通SVIP免广告


      195楼2016-07-05 16:14
      回复


        197楼2016-07-05 16:14
        回复
          然后我们修改一下其他的属性。


          198楼2016-07-05 16:15
          回复
            布局一下窗体,拖入ListBox、Label、Button、ProgressBar。


            201楼2016-07-05 16:19
            回复
              看看


              IP属地:广东来自Android客户端202楼2016-07-05 16:19
              收起回复
                设置按钮的文本和标签的属性。


                205楼2016-07-05 16:22
                回复
                  2026-01-14 14:56:09
                  广告
                  不感兴趣
                  开通SVIP免广告
                  最后我们写代码。咱们先重新写一下Launcher.cs的:
                  using System;
                  using System.Text;
                  using System.IO;
                  using System.Windows.Forms;
                  using System.Diagnostics;
                  using System.Reflection;
                  using System.Collections.Generic;
                  namespace JuicyLauncher
                  {
                  class Launcher
                  {
                  List<string> URLList=new List<string>();//声明总列表
                  /// <summary>
                  /// 启动主方法
                  /// </summary>
                  /// <param name="MaxMem">最大内存</param>
                  /// <param name="JavaPath">Javaw.exe路径</param>
                  /// <param name="UserName">用户名</param>
                  /// <param name="VerName">版本名</param>
                  /// <param name="returnvalue">返回值的指定。0为不返回,直接执行;1为返回库的完整字符串;2为返回完整的启动命令。默认为0。</param>
                  /// <param name="dc">指示是否下载文件。</param>
                  public string Launch(string MaxMem,string JavaPath,string UserName,string VerName,int returnvalue=0,bool dc=false)
                  {


                  208楼2016-07-05 16:25
                  收起回复
                    string rtxt = "";//声明
                    int tmp = 0;//声明
                    rtxt = File.ReadAllText(Application.StartupPath + "\\.minecraft\\versions\\" + VerName + "\\" + VerName + ".json").Replace(" ", "").Replace("\n","");//读取内容
                    tmp = rtxt.IndexOf("mainClass") + "mainClass".Length + 3;//取名称起始位置并赋值到tmp
                    String mainClass = rtxt.Substring(tmp, rtxt.IndexOf("\"", tmp) - tmp);//截取值
                    tmp = rtxt.IndexOf("minecraftArguments") + "minecraftArguments".Length + 3;//json读取部分,同上
                    String minecraftArguments = rtxt.Substring(tmp, rtxt.IndexOf("\"", tmp) - tmp).Replace("${", " ${").Replace("}", "} ").Replace("cpw", " cpw");//json读取部分,同上
                    tmp = rtxt.IndexOf("libraries") + "libraries".Length + 3;//json读取部分,同上
                    String libraries = rtxt.Substring(tmp + 1, rtxt.LastIndexOf("]") - tmp);//json读取部分,同上
                    String natives = Application.StartupPath + "\\.minecraft\\versions\\" + VerName + "\\" + VerName + "-natives";//设置natives路径
                    if (!Directory.Exists(natives))//目录不存在
                    {
                    Directory.CreateDirectory(natives);//创建
                    }
                    String[] libs = libraries.Replace("${arch}","32").Replace("},{", "^").Split("^".ToCharArray());//将},{替换为^然后以^进行分割,顺便决定32位系统
                    String libp="";//声明libp
                    for (int i = 0; i < libs.Length; i++)//为数组内容循环,也可以考虑foreach
                    {
                    if (libs[i].IndexOf("name") == -1)//如果没有name值
                    {
                    continue;//跳过
                    }
                    String tml = libs[i];//声明临时字符串变量tml
                    if (tml.IndexOf("{") != -1)//如果含有子json对象,则去掉子项
                    {
                    do//循环
                    {
                    try//捕获错误
                    {
                    tml = tml.Replace(tml.Substring(tml.LastIndexOf("{") - 1, tml.IndexOf("}", tml.LastIndexOf("{")) - tml.LastIndexOf("{") + 1), "");//去掉子项
                    }
                    catch (ArgumentOutOfRangeException ex)//如果是干扰的
                    {
                    tml = tml + "," + libs[i + 1];//追加
                    tml = tml.Replace(tml.Substring(tml.LastIndexOf("{") - 1, tml.IndexOf("}", tml.LastIndexOf("{")) - tml.LastIndexOf("{") + 1), "");//再去掉子项
                    }
                    } while (tml.IndexOf("{") != -1);//有子项则仍然循环
                    tml = tml.Replace("{", "").Replace("}", "");//去掉干扰的{}
                    }
                    tmp = tml.IndexOf("name") + "name".Length + 3;//json读取部分,同上
                    String libn = tml.Substring(tmp, tml.IndexOf("\"", tmp) - tmp);//json读取部分,同上
                    if (libn.IndexOf(":") == -1)//如果name的值不合法
                    {
                    continue;//跳过
                    }
                    String[] tlib = new String[] { libn.Substring(0, libn.IndexOf(":")).Replace(":", ""), libn.Substring(libn.IndexOf(":") + 1, libn.IndexOf(":", libn.IndexOf(":") + 1) - libn.IndexOf(":")).Replace(":", ""), libn.Substring(libn.IndexOf(":", libn.IndexOf(":") +1)).Replace(":", "") };//将读取的name值转成路径
                    String tpath = Application.StartupPath + "\\.minecraft\\libraries\\" + tlib[0].Replace(".", "\\") + "\\" + tlib[1] + "\\" + tlib[2] + "\\" + tlib[1] + "-" + tlib[2] + ".jar";//同上
                    if (libs[i].IndexOf("natives")!= -1 && libs[i].IndexOf("windows") != -1)//如果有natives指定
                    {
                    tmp = libs[i].IndexOf("windows") + "windows".Length + 3;//json读取部分,同上
                    tpath = tpath.Replace(".jar", "") + "-" + libs[i].Substring(tmp, libs[i].IndexOf("\"", tmp) - tmp) + ".jar";//json读取部分,同上
                    }
                    if (File.Exists(tpath))//检查文件是否存在
                    {
                    libp = libp + tpath + ";";//存在就加录
                    }
                    else//如果不存在
                    {
                    URLList.Add("https://libraries.minecraft.net" + tpath.Replace(Application.StartupPath + "\\.minecraft\\libraries", "").Replace("\\", "/") + ":::" + tpath);//加入到下载列表
                    }
                    if (libs[i].IndexOf("extract") != -1)//如果要提取natives
                    {
                    decompress(tpath, natives);//提取
                    }
                    }
                    if (returnvalue == 1)//如果要返回库路径
                    {
                    return libp;//返回并退出方法
                    }
                    if (URLList.Count != 0 && dc==false)//如果下载列表不为空且尚未执行下载
                    {
                    ShowDownload sd = new ShowDownload();//引用下载进度窗体到实例
                    sd.Show();//显示该窗体
                    sd.DownloadBL(URLList,MaxMem + ",%,%," + JavaPath + ",%,%," + UserName + ",%,%," + VerName);//调用窗体中的下载方法并传参
                    return null;//退出方法
                    }
                    if (rtxt.IndexOf("inheritsFrom\":") != -1)//如果是继承的json数据
                    {
                    tmp = rtxt.IndexOf("inheritsFrom\":") + "inheritsFrom".Length + 3;//json读取部分,同上
                    String newVerName = rtxt.Substring(tmp, rtxt.IndexOf("\"", tmp) - tmp);//json读取部分,同上
                    libp += Launch("", "", "", newVerName, 1);//读入父json数据生成的库,解压父json数据要求的natives
                    tmp = rtxt.IndexOf("jar\":") + "jar".Length + 3;//json读取部分,同上
                    VerName = rtxt.Substring(tmp, rtxt.IndexOf("\"", tmp) - tmp);//json读取部分,同上
                    natives = Application.StartupPath + "\\.minecraft\\versions\\" + newVerName + "\\" + newVerName + "-natives";//重新指定natives文件夹
                    }
                    libp = libp + Application.StartupPath + "\\.minecraft\\versions\\" + VerName + "\\" + VerName + ".jar";//整合字符串
                    String assets = Application.StartupPath + "\\.minecraft\\assets";//设置资源文件夹路径
                    tmp = rtxt.IndexOf("assets\":") + "assets".Length + 3;//json读取部分,同上
                    String assetIndex = rtxt.Substring(tmp, rtxt.IndexOf("\"", tmp) - tmp);//json读取部分,同上
                    if (!File.Exists(assets + "\\indexes\\" + assetIndex + ".json"))//如果不存在
                    {
                    if (File.Exists(assets + "\\virtual\\legacy\\indexes\\" + assetIndex + ".json"))//如果virtual目录有效
                    {
                    assets = assets + "\\virtual\\legacy";//修改资源文件夹
                    }
                    }
                    String gameDir=Application.StartupPath + "\\.minecraft";//设置游戏路径
                    if (Application.StartupPath.IndexOf(" ") != -1)//如果路径有空格
                    {
                    natives = "\"" + natives + "\"";//加上引号
                    libp = "\"" + libp + "\"";//加上引号
                    assets = "\"" + assets + "\"";//加上引号
                    gameDir = "\"" + gameDir + "\"";//加上引号
                    }
                    minecraftArguments = minecraftArguments.Replace("${auth_player_name}", UserName).Replace("${version_name}", "JuicyLauncher_1.0").Replace("${game_directory}", gameDir).Replace("${game_assets}", assets).Replace("${assets_root}",assets).Replace("${assets_index_name}",assetIndex).Replace("${user_properties}","{}").Replace("${user_type}","Legacy");//读取额外参数
                    //启动参数拼接
                    String RunComm = "";//声明RunComm
                    RunComm = "-Xmx" + MaxMem + "m -Djava.library.path=" + natives + " -Dfml.ignoreInvalidMinecraftCertificates=true -Dfml.ignorePatchDiscrepancies=true -cp " + libp + " " + mainClass + " " + minecraftArguments;//拼接参数
                    if (returnvalue == 2)//如果要返回完整的启动命令
                    {
                    return RunComm;//返回并退出
                    }


                    209楼2016-07-05 16:25
                    回复
                      Process mjp=new Process();//运行部分
                      ProcessStartInfo psi = new ProcessStartInfo(JavaPath, RunComm);//运行部分
                      psi.UseShellExecute = false;//运行部分
                      mjp.StartInfo = psi;//运行部分
                      mjp.Start();//运行部分
                      Application.Exit();//退出
                      return null;//最终返回空值
                      }


                      215楼2016-07-05 16:35
                      回复
                        public void decompress(String inputFileName, String outputDirName)
                        {
                        Assembly assembly = Assembly.GetExecutingAssembly();//释放7z.exe和7z.dll部分
                        Stream stream = assembly.GetManifestResourceStream("JuicyLauncher.7z.exe");//释放7z.exe和7z.dll部分
                        byte[] bytes = new byte[stream.Length];//释放7z.exe和7z.dll部分
                        stream.Read(bytes, 0, int.Parse(stream.Length.ToString()));//释放7z.exe和7z.dll部分
                        File.WriteAllBytes(Application.StartupPath + "\\7z.exe", bytes);//释放7z.exe和7z.dll部分
                        assembly = Assembly.GetExecutingAssembly();//释放7z.exe和7z.dll部分
                        stream = assembly.GetManifestResourceStream("JuicyLauncher.7z.dll");//释放7z.exe和7z.dll部分
                        bytes = new byte[stream.Length];//释放7z.exe和7z.dll部分
                        stream.Read(bytes, 0, int.Parse(stream.Length.ToString()));//释放7z.exe和7z.dll部分
                        File.WriteAllBytes(Application.StartupPath + "\\7z.dll", bytes); //释放7z.exe和7z.dll部分
                        Process sz=new Process();//运行7z.exe解压部分
                        ProcessStartInfo psi = new ProcessStartInfo(Application.StartupPath + "\\7z.exe", "x \"" + inputFileName + "\" -o\"" + outputDirName + "\" -y");//运行7z.exe解压部分
                        psi.UseShellExecute = false;//运行7z.exe解压部分
                        psi.WindowStyle = ProcessWindowStyle.Hidden;//设置不显示
                        psi.CreateNoWindow = true;//设置不显示
                        sz.StartInfo = psi;//运行7z.exe解压部分
                        sz.Start();//运行7z.exe解压部分
                        sz.WaitForExit();//等待退出
                        File.Delete(Application.StartupPath + "\\7z.exe");//删除7z.exe
                        File.Delete(Application.StartupPath + "\\7z.dll");//删除7z.dll
                        }
                        }
                        }


                        216楼2016-07-05 16:36
                        回复
                          然后转到ShowDownload窗体,双击“取消“按钮,把整个文件中的代码删掉,换成下面的内容:


                          217楼2016-07-05 16:42
                          收起回复
                            这是效果图。


                            221楼2016-07-05 16:46
                            回复
                              2026-01-14 14:50:09
                              广告
                              不感兴趣
                              开通SVIP免广告
                              进阶五:Forge版库的补全


                              来自Android客户端222楼2016-07-05 19:22
                              回复