2022-01-10 02:35:24 +01:00
package com.falsepattern.lib ;
2022-05-06 13:03:23 +02:00
import com.falsepattern.lib.version.Version ;
2022-01-11 00:26:36 +01:00
import com.google.common.eventbus.EventBus ;
2022-01-10 02:35:24 +01:00
import cpw.mods.fml.common.DummyModContainer ;
2022-01-11 00:26:36 +01:00
import cpw.mods.fml.common.LoadController ;
2022-01-10 02:35:24 +01:00
import cpw.mods.fml.common.ModMetadata ;
2022-01-10 18:21:27 +01:00
import lombok.NonNull ;
2022-01-10 02:35:24 +01:00
import lombok.val ;
import lombok.var ;
import net.minecraft.launchwrapper.Launch ;
import net.minecraft.launchwrapper.LaunchClassLoader ;
import org.apache.logging.log4j.LogManager ;
import org.apache.logging.log4j.Logger ;
import javax.net.ssl.HttpsURLConnection ;
import java.io.* ;
import java.net.URL ;
import java.util.* ;
public class FalsePatternLib extends DummyModContainer {
public static Logger libLog = LogManager . getLogger ( ModInfo . MODNAME );
public static final boolean developerEnvironment = ( boolean ) Launch . blackboard . get ( "fml.deobfuscatedEnvironment" );
2022-01-10 18:21:27 +01:00
private static final Map < String , Version > loadedLibraries = new HashMap <> ();
private static final Map < String , String > loadedLibraryMods = new HashMap <> ();
private static final Set < String > mavenRepositories = new HashSet <> ();
2022-01-10 02:35:24 +01:00
public FalsePatternLib () {
super ( new ModMetadata ());
libLog . info ( "All your libraries are belong to us!" );
val meta = getMetadata ();
meta . modId = ModInfo . MODID ;
meta . name = ModInfo . MODNAME ;
meta . version = ModInfo . VERSION ;
meta . url = ModInfo . URL ;
meta . credits = ModInfo . CREDITS ;
meta . authorList = Arrays . asList ( ModInfo . AUTHORS );
meta . description = ModInfo . DESCRIPTION ;
meta . useDependencyInformation = true ;
}
2022-01-11 00:26:36 +01:00
@SuppressWarnings ( "UnstableApiUsage" )
@Override
public boolean registerBus ( EventBus bus , LoadController controller ) {
return true ;
}
2022-01-10 02:35:24 +01:00
public static void addMavenRepo ( String url ) {
mavenRepositories . add ( url );
}
2022-01-10 18:21:27 +01:00
@SuppressWarnings ( "ResultOfMethodCallIgnored" )
2022-03-18 23:33:18 +01:00
public static void loadLibrary ( String loadingModId , String groupId , String artifactId , @NonNull Version minVersion , Version maxVersion , @NonNull Version preferredVersion , String regularSuffix , String devSuffix ) {
val suffix = developerEnvironment ? devSuffix : regularSuffix ;
libLog . info ( "Adding library {}:{}:{}{}, requested by mod {}" , groupId , artifactId , preferredVersion , suffix != null ? "-" + suffix : "" , loadingModId );
var artifact = groupId + ":" + artifactId + ":" + suffix ;
2022-01-10 02:35:24 +01:00
if ( loadedLibraries . containsKey ( artifact )) {
val currentVer = loadedLibraries . get ( artifact );
2022-01-10 18:21:27 +01:00
if ( currentVer . equals ( preferredVersion )) return ;
val rangeString = "(minimum: " + minVersion + ( maxVersion == null ? "" : ", maximum: " + maxVersion ) + ")" ;
if ( minVersion . compareTo ( currentVer ) > 0 || ( maxVersion != null && maxVersion . compareTo ( currentVer ) < 0 )) {
for ( int i = 0 ; i < 16 ; i ++ ) {
libLog . fatal ( "ALERT VVVVVVVVVVVV ALERT" );
}
2022-03-18 23:33:18 +01:00
libLog . fatal ( "Library {}:{}{} already loaded with version {}, " +
2022-01-10 18:21:27 +01:00
"but a version in the range {} was requested! Thing may go horribly wrong! " +
"Requested by mod: {}, previously loaded by mod: {}" ,
2022-03-18 23:33:18 +01:00
groupId , artifactId , suffix != null ? ":" + suffix : "" , currentVer ,
2022-01-10 18:21:27 +01:00
rangeString ,
loadingModId , loadedLibraryMods . get ( artifact ));
for ( int i = 0 ; i < 16 ; i ++ ) {
libLog . fatal ( "ALERT ^^^^^^^^^^^^ ALERT" );
}
} else {
2022-03-18 23:33:18 +01:00
libLog . info ( "Attempted loading of library {}:{}{} with preferred version {}, " +
2022-01-10 18:21:27 +01:00
"but version {} was already loaded, which matched the range {}. This is not an error. " +
"Requested by mod: {}, previously loaded by mod: {}" ,
2022-03-18 23:33:18 +01:00
groupId , artifactId , suffix != null ? ":" + suffix : "" , preferredVersion ,
2022-01-10 18:21:27 +01:00
currentVer , rangeString ,
loadingModId , loadedLibraryMods . get ( artifact ));
2022-01-10 02:35:24 +01:00
}
2022-01-10 18:21:27 +01:00
return ;
2022-01-10 02:35:24 +01:00
}
val modsDir = new File ( CoreLoadingPlugin . mcDir , "mods" );
2022-03-18 23:33:18 +01:00
val mavenJarName = String . format ( "%s-%s%s.jar" , artifactId , preferredVersion , ( suffix != null ) ? ( "-" + suffix ) : "" );
2022-01-11 00:23:51 +01:00
val jarName = groupId + "-" + mavenJarName ;
val libDir = new File ( modsDir , "falsepattern" );
if ( ! libDir . exists ()) {
libDir . mkdirs ();
2022-01-10 02:35:24 +01:00
}
2022-01-11 00:23:51 +01:00
val file = new File ( libDir , jarName );
2022-01-10 02:35:24 +01:00
if ( file . exists ()) {
try {
2022-01-11 00:23:51 +01:00
addToClasspath ( file );
2022-01-10 18:21:27 +01:00
loadedLibraries . put ( artifact , preferredVersion );
2022-03-18 23:33:18 +01:00
libLog . info ( "Library {}:{}:{}{} successfully loaded from disk!" , groupId , artifactId , preferredVersion , ( suffix != null ) ? ":" + suffix : "" );
2022-01-10 02:35:24 +01:00
return ;
} catch ( RuntimeException e ) {
2022-03-18 23:33:18 +01:00
libLog . warn ( "Failed to load library {}:{}:{}{} from file! Redownloading..." , groupId , artifactId , preferredVersion , ( suffix != null ) ? ":" + suffix : "" );
2022-01-10 02:35:24 +01:00
file . delete ();
}
}
for ( var repo : mavenRepositories ) {
try {
if ( ! repo . endsWith ( "/" )) repo = repo + "/" ;
2022-01-10 18:39:15 +01:00
val url = new URL ( String . format ( "%s%s/%s/%s/%s" , repo , groupId . replace ( '.' , '/' ), artifactId , preferredVersion , mavenJarName ));
2022-01-10 02:35:24 +01:00
val connection = ( HttpsURLConnection ) url . openConnection ();
connection . setConnectTimeout ( 1500 );
connection . setReadTimeout ( 1500 );
connection . setRequestProperty ( "User-Agent" , "FalsePatternLib Downloader" );
if ( connection . getResponseCode () != 200 ) {
2022-03-18 23:33:18 +01:00
libLog . info ( "Artifact {}:{}:{}{} was not found on repo {}" , groupId , artifactId , preferredVersion , ( suffix != null ) ? ":" + suffix : "" , repo );
2022-01-10 02:35:24 +01:00
connection . disconnect ();
continue ;
}
2022-03-18 23:33:18 +01:00
libLog . info ( "Downloading {}:{}:{}{} from {}" , groupId , artifactId , preferredVersion , ( suffix != null ) ? ":" + suffix : "" , repo );
2022-01-10 02:35:24 +01:00
download ( connection . getInputStream (), file );
2022-03-18 23:33:18 +01:00
libLog . info ( "Downloaded {}:{}:{}{}" , groupId , artifactId , preferredVersion , ( suffix != null ) ? ":" + suffix : "" );
2022-01-10 18:21:27 +01:00
loadedLibraries . put ( artifact , preferredVersion );
loadedLibraryMods . put ( artifact , loadingModId );
2022-01-10 02:35:24 +01:00
addToClasspath ( file );
return ;
} catch ( IOException ignored ) {}
}
2022-03-18 23:33:18 +01:00
val errorMessage = "Failed to download library " + groupId + ":" + artifactId + ":" + preferredVersion + (( suffix != null ) ? ":" + suffix : "" ) + " from any repository! Requested by mod: " + loadingModId ;
2022-01-10 18:21:27 +01:00
libLog . fatal ( errorMessage );
throw new IllegalStateException ( errorMessage );
2022-01-10 02:35:24 +01:00
}
private static void addToClasspath ( File file ) {
try {
val cl = ( LaunchClassLoader ) FalsePatternLib . class . getClassLoader ();
cl . addURL ( file . toURI (). toURL ());
libLog . info ( "Injected file {} into classpath!" , file . getPath ());
} catch ( Exception e ) {
throw new RuntimeException ( "Failed to add library to classpath: " + file . getAbsolutePath (), e );
}
}
private static void download ( InputStream is , File target ) throws IOException {
if ( target . exists ()) return ;
var bytesRead = 0 ;
val fileOutput = new BufferedOutputStream ( new FileOutputStream ( target ));
byte [] smallBuffer = new byte [ 4096 ] ;
while (( bytesRead = is . read ( smallBuffer )) >= 0 ) {
fileOutput . write ( smallBuffer , 0 , bytesRead );
}
fileOutput . close ();
is . close ();
}
}