2018-03-25 15:59:43 +00:00
/ *
* Minecraft Forge
2019-02-10 22:57:03 +00:00
* Copyright ( c ) 2016 - 2019 .
2018-03-25 15:59:43 +00:00
*
* This library is free software ; you can redistribute it and / or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2 . 1
* of the License .
*
* This library is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* Lesser General Public License for more details .
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library ; if not , write to the Free Software
* Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA
* /
package net.minecraftforge.fml.loading ;
2019-01-04 16:44:57 +00:00
import cpw.mods.modlauncher.TransformingClassLoader ;
2018-03-25 15:59:43 +00:00
import cpw.mods.modlauncher.api.IEnvironment ;
2018-04-08 00:38:43 +00:00
import cpw.mods.modlauncher.api.ILaunchHandlerService ;
2018-03-25 15:59:43 +00:00
import cpw.mods.modlauncher.api.ITransformationService ;
2018-06-06 15:37:56 +00:00
import cpw.mods.modlauncher.api.ITransformingClassLoader ;
2018-03-25 15:59:43 +00:00
import cpw.mods.modlauncher.api.IncompatibleEnvironmentException ;
import cpw.mods.modlauncher.serviceapi.ILaunchPluginService ;
2018-06-21 19:37:32 +00:00
import net.minecraftforge.api.distmarker.Dist ;
2018-06-06 15:37:56 +00:00
import net.minecraftforge.fml.loading.moddiscovery.BackgroundScanHandler ;
2018-03-25 15:59:43 +00:00
import net.minecraftforge.fml.loading.moddiscovery.ModDiscoverer ;
2018-04-07 22:15:32 +00:00
import net.minecraftforge.fml.loading.moddiscovery.ModFile ;
2019-01-14 03:51:36 +00:00
import net.minecraftforge.forgespi.coremod.ICoreModProvider ;
2018-08-27 17:10:07 +00:00
import org.apache.logging.log4j.LogManager ;
import org.apache.logging.log4j.Logger ;
2018-03-25 15:59:43 +00:00
2018-04-07 22:15:32 +00:00
import java.net.URL ;
import java.nio.file.Path ;
import java.nio.file.Paths ;
2018-12-31 21:33:54 +00:00
import java.util.* ;
import java.util.function.Predicate ;
2018-04-07 03:58:48 +00:00
import java.util.stream.Collectors ;
2018-03-25 15:59:43 +00:00
2018-12-31 21:33:54 +00:00
import static net.minecraftforge.fml.loading.LogMarkers.CORE ;
import static net.minecraftforge.fml.loading.LogMarkers.SCAN ;
2018-03-25 15:59:43 +00:00
public class FMLLoader
{
2018-08-27 17:10:07 +00:00
private static final Logger LOGGER = LogManager . getLogger ( ) ;
2018-03-25 15:59:43 +00:00
private static ILaunchPluginService accessTransformer ;
private static ModDiscoverer modDiscoverer ;
2018-04-07 15:48:43 +00:00
private static ICoreModProvider coreModProvider ;
2018-06-11 01:12:46 +00:00
private static ILaunchPluginService eventBus ;
2018-04-07 15:48:43 +00:00
private static LanguageLoadingProvider languageLoadingProvider ;
2018-06-21 19:37:32 +00:00
private static Dist dist ;
2018-06-15 19:03:35 +00:00
private static LoadingModList loadingModList ;
2019-01-04 16:44:57 +00:00
private static TransformingClassLoader launchClassLoader ;
2018-06-21 19:37:32 +00:00
private static RuntimeDistCleaner runtimeDistCleaner ;
2018-06-22 18:38:53 +00:00
private static Path gamePath ;
2018-06-23 02:45:01 +00:00
private static Path forgePath ;
2018-12-31 21:33:54 +00:00
private static Path [ ] mcPaths ;
static String mcVersion ;
2019-01-01 21:50:04 +00:00
private static String mcpVersion ;
static String forgeVersion ;
private static String forgeGroup ;
2018-12-31 21:33:54 +00:00
private static Predicate < String > classLoaderExclusions ;
2018-03-25 15:59:43 +00:00
2018-04-07 03:58:48 +00:00
static void onInitialLoad ( IEnvironment environment , Set < String > otherServices ) throws IncompatibleEnvironmentException
2018-03-25 15:59:43 +00:00
{
2018-12-31 21:33:54 +00:00
final String version = LauncherVersion . getVersion ( ) ;
2018-08-27 17:10:07 +00:00
LOGGER . debug ( CORE , " FML {} loading " , version ) ;
2018-03-25 15:59:43 +00:00
final Package modLauncherPackage = ITransformationService . class . getPackage ( ) ;
2018-08-27 17:10:07 +00:00
LOGGER . debug ( CORE , " FML found ModLauncher version : {} " , modLauncherPackage . getImplementationVersion ( ) ) ;
2018-03-25 15:59:43 +00:00
if ( ! modLauncherPackage . isCompatibleWith ( " 1.0 " ) ) {
2019-01-06 20:46:29 +00:00
LOGGER . fatal ( CORE , " Found incompatible ModLauncher specification : {}, version {} from {} " , modLauncherPackage . getSpecificationVersion ( ) , modLauncherPackage . getImplementationVersion ( ) , modLauncherPackage . getImplementationVendor ( ) ) ;
2018-03-25 15:59:43 +00:00
throw new IncompatibleEnvironmentException ( " Incompatible modlauncher found " + modLauncherPackage . getSpecificationVersion ( ) ) ;
}
2018-08-27 17:10:07 +00:00
LOGGER . debug ( CORE , " Initializing modjar URL handler " ) ;
2018-06-11 01:12:46 +00:00
URL . setURLStreamHandlerFactory ( p - > p . equals ( " modjar " ) ? new ModJarURLHandler ( ) : null ) ;
2018-03-25 15:59:43 +00:00
accessTransformer = environment . findLaunchPlugin ( " accesstransformer " ) . orElseThrow ( ( ) - > new IncompatibleEnvironmentException ( " Missing AccessTransformer, cannot run " ) ) ;
final Package atPackage = accessTransformer . getClass ( ) . getPackage ( ) ;
2018-08-27 17:10:07 +00:00
LOGGER . debug ( CORE , " FML found AccessTransformer version : {} " , atPackage . getImplementationVersion ( ) ) ;
2018-03-25 15:59:43 +00:00
if ( ! atPackage . isCompatibleWith ( " 1.0 " ) ) {
2019-01-06 20:46:29 +00:00
LOGGER . fatal ( CORE , " Found incompatible AccessTransformer specification : {}, version {} from {} " , atPackage . getSpecificationVersion ( ) , atPackage . getImplementationVersion ( ) , atPackage . getImplementationVendor ( ) ) ;
2018-04-07 03:58:48 +00:00
throw new IncompatibleEnvironmentException ( " Incompatible accesstransformer found " + atPackage . getSpecificationVersion ( ) ) ;
2018-03-25 15:59:43 +00:00
}
2018-06-11 01:12:46 +00:00
eventBus = environment . findLaunchPlugin ( " eventbus " ) . orElseThrow ( ( ) - > new IncompatibleEnvironmentException ( " Missing EventBus, cannot run " ) ) ;
final Package eventBusPackage = eventBus . getClass ( ) . getPackage ( ) ;
2018-08-27 17:10:07 +00:00
LOGGER . debug ( CORE , " FML found EventBus version : {} " , eventBusPackage . getImplementationVersion ( ) ) ;
2018-06-11 01:12:46 +00:00
if ( ! eventBusPackage . isCompatibleWith ( " 1.0 " ) ) {
2019-01-06 20:46:29 +00:00
LOGGER . fatal ( CORE , " Found incompatible EventBus specification : {}, version {} from {} " , eventBusPackage . getSpecificationVersion ( ) , eventBusPackage . getImplementationVersion ( ) , eventBusPackage . getImplementationVendor ( ) ) ;
2018-06-11 01:12:46 +00:00
throw new IncompatibleEnvironmentException ( " Incompatible eventbus found " + eventBusPackage . getSpecificationVersion ( ) ) ;
}
2018-06-21 19:37:32 +00:00
runtimeDistCleaner = ( RuntimeDistCleaner ) environment . findLaunchPlugin ( " runtimedistcleaner " ) . orElseThrow ( ( ) - > new IncompatibleEnvironmentException ( " Missing RuntimeDistCleaner, cannot run! " ) ) ;
2018-08-27 17:10:07 +00:00
LOGGER . debug ( CORE , " Found Runtime Dist Cleaner " ) ;
2018-06-21 19:37:32 +00:00
2018-04-07 03:58:48 +00:00
final ArrayList < ICoreModProvider > coreModProviders = new ArrayList < > ( ) ;
ServiceLoader . load ( ICoreModProvider . class ) . forEach ( coreModProviders : : add ) ;
if ( coreModProviders . isEmpty ( ) ) {
2019-01-06 20:46:29 +00:00
LOGGER . fatal ( CORE , " Found no coremod provider. Cannot run " ) ;
2018-04-07 03:58:48 +00:00
throw new IncompatibleEnvironmentException ( " No coremod library found " ) ;
} else if ( coreModProviders . size ( ) > 1 ) {
2019-01-06 20:46:29 +00:00
LOGGER . fatal ( CORE , " Found multiple coremod providers : {}. Cannot run " , coreModProviders . stream ( ) . map ( p - > p . getClass ( ) . getName ( ) ) . collect ( Collectors . toList ( ) ) ) ;
2018-04-07 03:58:48 +00:00
throw new IncompatibleEnvironmentException ( " Multiple coremod libraries found " ) ;
}
2018-04-07 15:48:43 +00:00
coreModProvider = coreModProviders . get ( 0 ) ;
final Package coremodPackage = coreModProvider . getClass ( ) . getPackage ( ) ;
2018-08-27 17:10:07 +00:00
LOGGER . debug ( CORE , " FML found CoreMod version : {} " , coremodPackage . getImplementationVersion ( ) ) ;
2018-04-07 03:58:48 +00:00
}
2018-12-31 21:33:54 +00:00
static void setupLaunchHandler ( final IEnvironment environment , final Map < String , ? > arguments )
2018-04-08 00:38:43 +00:00
{
final String launchTarget = environment . getProperty ( IEnvironment . Keys . LAUNCHTARGET . get ( ) ) . orElse ( " MISSING " ) ;
final Optional < ILaunchHandlerService > launchHandler = environment . findLaunchHandler ( launchTarget ) ;
2018-08-27 17:10:07 +00:00
LOGGER . debug ( CORE , " Using {} as launch service " , launchTarget ) ;
2018-04-08 00:38:43 +00:00
if ( ! launchHandler . isPresent ( ) ) {
2019-01-06 20:46:29 +00:00
LOGGER . fatal ( CORE , " Missing LaunchHandler {}, cannot continue " , launchTarget ) ;
2018-06-06 15:37:56 +00:00
throw new RuntimeException ( " Missing launch handler " ) ;
2018-04-08 00:38:43 +00:00
}
if ( ! ( launchHandler . get ( ) instanceof FMLCommonLaunchHandler ) ) {
2019-01-06 20:46:29 +00:00
LOGGER . fatal ( CORE , " Incompatible Launch handler found - type {}, cannot continue " , launchHandler . get ( ) . getClass ( ) . getName ( ) ) ;
2018-06-06 15:37:56 +00:00
throw new RuntimeException ( " Incompatible launch handler found " ) ;
2018-04-08 00:38:43 +00:00
}
2018-06-22 18:38:53 +00:00
gamePath = environment . getProperty ( IEnvironment . Keys . GAMEDIR . get ( ) ) . orElse ( Paths . get ( " . " ) . toAbsolutePath ( ) ) ;
2018-04-08 00:38:43 +00:00
FMLCommonLaunchHandler commonLaunchHandler = ( FMLCommonLaunchHandler ) launchHandler . get ( ) ;
2018-06-21 19:37:32 +00:00
dist = commonLaunchHandler . getDist ( ) ;
2018-12-31 21:33:54 +00:00
mcVersion = ( String ) arguments . get ( " mcVersion " ) ;
2019-01-01 21:50:04 +00:00
mcpVersion = ( String ) arguments . get ( " mcpVersion " ) ;
2018-12-31 21:33:54 +00:00
forgeVersion = ( String ) arguments . get ( " forgeVersion " ) ;
2019-01-01 21:50:04 +00:00
forgeGroup = ( String ) arguments . get ( " forgeGroup " ) ;
2018-12-31 21:33:54 +00:00
2019-01-27 05:06:57 +00:00
LOGGER . debug ( CORE , " Received command line version data : MC Version: '{}' MCP Version: '{}' Forge Version: '{}' Forge group: '{}' " , mcVersion , mcpVersion , forgeVersion , forgeGroup ) ;
2019-01-01 21:50:04 +00:00
forgePath = commonLaunchHandler . getForgePath ( mcVersion , forgeVersion , forgeGroup ) ;
mcPaths = commonLaunchHandler . getMCPaths ( mcVersion , mcpVersion , forgeVersion , forgeGroup ) ;
2018-12-31 21:33:54 +00:00
2019-01-01 21:50:04 +00:00
commonLaunchHandler . validatePaths ( forgePath , mcPaths , forgeVersion , mcVersion , mcpVersion ) ;
2018-12-31 21:33:54 +00:00
commonLaunchHandler . setup ( environment , arguments ) ;
classLoaderExclusions = commonLaunchHandler . getPackagePredicate ( ) ;
2019-01-14 03:51:36 +00:00
2018-12-31 21:33:54 +00:00
languageLoadingProvider = new LanguageLoadingProvider ( ) ;
2019-01-01 21:50:04 +00:00
languageLoadingProvider . addForgeLanguage ( forgePath ) ;
2018-12-31 21:33:54 +00:00
2018-06-21 19:37:32 +00:00
runtimeDistCleaner . getExtension ( ) . accept ( dist ) ;
2018-04-08 00:38:43 +00:00
}
2018-12-31 21:33:54 +00:00
public static void beginModScan ( final Map < String , ? > arguments )
2018-04-07 03:58:48 +00:00
{
2018-08-27 17:10:07 +00:00
LOGGER . debug ( SCAN , " Scanning for Mod Locators " ) ;
2018-12-31 21:33:54 +00:00
modDiscoverer = new ModDiscoverer ( arguments ) ;
2018-06-06 15:37:56 +00:00
final BackgroundScanHandler backgroundScanHandler = modDiscoverer . discoverMods ( ) ;
2018-06-15 19:03:35 +00:00
loadingModList = backgroundScanHandler . getLoadingModList ( ) ;
2018-03-25 15:59:43 +00:00
}
2018-04-07 15:48:43 +00:00
public static ICoreModProvider getCoreModProvider ( ) {
return coreModProvider ;
}
public static LanguageLoadingProvider getLanguageLoadingProvider ( )
{
return languageLoadingProvider ;
}
2018-04-07 22:15:32 +00:00
2018-12-31 21:33:54 +00:00
static ModDiscoverer getModDiscoverer ( ) {
return modDiscoverer ;
}
2018-04-07 22:15:32 +00:00
public static void addAccessTransformer ( Path atPath , ModFile modName )
{
2018-08-27 17:10:07 +00:00
LOGGER . debug ( SCAN , " Adding Access Transformer in {} " , modName . getFilePath ( ) ) ;
2018-04-07 22:15:32 +00:00
accessTransformer . addResource ( atPath , modName . getFileName ( ) ) ;
}
2018-06-06 15:37:56 +00:00
2018-06-21 19:37:32 +00:00
public static Dist getDist ( )
2018-06-06 15:37:56 +00:00
{
2018-06-21 19:37:32 +00:00
return dist ;
2018-06-06 15:37:56 +00:00
}
2018-12-31 21:33:54 +00:00
public static void beforeStart ( ITransformingClassLoader launchClassLoader )
2018-06-06 15:37:56 +00:00
{
2019-01-04 16:44:57 +00:00
FMLLoader . launchClassLoader = ( TransformingClassLoader ) launchClassLoader . getInstance ( ) ;
2018-06-06 15:37:56 +00:00
}
2018-06-15 19:03:35 +00:00
public static LoadingModList getLoadingModList ( )
{
return loadingModList ;
}
2019-01-04 16:44:57 +00:00
public static TransformingClassLoader getLaunchClassLoader ( )
2018-06-06 15:37:56 +00:00
{
2018-06-15 19:03:35 +00:00
return launchClassLoader ;
2018-06-06 15:37:56 +00:00
}
2018-06-22 18:38:53 +00:00
public static Path getGamePath ( )
{
return gamePath ;
}
2018-06-23 02:45:01 +00:00
public static Path getForgePath ( ) {
return forgePath ;
}
2018-12-31 21:33:54 +00:00
public static Path [ ] getMCPaths ( ) {
return mcPaths ;
}
public static Predicate < String > getClassLoaderExclusions ( ) {
return classLoaderExclusions ;
}
2018-03-25 15:59:43 +00:00
}