2018-03-25 15:59:43 +00:00
/ *
* Minecraft Forge
* Copyright ( c ) 2018 .
*
* 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 ;
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-06 15:37:56 +00:00
import net.minecraftforge.api.Side ;
2018-03-25 15:59:43 +00:00
import net.minecraftforge.common.ForgeVersion ;
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 ;
2018-04-07 03:58:48 +00:00
import net.minecraftforge.forgespi.ICoreModProvider ;
2018-03-25 15:59:43 +00:00
2018-04-07 22:15:32 +00:00
import java.net.URISyntaxException ;
import java.net.URL ;
import java.nio.file.Path ;
import java.nio.file.Paths ;
2018-04-07 03:58:48 +00:00
import java.util.ArrayList ;
2018-04-07 22:15:32 +00:00
import java.util.Optional ;
2018-04-07 03:58:48 +00:00
import java.util.ServiceLoader ;
2018-03-25 15:59:43 +00:00
import java.util.Set ;
2018-04-07 03:58:48 +00:00
import java.util.stream.Collectors ;
2018-03-25 15:59:43 +00:00
2018-04-07 03:58:48 +00:00
import static net.minecraftforge.fml.Logging.CORE ;
import static net.minecraftforge.fml.Logging.SCAN ;
2018-03-25 15:59:43 +00:00
import static net.minecraftforge.fml.Logging.fmlLog ;
public class FMLLoader
{
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-06 15:37:56 +00:00
private static Side side ;
2018-06-15 19:03:35 +00:00
private static LoadingModList loadingModList ;
2018-06-06 15:37:56 +00:00
private static ClassLoader launchClassLoader ;
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
{
final String version = ForgeVersion . getVersion ( ) ;
2018-04-07 03:58:48 +00:00
fmlLog . debug ( CORE , " FML {} loading " , version ) ;
2018-03-25 15:59:43 +00:00
final Package modLauncherPackage = ITransformationService . class . getPackage ( ) ;
2018-04-07 03:58:48 +00:00
fmlLog . debug ( CORE , " FML found ModLauncher version : {} " , modLauncherPackage . getImplementationVersion ( ) ) ;
2018-03-25 15:59:43 +00:00
if ( ! modLauncherPackage . isCompatibleWith ( " 1.0 " ) ) {
2018-04-07 03:58:48 +00:00
fmlLog . error ( 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-06-11 01:12:46 +00:00
fmlLog . debug ( CORE , " Initializing modjar URL handler " ) ;
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-04-07 03:58:48 +00:00
fmlLog . debug ( CORE , " FML found AccessTransformer version : {} " , atPackage . getImplementationVersion ( ) ) ;
2018-03-25 15:59:43 +00:00
if ( ! atPackage . isCompatibleWith ( " 1.0 " ) ) {
2018-04-07 03:58:48 +00:00
fmlLog . error ( CORE , " Found incompatible AccessTransformer specification : {}, version {} from {} " , atPackage . getSpecificationVersion ( ) , atPackage . getImplementationVersion ( ) , atPackage . getImplementationVendor ( ) ) ;
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 ( ) ;
fmlLog . debug ( CORE , " FML found EventBus version : {} " , eventBusPackage . getImplementationVersion ( ) ) ;
if ( ! eventBusPackage . isCompatibleWith ( " 1.0 " ) ) {
fmlLog . error ( CORE , " Found incompatible EventBus specification : {}, version {} from {} " , eventBusPackage . getSpecificationVersion ( ) , eventBusPackage . getImplementationVersion ( ) , eventBusPackage . getImplementationVendor ( ) ) ;
throw new IncompatibleEnvironmentException ( " Incompatible eventbus found " + eventBusPackage . getSpecificationVersion ( ) ) ;
}
2018-04-07 03:58:48 +00:00
final ArrayList < ICoreModProvider > coreModProviders = new ArrayList < > ( ) ;
ServiceLoader . load ( ICoreModProvider . class ) . forEach ( coreModProviders : : add ) ;
if ( coreModProviders . isEmpty ( ) ) {
fmlLog . error ( CORE , " Found no coremod provider. Cannot run " ) ;
throw new IncompatibleEnvironmentException ( " No coremod library found " ) ;
} else if ( coreModProviders . size ( ) > 1 ) {
fmlLog . error ( CORE , " Found multiple coremod providers : {}. Cannot run " , coreModProviders . stream ( ) . map ( p - > p . getClass ( ) . getName ( ) ) . collect ( Collectors . toList ( ) ) ) ;
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-04-07 03:58:48 +00:00
fmlLog . debug ( CORE , " FML found CoreMod version : {} " , coremodPackage . getImplementationVersion ( ) ) ;
2018-04-07 15:48:43 +00:00
languageLoadingProvider = new LanguageLoadingProvider ( ) ;
2018-04-07 03:58:48 +00:00
}
2018-06-06 15:37:56 +00:00
static void setupLaunchHandler ( final IEnvironment environment )
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 ) ;
fmlLog . debug ( CORE , " Using {} as launch service " , launchTarget ) ;
if ( ! launchHandler . isPresent ( ) ) {
fmlLog . error ( 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 ) ) {
fmlLog . error ( 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
}
FMLCommonLaunchHandler commonLaunchHandler = ( FMLCommonLaunchHandler ) launchHandler . get ( ) ;
commonLaunchHandler . setup ( environment ) ;
2018-06-06 15:37:56 +00:00
side = commonLaunchHandler . getSidedness ( ) ;
2018-04-08 00:38:43 +00:00
}
2018-04-07 22:15:32 +00:00
public static void beginModScan ( )
2018-04-07 03:58:48 +00:00
{
fmlLog . debug ( SCAN , " Scanning for Mod Locators " ) ;
2018-03-25 15:59:43 +00:00
modDiscoverer = new ModDiscoverer ( ) ;
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
public static void loadAccessTransformer ( )
{
final URL resource = FMLLoader . class . getClassLoader ( ) . getResource ( " forge_at.cfg " ) ;
if ( resource = = null ) {
throw new RuntimeException ( " Missing forge_at.cfg file " ) ;
}
try
{
fmlLog . debug ( CORE , " Loading forge_at.cfg into access transformer " ) ;
accessTransformer . addResource ( Paths . get ( resource . toURI ( ) ) , " forge_at.cfg " ) ;
}
catch ( URISyntaxException e )
{
fmlLog . error ( " Error loading forge_at.cfg file " , e ) ;
throw new RuntimeException ( e ) ;
}
}
public static void addAccessTransformer ( Path atPath , ModFile modName )
{
fmlLog . debug ( SCAN , " Adding Access Transformer in {} " , modName . getFilePath ( ) ) ;
accessTransformer . addResource ( atPath , modName . getFileName ( ) ) ;
}
2018-06-06 15:37:56 +00:00
public static Side getSide ( )
{
return side ;
}
public static void beforeStart ( ITransformingClassLoader launchClassLoader )
{
2018-06-15 19:03:35 +00:00
FMLLoader . launchClassLoader = launchClassLoader . getInstance ( ) ;
2018-06-06 15:37:56 +00:00
}
2018-06-15 19:03:35 +00:00
public static LoadingModList getLoadingModList ( )
{
return loadingModList ;
}
public static ClassLoader 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-03-25 15:59:43 +00:00
}