@@ -28,21 +28,69 @@ import java.io.File
2828
2929private const val TAG = " VersionInfoParser"
3030
31+ class VersionInfoParser (private val version : Version ) {
32+ private var gameManifest: GameManifest ? = null
33+ private var inherit: Boolean? = null
34+ private var skipIfNotExists: Boolean = false
35+
36+ /* *
37+ * 设置预先加载的 [GameManifest]
38+ */
39+ fun setManifest (manifest : GameManifest ): VersionInfoParser {
40+ this .gameManifest = manifest
41+ return this
42+ }
43+
44+ /* *
45+ * 启用版本继承
46+ * @param skipIfNotExists 若 [GameManifest.inheritsFrom] 对应的 JSON 文件不存在,则静默跳过继承
47+ */
48+ fun setInheriting (skipIfNotExists : Boolean = false): VersionInfoParser {
49+ this .inherit = true
50+ this .skipIfNotExists = skipIfNotExists
51+ return this
52+ }
53+
54+ /* *
55+ * 构建并返回最终合并后的 [GameManifest]
56+ */
57+ fun build (): GameManifest {
58+ val manifest = gameManifest ? : GSON .fromJson(
59+ File (version.getVersionPath(), " ${version.getVersionName()} .json" ).readText(),
60+ GameManifest ::class .java
61+ )
62+
63+ val inheritsManifest = if (inherit == true && manifest.inheritsFrom != null ) {
64+ val inherits = manifest.inheritsFrom
65+ File (version.getVersionsFolder()).child(inherits).child(" ${inherits} .json" )
66+ .let { inheritsFile ->
67+ if (skipIfNotExists && ! inheritsFile.exists()) null
68+ else {
69+ GSON .fromJson(inheritsFile.readText(), GameManifest ::class .java)
70+ }
71+ }
72+ } else null
73+
74+ return getGameManifest(
75+ gameManifest = manifest,
76+ inheritsManifest = inheritsManifest
77+ )
78+ }
79+ }
80+
3181/* *
3282 * [Modified from PojavLauncher](https://github.com/PojavLauncherTeam/PojavLauncher/blob/a6f3fc0/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Tools.java#L885-L979)
3383 */
34- fun getGameManifest (
35- version : Version ,
36- gameManifest : GameManifest = GSON .fromJson(File (version.getVersionPath(), "${version.getVersionName()}.json").readText(), GameManifest ::class.java),
37- skipInheriting : Boolean = false
84+ private fun getGameManifest (
85+ gameManifest : GameManifest ,
86+ inheritsManifest : GameManifest ? ,
3887): GameManifest {
3988 var gameManifest0 = gameManifest
40- if (! skipInheriting && gameManifest0.inheritsFrom != null ) {
41- val inheritsManifest = run {
42- val inherits = gameManifest0.inheritsFrom
43- GSON .fromJson(File (version.getVersionsFolder()).child(inherits).child(" ${inherits} .json" ).readText(), GameManifest ::class .java)
44- }
45- inheritFields(inheritsManifest, gameManifest0)
89+ if (inheritsManifest != null && gameManifest0.inheritsFrom != null ) {
90+ mergeManifest(
91+ from = gameManifest0,
92+ target = inheritsManifest,
93+ )
4694
4795 // Go through the libraries, remove the ones overridden by the custom version
4896 val inheritLibraryList: MutableList <Library > = ArrayList (inheritsManifest.libraries)
@@ -124,14 +172,33 @@ fun getGameManifest(
124172 return gameManifest0
125173}
126174
127- private fun String?.isValid (): Boolean = ! this .isNullOrEmpty()
128- private fun inheritFields (target : GameManifest , from : GameManifest ) {
129- from.assetIndex?.let { target.assetIndex = it }
130- if (from.assets.isValid()) target.assets = from.assets
131- if (from.id.isValid()) target.id = from.id
132- if (from.mainClass.isValid()) target.mainClass = from.mainClass
133- if (from.minecraftArguments.isValid()) target.minecraftArguments = from.minecraftArguments
134- if (from.releaseTime.isValid()) target.releaseTime = from.releaseTime
135- if (from.time.isValid()) target.time = from.time
136- if (from.type.isValid()) target.type = from.type
175+ private inline fun <T > mergeField (
176+ getter : () -> T ? ,
177+ setter : (T ) -> Unit
178+ ) {
179+ when (val value = getter()) {
180+ null -> return
181+
182+ is String -> {
183+ if (value.isNotEmpty()) {
184+ setter(value)
185+ }
186+ }
187+
188+ else -> setter(value)
189+ }
190+ }
191+
192+ private fun mergeManifest (
193+ from : GameManifest ,
194+ target : GameManifest ,
195+ ) {
196+ mergeField(from::getRawAssetIndex, target::setAssetIndex)
197+ mergeField(from::getAssets, target::setAssets)
198+ mergeField(from::getId, target::setId)
199+ mergeField(from::getMainClass, target::setMainClass)
200+ mergeField(from::getMinecraftArguments, target::setMinecraftArguments)
201+ mergeField(from::getReleaseTime, target::setReleaseTime)
202+ mergeField(from::getTime, target::setTime)
203+ mergeField(from::getType, target::setType)
137204}
0 commit comments