2022-09-06 11:15:21 +02:00
package io.gitlab.jfronny.inceptum.common ;
import io.gitlab.jfronny.commons.OSUtils ;
import io.gitlab.jfronny.inceptum.common.api.MavenApi ;
import io.gitlab.jfronny.inceptum.common.model.inceptum.* ;
2022-09-06 21:20:59 +02:00
import io.gitlab.jfronny.inceptum.common.model.maven.* ;
2022-09-06 11:15:21 +02:00
import org.jetbrains.annotations.Nullable ;
import org.xml.sax.SAXException ;
import javax.xml.stream.XMLStreamException ;
import java.io.File ;
import java.io.IOException ;
import java.net.URISyntaxException ;
import java.nio.file.Files ;
import java.nio.file.Path ;
import java.util.* ;
import java.util.function.Consumer ;
import java.util.stream.Collectors ;
import java.util.stream.Stream ;
public class Updater {
2022-11-03 17:07:55 +01:00
private static final String ARTIFACTS_URL = " https://pages.frohnmeyer-wds.de/JfMods/Inceptum/artifacts/ " ;
private static final String STABLE_URL = " https://pages.frohnmeyer-wds.de/JfMods/Inceptum/stable/ " ;
public static final String PROJECT_MAVEN = " https://maven.frohnmeyer-wds.de/artifacts/ " ;
2022-09-06 11:15:21 +02:00
public static UpdateMetadata getUpdate ( ) {
2022-11-03 17:07:55 +01:00
return Updater . check ( InceptumConfig . channel , true , channel - > {
2022-09-06 11:15:21 +02:00
Utils . LOGGER . error ( " No stable version was found, switching to experimental channel " ) ;
2022-09-07 18:06:34 +02:00
InceptumConfig . channel = channel ;
InceptumConfig . saveConfig ( ) ;
2022-09-06 11:15:21 +02:00
} ) ;
}
public static void update ( UpdateMetadata source , boolean relaunch ) throws IOException , URISyntaxException {
if ( Runtime . version ( ) . feature ( ) < source . jvm ) {
throw new OutdatedException ( " A newer JVM version is required for the current build of Inceptum. Please update! " ) ;
} else if ( source . wrapperVersion > BuildMetadata . WRAPPER_VERSION ) {
throw new OutdatedException ( " The current build of Inceptum requires a newer wrapper version. Please update! " ) ;
} else if ( source . wrapperVersion < BuildMetadata . WRAPPER_VERSION ) {
throw new OutdatedException ( " The current build of Inceptum requires an older wrapper version. Please update! " ) ;
}
Utils . LOGGER . info ( " Downloading version " + source . version ) ;
WrapperConfig config = new WrapperConfig ( ) ;
config . natives = new HashMap < > ( ) ;
2022-09-06 21:20:59 +02:00
config . libraries = new LinkedHashSet < > ( ) ;
config . repositories = new LinkedHashSet < > ( source . repositories ) ;
source . natives . forEach ( ( k , v ) - > config . natives . put ( k , new LinkedHashSet < > ( v ) ) ) ;
2022-09-06 11:15:21 +02:00
2022-09-06 21:20:59 +02:00
DependencyNode node = downloadLibrary ( source . repositories , " io.gitlab.jfronny.inceptum:launcher-dist: " + source . version , config . libraries ) ;
Utils . LOGGER . info ( " Downloaded Dependencies: \ n " + node ) ;
2022-09-06 11:15:21 +02:00
List < String > currentLibraries = new LinkedList < > ( config . libraries ) ;
if ( source . natives . containsKey ( Utils . getCurrentFlavor ( ) ) ) {
2022-09-06 21:20:59 +02:00
Set < String > natives = new LinkedHashSet < > ( ) ;
2022-09-06 11:15:21 +02:00
for ( String lib : source . natives . get ( Utils . getCurrentFlavor ( ) ) ) {
downloadLibrary ( source . repositories , lib , natives ) ;
}
currentLibraries . addAll ( natives ) ;
config . natives . put ( Utils . getCurrentFlavor ( ) , natives ) ;
}
2022-11-02 00:38:04 +01:00
GC_WrapperConfig . write ( MetaHolder . WRAPPER_CONFIG_PATH , config ) ;
2022-09-06 11:15:21 +02:00
if ( relaunch ) {
Runtime . getRuntime ( ) . addShutdownHook ( new Thread ( ( ) - > {
try {
new ProcessBuilder ( OSUtils . getJvmBinary ( ) ,
" -cp " ,
buildClasspath ( currentLibraries . stream ( ) )
. map ( Path : : toString )
. collect ( Collectors . joining ( " " + File . pathSeparatorChar ) )
) . inheritIO ( ) . start ( ) ;
} catch ( IOException e ) {
Utils . LOGGER . error ( " Could not relaunch " , e ) ;
}
} ) ) ;
}
}
public static List < Path > getLaunchClasspath ( WrapperConfig wrapperConfig ) throws IOException , URISyntaxException {
2022-09-06 21:20:59 +02:00
Set < String > natives = wrapperConfig . natives . get ( Utils . getCurrentFlavor ( ) ) ;
if ( natives = = null ) natives = new LinkedHashSet < > ( ) ;
Set < String > libs = wrapperConfig . libraries ;
if ( libs = = null ) libs = new LinkedHashSet < > ( ) ;
2022-09-06 11:15:21 +02:00
boolean configChanged = false ;
for ( String lib : libs ) {
Path p = artifactToPath ( lib ) ;
if ( ! Files . exists ( p ) ) {
configChanged = true ;
downloadLibrary ( wrapperConfig . repositories , lib , libs ) ;
}
}
for ( String lib : natives ) {
Path p = artifactToPath ( lib ) ;
if ( ! Files . exists ( p ) ) {
configChanged = true ;
downloadLibrary ( wrapperConfig . repositories , lib , natives ) ;
}
}
2022-11-02 00:38:04 +01:00
if ( configChanged ) GC_WrapperConfig . write ( MetaHolder . WRAPPER_CONFIG_PATH , wrapperConfig ) ;
2022-09-06 11:15:21 +02:00
return buildClasspath ( Stream . concat ( libs . stream ( ) , natives . stream ( ) ) ) . toList ( ) ;
}
private static Stream < Path > buildClasspath ( Stream < String > libraries ) {
return libraries . map ( Updater : : artifactToPath ) ;
}
2022-09-06 21:20:59 +02:00
private static DependencyNode downloadLibrary ( Set < String > repositories , final String artifact , Set < String > libraries ) throws IOException , URISyntaxException {
2022-09-06 12:35:29 +02:00
List < Exception > exceptions = new LinkedList < > ( ) ;
2022-11-03 17:07:55 +01:00
for ( String repository : Stream . concat ( Stream . of ( PROJECT_MAVEN ) , repositories . stream ( ) ) . toList ( ) ) {
2022-09-06 11:15:21 +02:00
Pom pom ;
try {
pom = MavenApi . getPom ( repository , artifact ) ;
2022-09-06 12:35:29 +02:00
} catch ( IOException | URISyntaxException | XMLStreamException | SAXException e ) {
exceptions . add ( new Exception ( " Could not download artifact from " + repository , e ) ) ;
2022-09-06 11:15:21 +02:00
continue ;
}
2022-09-06 21:20:59 +02:00
Set < DependencyNode > dependencies = new LinkedHashSet < > ( ) ;
2022-09-06 12:35:29 +02:00
if ( pom . dependencies ! = null ) {
for ( MavenDependency dependency : pom . dependencies ) {
String mvnName = dependency . groupId + " : " + dependency . artifactId + " : " + dependency . version ;
2022-09-06 21:20:59 +02:00
dependencies . add ( downloadLibrary ( repositories , mvnName , libraries ) ) ;
2022-09-06 12:35:29 +02:00
}
2022-09-06 11:15:21 +02:00
}
2022-11-03 17:07:55 +01:00
MavenApi . downloadLibrary ( repository , pom ) ;
2022-09-06 11:15:21 +02:00
libraries . add ( artifact ) ;
2022-09-06 21:20:59 +02:00
return new DependencyNode ( pom , dependencies ) ;
2022-09-06 11:15:21 +02:00
}
2022-09-06 12:35:29 +02:00
IOException exception = new IOException ( " Could not find any repository containing the artifact " + artifact + " (searched: " + String . join ( " , " , repositories ) + " ) " ) ;
for ( Exception e : exceptions ) {
exception . addSuppressed ( e ) ;
}
throw exception ;
2022-09-06 11:15:21 +02:00
}
private static Path artifactToPath ( String artifact ) {
return MetaHolder . LIBRARIES_DIR . resolve ( MavenApi . mavenNotationToJarPath ( artifact ) ) . toAbsolutePath ( ) ;
}
2022-11-03 17:07:55 +01:00
public static @Nullable UpdateMetadata check ( UpdateChannel channel , boolean versionCompare , Consumer < UpdateChannel > channelInvalid ) {
2022-09-06 11:15:21 +02:00
try {
2022-11-03 17:07:55 +01:00
UpdateMetadata experimental = Net . downloadObject ( ARTIFACTS_URL + " version.json " , GC_UpdateMetadata : : read ) ;
2022-09-06 11:15:21 +02:00
UpdateMetadata stable = null ;
2022-11-03 17:07:55 +01:00
try {
stable = Net . downloadObject ( STABLE_URL + " version.json " , GC_UpdateMetadata : : read ) ;
} catch ( Throwable ignored ) { }
if ( stable = = null & & channel = = UpdateChannel . Stable ) {
2022-09-06 11:15:21 +02:00
channel = UpdateChannel . CI ;
channelInvalid . accept ( channel ) ;
}
UpdateMetadata info = switch ( channel ) {
case CI - > experimental ;
case Stable - > stable ;
} ;
2022-11-03 17:07:55 +01:00
if ( info . jvm > Runtime . version ( ) . feature ( ) ) {
//TODO visual indication for this
Utils . LOGGER . error ( " A newer JVM is required to use the latest inceptum version. Please update! " ) ;
2022-09-06 11:15:21 +02:00
return null ;
}
2022-11-03 17:07:55 +01:00
if ( versionCompare ) {
Utils . LOGGER . info ( " Latest version is " + info . version + " , current is " + BuildMetadata . VERSION ) ;
if ( BuildMetadata . BUILD_TIME > = info . buildTime ) {
Utils . LOGGER . info ( " Up-to-date " ) ;
return null ;
}
}
2022-09-06 11:15:21 +02:00
return info ;
2022-11-03 17:07:55 +01:00
} catch ( IOException e ) {
2022-09-06 11:15:21 +02:00
Utils . LOGGER . error ( " Could not check for updates " , e ) ;
}
return null ;
}
2022-11-03 17:07:55 +01:00
public static String getShadowJarUrl ( UpdateChannel channel ) {
return switch ( channel ) {
case CI - > ARTIFACTS_URL ;
case Stable - > STABLE_URL ;
} + " /Inceptum- " + Utils . getCurrentFlavor ( ) + " .jar " ;
2022-09-06 11:15:21 +02:00
}
}