@@ -12,14 +12,23 @@ const ConfigManager = require('./configmanager')
1212
1313const logger = LoggerUtil . getLogger ( 'ProcessBuilder' )
1414
15+
16+ /**
17+ * Only forge and fabric are top level mod loaders.
18+ *
19+ * Forge 1.13+ launch logic is similar to fabrics, for now using usingFabricLoader flag to
20+ * change minor details when needed.
21+ *
22+ * Rewrite of this module may be needed in the future.
23+ */
1524class ProcessBuilder {
1625
17- constructor ( distroServer , versionData , forgeData , authUser , launcherVersion ) {
26+ constructor ( distroServer , vanillaManifest , modManifest , authUser , launcherVersion ) {
1827 this . gameDir = path . join ( ConfigManager . getInstanceDirectory ( ) , distroServer . rawServer . id )
1928 this . commonDir = ConfigManager . getCommonDirectory ( )
2029 this . server = distroServer
21- this . versionData = versionData
22- this . forgeData = forgeData
30+ this . vanillaManifest = vanillaManifest
31+ this . modManifest = modManifest
2332 this . authUser = authUser
2433 this . launcherVersion = launcherVersion
2534 this . forgeModListFile = path . join ( this . gameDir , 'forgeMods.list' ) // 1.13+
@@ -28,6 +37,7 @@ class ProcessBuilder {
2837 this . libPath = path . join ( this . commonDir , 'libraries' )
2938
3039 this . usingLiteLoader = false
40+ this . usingFabricLoader = false
3141 this . llPath = null
3242 }
3343
@@ -40,9 +50,12 @@ class ProcessBuilder {
4050 process . throwDeprecation = true
4151 this . setupLiteLoader ( )
4252 logger . info ( 'Using liteloader:' , this . usingLiteLoader )
53+ this . usingFabricLoader = this . server . modules . some ( mdl => mdl . rawModule . type === Type . Fabric )
54+ logger . info ( 'Using fabric loader:' , this . usingFabricLoader )
4355 const modObj = this . resolveModConfiguration ( ConfigManager . getModConfiguration ( this . server . rawServer . id ) . mods , this . server . modules )
4456
4557 // Mod list below 1.13
58+ // Fabric only supports 1.14+
4659 if ( ! mcVersionAtLeast ( '1.13' , this . server . rawServer . minecraftVersion ) ) {
4760 this . constructJSONModList ( 'forge' , modObj . fMods , true )
4861 if ( this . usingLiteLoader ) {
@@ -166,7 +179,7 @@ class ProcessBuilder {
166179
167180 for ( let mdl of mdls ) {
168181 const type = mdl . rawModule . type
169- if ( type === Type . ForgeMod || type === Type . LiteMod || type === Type . LiteLoader ) {
182+ if ( type === Type . ForgeMod || type === Type . LiteMod || type === Type . LiteLoader || type === Type . FabricMod ) {
170183 const o = ! mdl . getRequired ( ) . value
171184 const e = ProcessBuilder . isModEnabled ( modCfg [ mdl . getVersionlessMavenIdentifier ( ) ] , mdl . getRequired ( ) )
172185 if ( ! o || ( o && e ) ) {
@@ -178,7 +191,7 @@ class ProcessBuilder {
178191 continue
179192 }
180193 }
181- if ( type === Type . ForgeMod ) {
194+ if ( type === Type . ForgeMod || type === Type . FabricMod ) {
182195 fMods . push ( mdl )
183196 } else {
184197 lMods . push ( mdl )
@@ -194,7 +207,7 @@ class ProcessBuilder {
194207 }
195208
196209 _lteMinorVersion ( version ) {
197- return Number ( this . forgeData . id . split ( '-' ) [ 0 ] . split ( '.' ) [ 1 ] ) <= Number ( version )
210+ return Number ( this . modManifest . id . split ( '-' ) [ 0 ] . split ( '.' ) [ 1 ] ) <= Number ( version )
198211 }
199212
200213 /**
@@ -206,7 +219,7 @@ class ProcessBuilder {
206219 if ( this . _lteMinorVersion ( 9 ) ) {
207220 return false
208221 }
209- const ver = this . forgeData . id . split ( '-' ) [ 2 ]
222+ const ver = this . modManifest . id . split ( '-' ) [ 2 ]
210223 const pts = ver . split ( '.' )
211224 const min = [ 14 , 23 , 3 , 2655 ]
212225 for ( let i = 0 ; i < pts . length ; i ++ ) {
@@ -282,18 +295,21 @@ class ProcessBuilder {
282295 // }
283296
284297 /**
285- * Construct the mod argument list for forge 1.13
298+ * Construct the mod argument list for forge 1.13 and Fabric
286299 *
287300 * @param {Array.<Object> } mods An array of mods to add to the mod list.
288301 */
289302 constructModList ( mods ) {
290303 const writeBuffer = mods . map ( mod => {
291- return mod . getExtensionlessMavenIdentifier ( )
304+ return this . usingFabricLoader ? mod . getPath ( ) : mod . getExtensionlessMavenIdentifier ( )
292305 } ) . join ( '\n' )
293306
294307 if ( writeBuffer ) {
295308 fs . writeFileSync ( this . forgeModListFile , writeBuffer , 'UTF-8' )
296- return [
309+ return this . usingFabricLoader ? [
310+ '--fabric.addMods' ,
311+ `@${ this . forgeModListFile } `
312+ ] : [
297313 '--fml.mavenRoots' ,
298314 path . join ( '..' , '..' , 'common' , 'modstore' ) ,
299315 '--fml.modLists' ,
@@ -361,7 +377,7 @@ class ProcessBuilder {
361377 args . push ( '-Djava.library.path=' + tempNativePath )
362378
363379 // Main Java Class
364- args . push ( this . forgeData . mainClass )
380+ args . push ( this . modManifest . mainClass )
365381
366382 // Forge Arguments
367383 args = args . concat ( this . _resolveForgeArgs ( ) )
@@ -384,17 +400,17 @@ class ProcessBuilder {
384400 const argDiscovery = / \$ { * ( .* ) } /
385401
386402 // JVM Arguments First
387- let args = this . versionData . arguments . jvm
403+ let args = this . vanillaManifest . arguments . jvm
388404
389405 // Debug securejarhandler
390406 // args.push('-Dbsl.debug=true')
391407
392- if ( this . forgeData . arguments . jvm != null ) {
393- for ( const argStr of this . forgeData . arguments . jvm ) {
408+ if ( this . modManifest . arguments . jvm != null ) {
409+ for ( const argStr of this . modManifest . arguments . jvm ) {
394410 args . push ( argStr
395411 . replaceAll ( '${library_directory}' , this . libPath )
396412 . replaceAll ( '${classpath_separator}' , ProcessBuilder . getClasspathSeparator ( ) )
397- . replaceAll ( '${version_name}' , this . forgeData . id )
413+ . replaceAll ( '${version_name}' , this . modManifest . id )
398414 )
399415 }
400416 }
@@ -411,10 +427,10 @@ class ProcessBuilder {
411427 args = args . concat ( ConfigManager . getJVMOptions ( this . server . rawServer . id ) )
412428
413429 // Main Java Class
414- args . push ( this . forgeData . mainClass )
430+ args . push ( this . modManifest . mainClass )
415431
416432 // Vanilla Arguments
417- args = args . concat ( this . versionData . arguments . game )
433+ args = args . concat ( this . vanillaManifest . arguments . game )
418434
419435 for ( let i = 0 ; i < args . length ; i ++ ) {
420436 if ( typeof args [ i ] === 'object' && args [ i ] . rules != null ) {
@@ -471,7 +487,7 @@ class ProcessBuilder {
471487 val = this . authUser . displayName . trim ( )
472488 break
473489 case 'version_name' :
474- //val = versionData .id
490+ //val = vanillaManifest .id
475491 val = this . server . rawServer . id
476492 break
477493 case 'game_directory' :
@@ -481,7 +497,7 @@ class ProcessBuilder {
481497 val = path . join ( this . commonDir , 'assets' )
482498 break
483499 case 'assets_index_name' :
484- val = this . versionData . assets
500+ val = this . vanillaManifest . assets
485501 break
486502 case 'auth_uuid' :
487503 val = this . authUser . uuid . trim ( )
@@ -493,7 +509,7 @@ class ProcessBuilder {
493509 val = this . authUser . type === 'microsoft' ? 'msa' : 'mojang'
494510 break
495511 case 'version_type' :
496- val = this . versionData . type
512+ val = this . vanillaManifest . type
497513 break
498514 case 'resolution_width' :
499515 val = ConfigManager . getGameWidth ( )
@@ -522,25 +538,11 @@ class ProcessBuilder {
522538 }
523539
524540 // Autoconnect
525- let isAutoconnectBroken
526- try {
527- isAutoconnectBroken = ProcessBuilder . isAutoconnectBroken ( this . forgeData . id . split ( '-' ) [ 2 ] )
528- } catch ( err ) {
529- logger . error ( err )
530- logger . error ( 'Forge version format changed.. assuming autoconnect works.' )
531- logger . debug ( 'Forge version:' , this . forgeData . id )
532- }
533-
534- if ( isAutoconnectBroken ) {
535- logger . error ( 'Server autoconnect disabled on Forge 1.15.2 for builds earlier than 31.2.15 due to OpenGL Stack Overflow issue.' )
536- logger . error ( 'Please upgrade your Forge version to at least 31.2.15!' )
537- } else {
538- this . _processAutoConnectArg ( args )
539- }
541+ this . _processAutoConnectArg ( args )
540542
541543
542544 // Forge Specific Arguments
543- args = args . concat ( this . forgeData . arguments . game )
545+ args = args . concat ( this . modManifest . arguments . game )
544546
545547 // Filter null values
546548 args = args . filter ( arg => {
@@ -556,7 +558,7 @@ class ProcessBuilder {
556558 * @returns {Array.<string> } An array containing the arguments required by forge.
557559 */
558560 _resolveForgeArgs ( ) {
559- const mcArgs = this . forgeData . minecraftArguments . split ( ' ' )
561+ const mcArgs = this . modManifest . minecraftArguments . split ( ' ' )
560562 const argDiscovery = / \$ { * ( .* ) } /
561563
562564 // Replace the declared variables with their proper values.
@@ -569,7 +571,7 @@ class ProcessBuilder {
569571 val = this . authUser . displayName . trim ( )
570572 break
571573 case 'version_name' :
572- //val = versionData .id
574+ //val = vanillaManifest .id
573575 val = this . server . rawServer . id
574576 break
575577 case 'game_directory' :
@@ -579,7 +581,7 @@ class ProcessBuilder {
579581 val = path . join ( this . commonDir , 'assets' )
580582 break
581583 case 'assets_index_name' :
582- val = this . versionData . assets
584+ val = this . vanillaManifest . assets
583585 break
584586 case 'auth_uuid' :
585587 val = this . authUser . uuid . trim ( )
@@ -594,7 +596,7 @@ class ProcessBuilder {
594596 val = '{}'
595597 break
596598 case 'version_type' :
597- val = this . versionData . type
599+ val = this . vanillaManifest . type
598600 break
599601 }
600602 if ( val != null ) {
@@ -669,10 +671,10 @@ class ProcessBuilder {
669671 classpathArg ( mods , tempNativePath ) {
670672 let cpArgs = [ ]
671673
672- if ( ! mcVersionAtLeast ( '1.17' , this . server . rawServer . minecraftVersion ) ) {
674+ if ( ! mcVersionAtLeast ( '1.17' , this . server . rawServer . minecraftVersion ) || this . usingFabricLoader ) {
673675 // Add the version.jar to the classpath.
674676 // Must not be added to the classpath for Forge 1.17+.
675- const version = this . versionData . id
677+ const version = this . vanillaManifest . id
676678 cpArgs . push ( path . join ( this . commonDir , 'versions' , version , version + '.jar' ) )
677679 }
678680
@@ -711,7 +713,7 @@ class ProcessBuilder {
711713 const nativesRegex = / .+ : n a t i v e s - ( [ ^ - ] + ) (?: - ( .+ ) ) ? /
712714 const libs = { }
713715
714- const libArr = this . versionData . libraries
716+ const libArr = this . vanillaManifest . libraries
715717 fs . ensureDirSync ( tempNativePath )
716718 for ( let i = 0 ; i < libArr . length ; i ++ ) {
717719 const lib = libArr [ i ]
@@ -830,10 +832,10 @@ class ProcessBuilder {
830832 const mdls = this . server . modules
831833 let libs = { }
832834
833- // Locate Forge/Libraries
835+ // Locate Forge/Fabric/ Libraries
834836 for ( let mdl of mdls ) {
835837 const type = mdl . rawModule . type
836- if ( type === Type . ForgeHosted || type === Type . Library ) {
838+ if ( type === Type . ForgeHosted || type === Type . Fabric || type === Type . Library ) {
837839 libs [ mdl . getVersionlessMavenIdentifier ( ) ] = mdl . getPath ( )
838840 if ( mdl . subModules . length > 0 ) {
839841 const res = this . _resolveModuleLibraries ( mdl )
@@ -887,24 +889,6 @@ class ProcessBuilder {
887889 return libs
888890 }
889891
890- static isAutoconnectBroken ( forgeVersion ) {
891-
892- const minWorking = [ 31 , 2 , 15 ]
893- const verSplit = forgeVersion . split ( '.' ) . map ( v => Number ( v ) )
894-
895- if ( verSplit [ 0 ] === 31 ) {
896- for ( let i = 0 ; i < minWorking . length ; i ++ ) {
897- if ( verSplit [ i ] > minWorking [ i ] ) {
898- return false
899- } else if ( verSplit [ i ] < minWorking [ i ] ) {
900- return true
901- }
902- }
903- }
904-
905- return false
906- }
907-
908892}
909893
910894module . exports = ProcessBuilder
0 commit comments