4343import java .util .Arrays ;
4444import java .util .Map ;
4545import java .util .Scanner ;
46+ import java .util .jar .Attributes ;
47+ import java .util .jar .JarFile ;
4648
4749public final class FoxLoaderUpdater extends MavenUpdater {
4850 private static final String ALL_LOADERS_URL = "https://cdn.fox2code.com/maven/foxloader-version-map.json" ;
@@ -75,19 +77,72 @@ protected String findLatestVersion() throws IOException {
7577
7678 @ Override
7779 protected void doUpdate () throws IOException {
80+ updateFoxLoaderImpl (this .latestMavenVersion , this .getUrlForLatestJar (), null );
81+ }
82+
83+ public static boolean updateFoxLoaderFromMod (File file ) throws IOException {
84+ if (!ModLoaderInit .Internal .isInPreBootupStage ()) {
85+ throw new IllegalStateException ("Cannot be called at runtime" );
86+ }
87+ String fileName = file .getName ();
88+ if (!((fileName .startsWith ("foxloader-" ) ||
89+ fileName .startsWith ("loader-" )) &&
90+ fileName .endsWith (".jar" ))) {
91+ return false ;
92+ }
93+ String foxLoaderVersion , mainClass ;
94+ try (JarFile jarFile = new JarFile (file )) {
95+ Attributes attributes = jarFile .getManifest ().getMainAttributes ();
96+ foxLoaderVersion = attributes .getValue ("FoxLoader-Version" );
97+ mainClass = attributes .getValue ("Main-Class" );
98+ } catch (IOException e ) {
99+ return false ;
100+ }
101+ // Allow FoxLoader when it goes through the installer, but not when it is from a server only jar.
102+ if (foxLoaderVersion == null || foxLoaderVersion .isEmpty () ||
103+ mainClass == null || !mainClass .startsWith ("com.fox2code.foxloader." )) {
104+ if (mainClass != null && mainClass .startsWith ("com.fox2code.foxloader.launcher." )) {
105+ throw new IOException ("Cannot upgrade from a server only jar. (File: " + fileName + ")" );
106+ }
107+ return false ;
108+ }
109+ ModLoaderInit .getModLoaderLogger ().info ("Found FoxLoader " +
110+ foxLoaderVersion + " in the mods folder: " + fileName );
111+ if (FoxLauncher .DEV_MODE || FoxLauncher .DEVELOPING_FOXLOADER ) {
112+ ModLoaderInit .getModLoaderLogger ().info (
113+ "Cannot update in a development environment, shutting down..." );
114+ return true ;
115+ }
116+ if (foxLoaderVersion .equals (BuildConfig .FOXLOADER_VERSION )) {
117+ ModLoaderInit .getModLoaderLogger ().info (
118+ "Cannot update to the same version as itself, shutting down..." );
119+ return true ;
120+ }
121+ ModLoaderInit .getModLoaderLogger ().info ("Updating to FoxLoader " + foxLoaderVersion );
122+ updateFoxLoaderImpl (foxLoaderVersion , null , file );
123+ ModLoaderInit .getModLoaderLogger ().info ("Update completed, shutting down..." );
124+ return true ;
125+ }
126+
127+ private static void updateFoxLoaderImpl (String updateVersion , String remoteFoxLoaderJar , File localFoxLoaderJar ) throws IOException {
128+ if (remoteFoxLoaderJar == null && localFoxLoaderJar == null ) {
129+ throw new IOException ("Both remoteFoxLoaderJar and localFoxLoaderJar are null..." );
130+ }
78131 File dest = null ;
79132 String [] args ;
80133 LauncherType launcherType = FoxLauncher .getLauncherType ();
81134 ModLoaderInit .getModLoaderLogger ().info (
82- "Updating to " + this . latestMavenVersion + " from " + launcherType + " launcher" );
135+ "Updating to " + updateVersion + " from " + launcherType + " launcher" );
83136 switch (launcherType ) {
84- default :
85- return ;
86137 case MMC_LIKE :
87138 File libraries = ModLoaderInit .getModContainer ("foxloader" ).getModInfo ().file .getParentFile ();
88- dest = new File (libraries , "foxloader-" + this .latestMavenVersion + ".jar" );
139+ dest = new File (libraries , "foxloader-" + updateVersion + ".jar" );
140+ // fall-through
89141 case VANILLA_LIKE :
90142 args = new String []{null , "-jar" , null , "--update" , launcherType .name ()};
143+ break ;
144+ default :
145+ return ;
91146 }
92147 if (dest == null ) {
93148 File updateTmp = new File (ModLoader .getConfigFolder (), "update-tmp" );
@@ -96,18 +151,21 @@ protected void doUpdate() throws IOException {
96151 .warning ("Unable to create update tmp folder." );
97152 return ;
98153 }
99- dest = new File (updateTmp , "foxloader-" + this . latestMavenVersion + ".jar" );
154+ dest = new File (updateTmp , "foxloader-" + updateVersion + ".jar" );
100155 }
101- if (BuildConfig .FOXLOADER_VERSION .equals (this . latestMavenVersion ) &&
156+ if (BuildConfig .FOXLOADER_VERSION .equals (updateVersion ) &&
102157 FoxLauncher .getLauncherType () != LauncherType .BIN ) {
103158 // Can happen if wrongly installed
104159 if (!dest .equals (FoxLauncher .foxLoaderFile )) {
105160 Files .copy (FoxLauncher .foxLoaderFile .toPath (), dest .toPath (),
106161 StandardCopyOption .REPLACE_EXISTING );
107162 }
163+ } else if (localFoxLoaderJar != null && localFoxLoaderJar .exists ()) {
164+ Files .copy (localFoxLoaderJar .toPath (), dest .toPath (),
165+ StandardCopyOption .REPLACE_EXISTING );
108166 } else {
109167 try (FileOutputStream fileOutputStream = new FileOutputStream (dest )) {
110- NetUtils .downloadTo (this . getUrlForLatestJar () , fileOutputStream );
168+ NetUtils .downloadTo (remoteFoxLoaderJar , fileOutputStream );
111169 }
112170 }
113171 args [0 ] = Platform .getPlatform ().javaBin .getPath ();
0 commit comments