@@ -26,6 +26,7 @@ public static void run(String[] args) {
2626 args = Arrays .stream (args ).skip (2 ).toArray (String []::new );
2727 if (cmd .equalsIgnoreCase ("add" )) add (args );
2828 else if (cmd .equalsIgnoreCase ("remove" )) remove (args );
29+ else if (cmd .equalsIgnoreCase ("update" )) update (args );
2930 else if (cmd .equalsIgnoreCase ("export" )) export (args );
3031 else if (cmd .equalsIgnoreCase ("edit" )) edit (args [0 ]);
3132 else if (cmd .equalsIgnoreCase ("delete" )) delete (args );
@@ -219,14 +220,14 @@ private static void add(String[] ids) {
219220 JSONObject json = (JSONObject ) Utils .readJsonFromUrl (Constants .CURSEFORGE_API + id );
220221 if (json == null || ((long ) ((JSONObject ) json .get ("categorySection" )).get ("gameCategoryId" )) != 6 ) throw new Exception ("The ID " +id +" does not represent a mod." );
221222 JSONArray files = (JSONArray ) Utils .readJsonFromUrl (Constants .CURSEFORGE_API + id + "/files" );
222- files .sort ((a , b ) -> (int ) ((long ) ((JSONObject ) b ).get ("id" ) - (long ) ((JSONObject ) a ).get ("id" )));
223223 List f = (List ) files .stream ().filter (o -> {
224224 JSONArray versions = (JSONArray ) ((JSONObject ) o ).get ("gameVersion" );
225225 return versions .get (0 ).equals (config .get ("mcVer" )) && ((String ) versions .get (1 )).equalsIgnoreCase ((String ) config .get ("launcher" ));
226226 }).collect (Collectors .toList ());
227+ f .sort ((a , b ) -> (int ) ((long ) ((JSONObject ) b ).get ("id" ) - (long ) ((JSONObject ) a ).get ("id" )));
227228 if (f .size () < 1 ) throw new Exception ("No available file of " + id + " found for this profile." );
228- JSONObject bestFile = (JSONObject ) Utils . getLast ( f );
229- String downloadUrl = (( String ) bestFile .get ("downloadUrl" )). replaceFirst ( "edge" , "media " );
229+ JSONObject bestFile = (JSONObject ) f . get ( 0 );
230+ String downloadUrl = (String ) bestFile .get ("downloadUrl" );
230231 if (mods .containsKey (Integer .parseInt (id ))) new File (modsFolder .getPath () + File .separator + mods .get (Integer .parseInt (id )).getValue () + "_" + id + "_" + mods .get (Integer .parseInt (id )).getKey () + ".jar" ).delete ();
231232 String loc = Utils .downloadFile (downloadUrl , modsFolder .getPath (), ((String ) bestFile .get ("fileName" )).replace (".jar" , "_" + id + "_" + bestFile .get ("id" ) + ".jar" ));
232233 System .out .println (Ansi .ansi ().fg (Ansi .Color .GREEN ).a ("Downloaded " + loc ));
@@ -312,6 +313,14 @@ private static void export(String[] args) {
312313 e .printStackTrace ();
313314 return ;
314315 }
316+ File modsFolder = new File (Config .profileDir .getPath () + File .separator + profile + File .separator + "mods" );
317+ File modsCopy = new File (modsFolder .getParent () + File .separator + "mods_copy" );
318+ try {
319+ FileUtils .copyDirectory (modsFolder , modsCopy );
320+ } catch (Exception e ) {
321+ e .printStackTrace ();
322+ return ;
323+ }
315324 Map <Integer , Map .Entry <Integer , String >> mods = Config .loadMods (profile );
316325 JSONArray files = new JSONArray ();
317326 for (Map .Entry <Integer , Map .Entry <Integer , String >> mod : mods .entrySet ()) {
@@ -320,6 +329,7 @@ private static void export(String[] args) {
320329 jo .put ("fileID" , mod .getValue ().getKey ());
321330 jo .put ("required" , true );
322331 files .add (jo );
332+ new File (modsCopy .getPath () + File .separator + mod .getValue ().getValue () + "_" + mod .getKey () + "_" + mod .getValue ().getKey () + ".jar" ).delete ();
323333 }
324334 System .out .println ("What is the version of this export?" );
325335 Scanner scanner = new Scanner (System .in );
@@ -369,6 +379,11 @@ private static void export(String[] args) {
369379 try {
370380 for (String dir : overridesDir ) FileUtils .copyDirectoryToDirectory (new File (dir ), overridesFolder );
371381 for (String file : overridesFile ) FileUtils .copyFileToDirectory (new File (file ), overridesFolder );
382+ if (modsCopy .listFiles ().length > 0 ) {
383+ File overrideMods = new File (overridesFolder .getPath () + File .separator + "mods" );
384+ if (!overrideMods .exists () || !overrideMods .isDirectory ()) overrideMods .mkdir ();
385+ FileUtils .copyDirectory (modsCopy , overrideMods );
386+ }
372387 } catch (Exception e ) {
373388 System .out .println (Ansi .ansi ().fg (Ansi .Color .RED ).a ("Failed to copy files to overrides." ));
374389 e .printStackTrace ();
@@ -398,6 +413,90 @@ private static void export(String[] args) {
398413 System .out .println (Ansi .ansi ().fg (Ansi .Color .GREEN ).a ("Exported profile " + profile + " to " + zipName ));
399414 }
400415
416+ private static void update (String [] args ) {
417+ String profile = args [0 ];
418+ if (!Config .loadProfiles ().contains (profile )) {
419+ System .out .println (Ansi .ansi ().fg (Ansi .Color .RED ).a ("Profile " + profile + " does not exist." ));
420+ return ;
421+ }
422+ File profileConfig = new File (Config .profileDir .getPath () + File .separator + profile + File .separator + "profile.json" );
423+ if (!profileConfig .exists () || !profileConfig .isFile ()) {
424+ System .err .println (Ansi .ansi ().fg (Ansi .Color .RED ).a ("Profile config is missing!" ));
425+ return ;
426+ }
427+ JSONObject config ;
428+ try {
429+ config = (JSONObject ) parser .parse (new FileReader (profileConfig ));
430+ } catch (ParseException | IOException e ) {
431+ e .printStackTrace ();
432+ return ;
433+ }
434+ Map <Integer , Map .Entry <Integer , String >> mods = Config .loadMods (profile );
435+ if (args .length - 1 < 1 ) {
436+ System .out .println (Ansi .ansi ().fg (Ansi .Color .CYAN ).a ("Mods with update available:" ));
437+ Map <Integer , String > updatables = new HashMap <>();
438+ for (Map .Entry <Integer , Map .Entry <Integer , String >> entry : mods .entrySet ()) {
439+ try {
440+ JSONObject json = (JSONObject ) Utils .readJsonFromUrl (Constants .CURSEFORGE_API + entry .getKey ());
441+ if (json == null || ((long ) ((JSONObject ) json .get ("categorySection" )).get ("gameCategoryId" )) != 6 ) throw new Exception ("The ID " +entry .getKey ()+" does not represent a mod." );
442+ JSONArray files = (JSONArray ) Utils .readJsonFromUrl (Constants .CURSEFORGE_API + entry .getKey () + "/files" );
443+ List f = (List ) files .stream ().filter (o -> {
444+ JSONArray versions = (JSONArray ) ((JSONObject ) o ).get ("gameVersion" );
445+ return versions .get (0 ).equals (config .get ("mcVer" )) && ((String ) versions .get (1 )).equalsIgnoreCase ((String ) config .get ("launcher" ));
446+ }).collect (Collectors .toList ());
447+ f .sort ((a , b ) -> (int ) ((long ) ((JSONObject ) b ).get ("id" ) - (long ) ((JSONObject ) a ).get ("id" )));
448+ if (f .size () < 1 ) throw new Exception ("No available file of " + entry .getKey () + " found for this profile." );
449+ JSONObject fjson = (JSONObject ) f .get (0 );
450+ if (((long ) fjson .get ("id" )) > entry .getValue ().getKey ()) {
451+ System .out .println (Ansi .ansi ().fg (Ansi .Color .YELLOW ).a (entry .getValue ().getValue ()).reset ().a (" | " ).fg (Ansi .Color .MAGENTA ).a (entry .getKey ()));
452+ updatables .put (entry .getKey (), entry .getValue ().getValue ());
453+ }
454+ } catch (Exception e ) {
455+ e .printStackTrace ();
456+ }
457+ }
458+ try {
459+ PrintWriter pw = new PrintWriter (profileConfig .getParent () + File .separator + "mod_updates.txt" );
460+ for (Map .Entry <Integer , String > entry : updatables .entrySet ()) pw .println (entry .getValue () + " = " + entry .getKey ());
461+ pw .println ();
462+ pw .println ("You can update these mods of a profile with the following command: " );
463+ String cmd = "curseforge profile add <profile> " + mods .keySet ().stream ().map (String ::valueOf ).collect (Collectors .joining (" " ));
464+ pw .println (cmd );
465+ pw .close ();
466+ System .out .println (Ansi .ansi ().fg (Ansi .Color .GREEN ).a ("Exported mods with update available to search.txt" ));
467+ } catch (Exception e ) {
468+ e .printStackTrace ();
469+ }
470+ return ;
471+ }
472+
473+ for (String id : Arrays .stream (args ).skip (1 ).toArray (String []::new )) {
474+ try {
475+ if (!Utils .isInteger (id )) throw new Exception ("Mod ID is invalid: " +id );
476+ JSONObject json = (JSONObject ) Utils .readJsonFromUrl (Constants .CURSEFORGE_API + id );
477+ if (json == null || ((long ) ((JSONObject ) json .get ("categorySection" )).get ("gameCategoryId" )) != 6 ) throw new Exception ("The ID " +id +" does not represent a mod." );
478+ JSONArray files = (JSONArray ) Utils .readJsonFromUrl (Constants .CURSEFORGE_API + id + "/files" );
479+ List f = (List ) files .stream ().filter (o -> {
480+ JSONArray versions = (JSONArray ) ((JSONObject ) o ).get ("gameVersion" );
481+ return versions .get (0 ).equals (config .get ("mcVer" )) && ((String ) versions .get (1 )).equalsIgnoreCase ((String ) config .get ("launcher" ));
482+ }).collect (Collectors .toList ());
483+ f .sort ((a , b ) -> (int ) ((long ) ((JSONObject ) b ).get ("id" ) - (long ) ((JSONObject ) a ).get ("id" )));
484+ if (f .size () < 1 ) throw new Exception ("No available file of " + id + " found for this profile." );
485+ JSONObject bestFile = (JSONObject ) f .get (0 );
486+ Map .Entry <Integer , String > entry = mods .get (Integer .parseInt (id ));
487+ if (((long ) bestFile .get ("id" )) > entry .getKey ()) {
488+ System .out .println (Ansi .ansi ().fg (Ansi .Color .YELLOW ).a (entry .getValue ()).reset ().a (" | " ).fg (Ansi .Color .MAGENTA ).a (entry .getKey ()));
489+ String downloadUrl = ((String ) bestFile .get ("downloadUrl" )).replaceFirst ("edge" , "media" );
490+ if (mods .containsKey (Integer .parseInt (id ))) new File (profileConfig .getParent () + File .separator + "mods" + File .separator + entry .getValue () + "_" + id + "_" + entry .getKey () + ".jar" ).delete ();
491+ String loc = Utils .downloadFile (downloadUrl , profileConfig .getParent () + File .separator + "mods" , ((String ) bestFile .get ("fileName" )).replace (".jar" , "_" + id + "_" + bestFile .get ("id" ) + ".jar" ));
492+ System .out .println (Ansi .ansi ().fg (Ansi .Color .GREEN ).a ("Downloaded " + loc ));
493+ }
494+ } catch (Exception e ) {
495+ e .printStackTrace ();
496+ }
497+ }
498+ }
499+
401500 public static void printHelp (String prefix ) {
402501 System .out .println (prefix + "profile: Commands for custom profiles." );
403502 System .out .println (prefix + "\t create: Create a profile." );
@@ -414,5 +513,8 @@ public static void printHelp(String prefix) {
414513 System .out .println (prefix + "\t remove: Remove a mod from the profile." );
415514 System .out .println (prefix + "\t \t arg <profile>: Name of the profile to target." );
416515 System .out .println (prefix + "\t \t arg <ID>: The ID of the mod." );
516+ System .out .println (prefix + "\t update: Update mods in the profile." );
517+ System .out .println (prefix + "\t \t arg <profile>: Name of the profile to target." );
518+ System .out .println (prefix + "\t \t arg [ID]: The ID of mods. Omit to check for updates." );
417519 }
418520}
0 commit comments