Eric_Stevens
本帖最后由 Eric_Stevens 于 2020-2-21 17:10 编辑

     
各位菊苣们好!我是开源启动核心ProjBobcat的开发者之一。正如标题所言,这是一份完整而深入浅出的ProjBobcat开发文档。希望这能对你建立起对ProjBobcat启动核心的了解有所帮助。
本教程持续在此贴更新,欢迎各位在回复中提出问题。
值得注意的是,ProjBobcat的接口适用于.Net Framework下的所有语言(Core在开发计划中),但为方便起见,本教程的所有例子采用C#编写。
我们欢迎第三方教程,如果质量较高会将其翻译并且链接至项目主页。

本教程采用CC-BY-NC-SA协议发布,继续阅读即表明您自愿遵守该协议。

2020/2/21更新
ProjBobcat现已支持完整的游戏资源补全功能和Forge安装模型支持,在近日会补充相关内容。

这一个视频中对CMFL与其他启动器下载游戏和启动游戏速度的横向比较可以清晰地反映ProjBobcat的优势所在:https://www.bilibili.com/video/av89055581

      为什么采用ProjBobcat?
  • ProjBobcat采用MIT协议发行。这意味着您可以任意以商业和非商业目的使用和编辑ProjBobcat的源代码,只要您保留我们的版权声明。由此,ProjBobcat的第三方修改的合法性就有了保证。(一些启动核心采用lgpl协议,在此协议下发行的程序包,如果您对其源代码有改动,则使用了您改动源代码的该程序包的程序集必须同样按照lgpl开源发布。)
  • ProjBobcat是一个年轻的项目。年轻意味着它还在活跃更新的状态中,每隔一段时间,开发团队都会给其加上新功能并且进行错误修复。
  • ProjBobcat是高度模块化的。这意味着启动过程中几乎所有的方法、数据模型等都是可以在没有workaround的情况下外置接入的,你甚至不需要编辑本项目的代码,就能实现无数种可能。
  • ProjBobcat是完整的。除了启动功能之外,ProjBobcat在最新的迭代中已经支持完整的游戏资源补全功能和Forge安装模型支持。
  • ProjBobcat是面向生产环境的。ProjBobcat是CMFL启动器的自研启动核心,并不是凭空开发和测试的,因此,ProjBobcat对生产环境的兼容性较强,部署能力也较强。
  • ProjBobcat的代码易于研究学习。ProjBobcat的体系结构非常清晰,而且我们正在以中英双语的形式完善整个项目代码的注释体系。
  • ProjBobcat有只橘猫,其他项目没有。

      联系方式
ProjBobcat在本版块的发布帖:https://www.mcbbs.net/thread-953949-1-1.html
ProjBobcat官方讨论组:677872263。
如果您要参与开发,欢迎加入:1040526762。

      安装
有3种主要方法安装ProjBobcat。
  • 直接clone我们的Github项目:https://github.com/Corona-Studio/ProjBobcat。希望您也能反手给咱一颗星。
  • 在Visual Studio项目的NuGet程序包管理器中搜索ProjBobcat,选择最新稳定版本安装即可,安装过程中可能会要求您同意MIT协议。
  • 直接在Visual Studio的程序包管理控制台输入:Install-Package ProjBobcat
  !   我的IDE环境的语言是英文,部分和IDE有关的操作的中文翻译难以查证,如果出现与您IDE中不同的操作指示,请在表意基本相同的情况下以您的IDE为准。
  !   如果在配置无误的情况下样例编译错误,请检查是否添加using引用。

      初级开发教程前言
初级开发教程主要涉及启动器的基本功能。对于ProjBobcat的外部模块接入等操作将在未来更新的高级教程补上。

      获取Java位置
  !   为了解决一些注册表读取的玄学问题,请进入项目选项(Properties…)->生成(Build),并取消勾选优先32位生成(Prefer 32-bit)。
所有方法
方法名称
代码形式
返回
获取Java路径
ProjBobcat.Class.Helper.SystemInfoHelper.FindJava();
一个表,包含系统中能搜寻到的所有Java路径,即IEnumerable枚举对象
例子
  1. public List<string> GetJavaList()
  2. {
  3.     return ProjBobcat.Class.Helper.SystemInfoHelper.FindJava().ToList();
  4. }
复制代码
对于Winform程序,可以直接将下拉菜单(ComboBox)的数据源映射到上述方法生成的List<string>中:

  1. var jList = GetJavaList();
  2. comboBox1.DataSource = jList; //假设WinForm程序中有一下拉菜单名为comboBox1

复制代码
练习
写一段控制台代码,输出系统中所有安装的Java路径。
答案
  1. var jl = ProjBobcat.Class.Helper.SystemInfoHelper.FindJava();
  2. foreach(var java in jl)
  3. {
  4.     Console.WriteLine(java);
  5. }
复制代码

      初始化启动核心
特殊类型
  !   为了初学者更容易理解本文档,文档前部的所有内容均不会包含抽象基类/接口(除非必要)。在后期的高级编程中,我们再讨论有关内容。
类型名称
代码形式
默认启动核心
ProjBobcat.DefaultGameCore
默认游戏扫描器
ProjBobcat.DefaultVersionLocator
默认launcher_profiles.json解释器
ProjBobcat.DefaultLauncherProfileParser
所有方法
方法名称
代码形式
返回
默认游戏扫描器构造函数
ProjBobcat.DefaultVersionLocator.DefaultVersionLocator(string rootPath, Guid clientToken)
构造函数
默认启动核心构造函数
ProjBobcat.DefaultGameCore.DefaultGameCore()
构造函数
默认launcher_profiles.json解释器
ProjBobcat.DefaultLauncherProfileParser.DefaultLauncherProfileParser (string rootPath, Guid clientToken)
构造函数
备注
DefaultGameCore可以看作外接程序对ProjBobcat的全套启动系统的一个入口类,接下来教程几乎所有的操作都基于DefaultGameCore,所以不管是定义还是操作的执行都优先从其开始(见例子)。虽然构造函数中不存在参数,但是该类中有三个public变量强制要求开发者定义,它们是:
String RootPath - 一般来说是.minecraft文件夹的所在路径
IVersionLocator VersionLocator - 对于ProjBobcat的初级编程,只要new一个DefaultVersionLocator并且对接即可。
Guid ClientToken – launcher_profiles.json中定义的客户端识别码,可以随意设置,如生成一个随机的Guid或者使用自己定义的值。
对于初级编程操作,可以直接参考下例中的初始化方法。
例子
先对整个程序定义全局变量(如WinForm和控制台程序的Program.cs或者WPF程序的App.xaml.cs):
  1. public static DefaultGameCore core;
复制代码
然后在程序初始化时候添加一个函数:
  1. public static void InitLauncherCore()
  2. {
  3.     var clientToken = new Guid("88888888-8888-8888-8888-888888888888");
  4.     var rootPath = ".minecraft\";
  5.    
  6.     core = new DefaultGameCore
  7.     {
  8.         ClientToken = clientToken,
  9.         RootPath = rootPath,
  10.         VersionLocator = new DefaultVersionLocator(rootPath, clientToken)
  11.         {
  12.             LauncherProfileParser = new DefaultLauncherProfileParser(rootPath, clientToken)
  13.         }
  14.     };
  15. }
复制代码
然后在程序入口点执行InitLauncherCore()即可。

      获取全部或指定游戏信息
  !   请注意。和其他同类开源项目一样,ProjBobcat没有内置自动补全系统和游戏下载系统等任何联网的系统。我们有相关的开发计划,但是截至目前为止,ProjBobcat是为已经完全下载了所有Assets和Libraries的服务器或者本地整合包设计的。如果您想开发一款鲁棒性极强的启动器,在我们推出网络模块之前,您要自行解决版本下载和补全的问题。
  !   由于上述限制,在接下来的教程中,我们默认已经满足了所有条件。如果您要为调试创造这种环境,您可以用别的启动器在开发文件夹中下载游戏并且补全资源。
特殊类型
类型名称
代码形式
(包括启动参数、Assets和Libraries列表等在内的)游戏信息
ProjBobcat.Class.Model.VersionInfo
所有方法
方法名称
代码形式
返回
获取所有游戏信息
ProjBobcat.DefaultGameCore.VersionLocator.GetAllGames()
一个IEnumerable表,以VersionInfo形式包含所有游戏的信息
获取部分游戏信息
ProjBobcat.DefaultGameCore.VersionLocator.GetGame(string id)
一个VersionInfo类型,包含版本号为id的游戏信息
例子
下述实例是一个用GetAllGames()输出所有游戏名称和用GetGame()获取此前生成的游戏列表的第一个游戏的Assets下载地址的控制台程序代码:
  1. Console.WriteLine(core.VersionLocator.GetAllGames().Count());
  2. List<VersionInfo> gameList = core.VersionLocator.GetAllGames().ToList();
  3. foreach(var game in gameList)
  4. {
  5.     Console.WriteLine(game.Name);
  6. }
复制代码
练习
已知.minecraft\versions\文件夹下所有文件夹的名称与该文件夹内部包含游戏的版本相同,假设没有空文件夹,写一个程序,只用GetGame()方法,将所有游戏的VersionInfo装到一个表List<VersionInfo>里。
参考思路
通过系统的Directory类提供的GetDirectories()方法获取versions文件夹下所有的子文件夹名称,然后对各个名称进行枚举,对于每个名称,对其使用GetGame()方法,然后把获得的VersionInfo数据装入一个例如List<VersionInfo>的表中。
事实上,这和ProjBobcat对GetAllGames()的内部实现相似。

      启动配置
  !   文档少了些什么?本文的前面部分都假设所有的Assets和Libraries已经下载好,故没有“获取补全列表”部分。这将在后面补充。如果您对C#开发比较了解,那么您可以先研究一下VersionInfo中包含的信息,事实上补全列表也在其中。
特殊类型
类型名称
代码形式
启动设置
ProjBobcat.Class.Model.LaunchSettings
启动参数
ProjBobcat.Class.Model.GameArguments
离线验证器
ProjBobcat.Authenticator.OfflineAuthenticator
所有方法
都是构造函数我懒得写了,反正你们也不看这两个表(
例子
  !   本教程的在线验证器部分将在未来更新。
  1. var launchSettings = new LaunchSettings
  2. {
  3.     FallBackGameArguments = new GameArguments // 游戏启动参数缺省值,适用于以该启动设置启动的所有游戏,对于具体的某个游戏,可以设置(见下)具体的启动参数,如果所设置的具体参数出现缺失,将使用这个补全
  4.     {
  5.         GcType = GcType.G1Gc, // GC类型
  6.         JavaExecutable = javaPath, // Java路径
  7.         Resolution = new ResolutionModel // 游戏窗口分辨率
  8.         {
  9. Height = 600, // 高度
  10. Width = 800 // 宽度
  11.         },
  12.         MinMemory = 512, // 最小内存
  13.         MaxMemory = 1024 // 最大内存
  14.     },
  15.     Version = versionId, // 需要启动的游戏ID
  16.     VersionInsulation = false, // 版本隔离
  17.     GameResourcePath = core.RootPath, // 资源根目录
  18.     GamePath = core.RootPath, // 游戏根目录,如果有版本隔离则应该改为GamePathHelper.GetGamePath(Core.RootPath, versionId)
  19.     VersionLocator = core.VersionLocator, // 游戏定位器
  20.    
  21. };

  22. launchSettings.GameArguments = new GameArguments // (可选)具体游戏启动参数
  23. {
  24.     AdvanceArguments = "", // 高级启动参数
  25.     JavaExecutable = javaPath, // JAVA路径
  26.     Resolution = new ResolutionModel
  27.     {
  28.         Height=600,
  29.         Width=800
  30.     }, // 游戏窗口分辨率
  31.     MinMemory = 512, // 最小内存
  32.     MaxMemory = 1024 // 最大内存
  33. };


  34. launchSettings.Authenticator = new OfflineAuthenticator
  35. {
  36.     Username = "test",
  37.     LauncherProfileParser = core.VersionLocator.LauncherProfileParser // launcher_profiles.json解析组件
  38. };
复制代码

      启动游戏!
特殊类型
类型名称
代码形式
启动结果
ProjBobcat.Class.Model.LaunchResult
所有方法
方法名称
代码形式
返回
(异步)游戏启动
ProjBobcat.DefaultGameCore.LaunchTaskAsync(LaunchSettings launchSettings)
一个启动结果,类型为LaunchResult。
  !    哪个男孩不想让启动器在游戏启动的时候卡一下呢?我们将在不久的将来给启动核心加上同步的游戏启动,满足各类奇异癖好的需求!
例子
  1. var result = await core.LaunchTaskAsync(launchSettings).ConfigureAwait(true);
复制代码
备注
此外,我们还提供了若干事件用于绑定:
DefaultGameCore.GameLogEventDelegate用于绑定游戏日志事件
DefaultGameCore.LaunchLogEventDelegate用于绑定启动核心日志事件
DefaultGameCore.GameExitEventDelegate用于绑定游戏退出事件
对事件绑定的使用可参考以下练习。
练习
写一个控制台程序片段,实现在游戏退出时输出“DONE”。
答案
在上述例子的代码之前加上:
  1. core.GameExitEventDelegate += Core_GameExitEventDelegate;
复制代码
然后新建一个方法:
  1. private static void Core_GameExitEventDelegate(object sender, ProjBobcat.Event.GameExitEventArgs e)
  2. {
  3.     Console.WriteLine("DONE");
  4. }
复制代码

      初级编程部分尾声
至此,ProjBobcat的初级教程告终。
这里附一份在编纂本文档期间编写的一份控制台启动代码,涵盖了上述讲的所有内容,可以运行获取的游戏列表中的第一款游戏。
这一段代码是非常初级的,与真正的启动器的游戏启动模块相比,还缺少包括内存回收在内的很多内容,仅供参考。
复制到您的项目中时,记得修改命名空间使其对应您的项目。

      更新预告
在接下来的内容中,在补充初级教程的正版验证教学的同时,我会补上两大教学内容:
ProjBobcat高级开发 - 通过我们在ProjBobcat中设置的大量接口和基类,在不修改ProjBobcat本身代码的情况下,把ProjBobcat的四大核心(启动内核、版本搜索器、launcher_profiles.json解析器、启动参数生成器)换成自定义的核心!
ProjBobcat解构 - 完全解析ProjBobcat的代码结构和代码用途,为启动核心学习者准备的最好礼物!

CRAFTMINEFUN
快更新!!!写的很详细!!!(团队成员前来康康)(跑

天宫时雨
ProjBobcat有只橘猫,其他项目没有。

橘猫好评!

Heer_Kaisair
既然这样那就和朋友搞个水墨风启动器得了(水墨风是幌子(删去
楼主加油更新(来自一个咕咕咕帖子半年的人

法棍面包
橘猫好哇!

日暮清林
老腊肉快给我更新教程!

fang—he
你的示例代码中缺少GameName导致启动失败

LF_Mcxixif
不能用太草了?



akchiji888

要用net5.0+

akchiji888
话说using后面要填啥啊

祥冬
终于找到C#编的核心了![泪目]

可可的验证
快更新!!!写的很详细!!!(团队成员前来康康)(跑

祥冬
顶一顶[防陈旧]

祥冬
话说作者可否把框架改回.NETFramework?.Net虽然可以跨平台,但是支持的插件太少了

祥冬
帖子咋又要挖掘卡了?[热度不会这么低ba]

akchiji888
顶一顶,防陈旧

akchiji888
MCBBS有你更精彩

akchiji888
为什么又要挖掘卡了

akchiji888
66666666666

akchiji888
快更新微软登录求求了

akchiji888

顶一顶[防陈旧]

CRAFTMINEFUN
akchiji888 发表于 2022-3-11 08:20
快更新微软登录求求了

微软登录很早就支持辣

CRAFTMINEFUN

ProjBobcat 目前仅支持 .Net5 及以上的运行时

CRAFTMINEFUN
祥冬 发表于 2022-1-28 13:41
话说作者可否把框架改回.NETFramework?.Net虽然可以跨平台,但是支持的插件太少了 ...

现在支持的 Nuget 包挺多的吧,主要是 ProjBobcat 使用了很多新语法

祥冬
顶一顶[防陈旧]

祥冬
顶一顶[防陈旧]

akchiji888
CRAFTMINEFUN 发表于 2022-3-27 13:24
微软登录很早就支持辣

我指的是微软登录的教程啦

第一页 上一页 下一页 最后一页