minecraft吧 关注:2,568,787贴子:32,084,099

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

只看楼主收藏回复

卧槽这个略屌


IP属地:日本223楼2016-07-05 21:45
回复
    233.我来了


    IP属地:河南来自Android客户端224楼2016-07-05 21:47
    收起回复
      2026-01-14 08:20:10
      广告
      不感兴趣
      开通SVIP免广告
      请您再看一下1.7.2Forge版的json数据,您可以发现,这其中的某些库提供了url。这些url不是可以直接下载的,它们是父下载地址,相当于https://libraries.minecraft.net/,我们需要自行加上库路径。


      225楼2016-07-06 16:57
      回复
        不过,光是加上路径是不行的。forge主启动库的文件名没有-universal结尾,但下载地址中需要这个后缀。


        来自Android客户端226楼2016-07-06 18:08
        回复
          至于什么liteloader的,以后再说。


          来自Android客户端227楼2016-07-07 08:06
          回复

            lz能不能帮我做一下?我刚刚按照你的做了两小时,还是没做出来,报了一堆错(启动后)


            IP属地:北京228楼2016-07-07 17:08
            收起回复
              using System;
              using System.Collections.Generic;
              using System.ComponentModel;
              using System.Data;
              using System.Drawing;
              using System.Text;
              using System.Windows.Forms;
              using System.Diagnostics;//貌似必须这样才可以有Process
              using System.Runtime.InteropServices;//加窗口阴影要用的
              using System.IO;//启动器需要的
              using JuicyLauncher;
              using Microsoft.Win32;
              namespace Minecraft_Code_Assistant
              {
              public partial class Form_QD : Form
              {
              //以下是窗口阴影
              private const int CS_DropSHADOW = 0x20000;
              private const int GCL_STYLE = (-26);
              [DllImport("user32.dll", CharSet = CharSet.Auto)]
              public static extern int SetClassLong(IntPtr hwnd, int nIndex, int dwNewLong);
              [DllImport("user32.dll", CharSet = CharSet.Auto)]
              public static extern int GetClassLong(IntPtr hwnd, int nIndex);
              //以上是窗口阴影
              public Form_QD()
              {
              InitializeComponent();
              // DBB();
              }
              public void DBB()
              {
              try
              {
              //读取版本
              listBox1.Items.Clear();
              String[] vers = Directory.GetDirectories(Application.StartupPath + "\\.minecraft\\versions");
              foreach (String item0 in vers)
              {
              listBox1.Items.Add(item0.Replace(Application.StartupPath + "\\.minecraft\\versions\\", ""));
              }
              }
              catch (Exception)
              {
              throw;
              }
              }
              //以下是窗口移动
              private Point offset;
              private void Form_QD_MouseDown(object sender, MouseEventArgs e)
              {
              if (MouseButtons.Left != e.Button) return;
              Point cur = this.PointToScreen(e.Location);
              offset = new Point(cur.X - this.Left, cur.Y - this.Top);
              }
              private void Form_QD_MouseMove(object sender, MouseEventArgs e)
              {
              if (MouseButtons.Left != e.Button) return;
              Point cur = MousePosition;
              this.Location = new Point(cur.X - offset.X, cur.Y - offset.Y);
              }
              //以上是窗口移动
              public void Form_yy()
              {
              SetClassLong(this.Handle, GCL_STYLE, GetClassLong(this.Handle, GCL_STYLE) | CS_DropSHADOW);//实现窗口阴影
              }
              private void Form_QD_Load(object sender, EventArgs e)
              {
              // XPZ();
              TuPian_TouMing();
              Form_yy();
              //DPZ();
              // DPZ_1();;
              }
              public void XPZ()
              {
              //写配置
              String[] Ct = new String[] { mm.Text, @"F:\java\bin\java.exe", un.Text };//拼接配置文件内容
              File.WriteAllLines(Application.StartupPath + "\\JLConfig.JLConfig", Ct);//写入
              }
              public void DPZ_1()
              {
              //读取配置
              if (!File.Exists(Application.StartupPath + "\\JLConfig.JLConfig"))
              {
              String[] js = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\JavaSoft\Java Runtime Environment").GetSubKeyNames();//读取jre路径。
              StreamWriter sw = File.CreateText(Application.StartupPath + "\\JLConfig.JLConfig");
              sw.Write("1024\n" + Registry.LocalMachine.OpenSubKey(@"SOFTWARE\JavaSoft\Java Runtime Environment\" + js[0]).GetValue("JavaHome") + "\\bin\\javaw.exe\nPlayer\n");
              sw.Close();
              }
              string[] Ct = new string[] { };
              Ct = System.IO.File.ReadAllLines(Application.StartupPath + "\\JLConfig.JLConfig");
              mm.Text = Ct[0];
              jp.Text = Ct[1];
              un.Text = Ct[2];
              }
              public void DPZ()
              {
              //读取配置
              if (!File.Exists(Application.StartupPath + "\\JLConfig.JLConfig"))
              {
              File.Create(Application.StartupPath + "\\JLConfig.JLConfig");
              return;
              }
              string[] Ct = new string[] { };
              Ct = System.IO.File.ReadAllLines(Application.StartupPath + "\\JLConfig.JLConfig");
              mm.Text = Ct[0];
              jp.Text = Ct[1];
              un.Text = Ct[2];
              }
              public void TuPian_TouMing()
              {
              label1.BackColor = Color.Transparent;//让这个标签的背景透明
              label2.BackColor = Color.Transparent;
              label3.BackColor = Color.Transparent;
              label4.BackColor = Color.Transparent;
              label5.BackColor = Color.Transparent;
              label6.BackColor = Color.Transparent;
              label7.BackColor = Color.Transparent;
              }
              private void label5_Click(object sender, EventArgs e)
              {
              this.Close();//关闭当前窗口
              Form_zhu w_1;
              w_1 = new Form_zhu();
              w_1.Show();
              }
              private void label6_Click(object sender, EventArgs e)
              {
              //写配置
              String[] Ct = new String[] { mm.Text, jp.Text, un.Text };//拼接配置文件内容
              File.WriteAllLines(Application.StartupPath + "\\JLConfig.JLConfig", Ct);//写入
              }
              private void label1_Click(object sender, EventArgs e)
              {
              //启动
              String[] TCfg = new String[3];
              TCfg = System.IO.File.ReadAllLines(Application.StartupPath + "\\JLConfig.JLConfig");//读取配置
              Launcher launcher = new Launcher();
              if (listBox1.SelectedIndex == -1)
              {
              listBox1.SelectedIndex = 0;
              }
              launcher.Launch(TCfg[0], TCfg[1], TCfg[2], listBox1.SelectedItem.ToString());
              }
              private void label7_Click(object sender, EventArgs e)
              {
              //浏览部分
              OpenFileDialog ofd = new OpenFileDialog();//初始化打开文件对话框
              ofd.Title = "请选择您的javaw.exe所在路径";//设置标题
              ofd.RestoreDirectory = true;//不还原路径
              ofd.Multiselect = false;//不允许选择多个
              ofd.Filter = "应用程序(*.exe)|*.exe";//设置格式过滤
              if (ofd.ShowDialog() == DialogResult.OK)
              {//显示对话框
              jp.Text = ofd.FileName;//返回路径名
              }
              }
              }
              }
              这是我的源码,哪里错了?


              IP属地:北京229楼2016-07-07 17:09
              收起回复
                根据楼主的测试,Forge官网有一些库不提供下载,但仍然可以启动。


                来自Android客户端230楼2016-07-08 08:01
                回复
                  2026-01-14 08:14:10
                  广告
                  不感兴趣
                  开通SVIP免广告
                  所以我们需要把下载失败的库删除,以防载入无效的空库。


                  来自Android客户端231楼2016-07-08 08:02
                  回复


                    来自Android客户端232楼2016-07-08 08:21
                    收起回复
                      一堆


                      IP属地:北京233楼2016-07-08 13:38
                      收起回复
                        所以,我们就可以开始写代码了。


                        234楼2016-07-08 15:21
                        回复
                          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 LaunchReturn//返回的公共类,暂时还没用
                          {
                          public String rtv;//子值,返回字符串
                          public List<string> DUList = new List<string>();//子值,返回下载列表
                          }
                          class Launcher
                          {
                          private 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 LaunchReturn Launch(string MaxMem, string JavaPath, string UserName, string VerName, int returnvalue = 0, bool dc = false)
                          {
                          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)//如果是干扰的
                          {
                          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//如果不存在
                          {
                          if (libs[i].IndexOf("url") == -1)//判断是否存在url
                          {//不存在


                          235楼2016-07-08 15:23
                          回复
                            URLList.Add("ht删tps://libraries.掉minecraft.中n文et" + tpath.Replace(Application.StartupPath + "\\.minecraft\\libraries", "").Replace("\\", "/") + ":::" + tpath);//加入到下载列表
                            }
                            else//存在
                            {
                            tmp = libs[i].IndexOf("url") + "url".Length + 3;//json读取部分,同上
                            String du = libs[i].Substring(tmp, libs[i].IndexOf("\"", tmp) - tmp);//读取到url
                            if (du == "ht删tp://fi掉les.中minecraftforge.n文et/maven/")//如果是forge的
                            {
                            String tmpp = tpath;//声明临时url
                            if (tpath.IndexOf(@"net\minecraftforge\forge\") != -1)//如果是forge主文件
                            {
                            tmpp = tpath.Replace(".jar", "") + "-universal.jar";//加上universal后缀
                            }
                            URLList.Add(du.Substring(0, du.Length - 1) + tmpp.Replace(Application.StartupPath + "\\.minecraft\\libraries", "").Replace("\\", "/") + ":::" + tpath);//加入到下载列表
                            }
                            else//不是Forge的
                            {
                            URLList.Add("ht删tps://libraries掉.中minecraft.n文et" + tpath.Replace(Application.StartupPath + "\\.minecraft\\libraries", "").Replace("\\", "/") + ":::" + tpath);//加入到下载列表
                            }
                            }
                            }


                            238楼2016-07-08 15:26
                            回复
                              2026-01-14 08:08:10
                              广告
                              不感兴趣
                              开通SVIP免广告
                              if (libs[i].IndexOf("extract") != -1)//如果要提取natives
                              {
                              decompress(tpath, natives);//提取
                              }
                              }
                              String oldVerName = VerName;//转储版本号
                              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).rtv;//读入父json数据生成的库,解压父json数据要求的natives
                              tmp = rtxt.IndexOf("jar\":") + "jar".Length + 3;//json读取部分,同上
                              VerName = newVerName;//转储
                              natives = Application.StartupPath + "\\.minecraft\\versions\\" + newVerName + "\\" + newVerName + "-natives";//重新指定natives文件夹
                              }
                              if (returnvalue == 1)//如果要返回库路径
                              {
                              LaunchReturn lr = new LaunchReturn();
                              lr.rtv = libp;
                              return lr;//返回并退出方法
                              }
                              if (URLList.Count != 0 && dc == false)//如果下载列表不为空且尚未执行下载
                              {
                              ShowDownload sd = new ShowDownload();//引用下载进度窗体到实例
                              sd.Show();//显示该窗体
                              sd.DownloadBL(URLList, MaxMem + ",%,%," + JavaPath + ",%,%," + UserName + ",%,%," + oldVerName);//调用窗体中的下载方法并传参,但使用的是原版本号
                              return null;//返回空值
                              }
                              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)//如果要返回完整的启动命令
                              {
                              LaunchReturn lr = new LaunchReturn();
                              lr.rtv = RunComm;
                              return lr;//返回并退出
                              }
                              Process mjp = new Process();//运行部分
                              ProcessStartInfo psi = new ProcessStartInfo(JavaPath, RunComm);//运行部分
                              psi.UseShellExecute = false;//运行部分
                              mjp.StartInfo = psi;//运行部分
                              mjp.Start();//运行部分
                              Application.Exit();//退出
                              return null;//最终返回空值
                              }
                              (此处省略decompress方法)
                              }
                              }


                              239楼2016-07-08 15:28
                              回复