Skip to content
This repository was archived by the owner on Sep 9, 2023. It is now read-only.

Commit 9fd2828

Browse files
list failed downloads
1 parent 128ad57 commit 9fd2828

8 files changed

Lines changed: 66 additions & 52 deletions

File tree

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,10 @@ If you want to use the "curseforge-cli.jar" file directly, follow step 2 and 3 a
3737
You can configure CurseForge CLI by editing `cf.json`. The file should be generated once the JAR file has run once.
3838
These are the options you can edit:
3939
- `directory` The directory where modpacks and profiles are stored. Default: `./curseforge-cli`
40-
- `acceptParent` Whether mods with only the parent version of a profile is accepted. For example, you can install a 1.18 mod into a 1.18.1 profile. Default: `true`
40+
- `acceptParent` Whether mods with only the parent version of a profile is accepted or not. For example, you can install a 1.18 mod into a 1.18.1 profile. Default: `true`
41+
- `suppressUpdates` Whether the update messages should be suppressed or not. Default: `false`
42+
- `silentExceptions` Whether the exception stack traces should be silenced or not. Default: `false`
43+
- `retries` The amount of retries when downloading something fails. Default: `3`
4144

4245
### Other Features
4346
If you put the JAR file together with a zip of the exported profile, CurseForge CLI will automatically install that profile to the current directory.

src/ml/northwestwind/Config.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
public class Config {
1414
public static File directory, modpackDir, profileDir, exportDir, tempDir;
15-
public static boolean acceptParentVersionMod, suppressUpdates;
15+
public static boolean acceptParentVersionMod, suppressUpdates, silentExceptions;
1616
public static long retries;
1717

1818
public static void run(String[] args) {
@@ -56,9 +56,10 @@ public static void load() {
5656
tempDir = new File(directory.getAbsolutePath() + File.separator + "tmp");
5757
acceptParentVersionMod = (boolean) json.getOrDefault("acceptParent", true);
5858
suppressUpdates = (boolean) json.getOrDefault("suppressUpdates", false);
59+
silentExceptions = (boolean) json.getOrDefault("silentExceptions", false);
5960
retries = (long) json.getOrDefault("retries", 3L);
6061
} catch (Exception e) {
61-
e.printStackTrace();
62+
if (!silentExceptions) e.printStackTrace();
6263
}
6364
}
6465

@@ -135,6 +136,7 @@ public static void save() {
135136
jo.put("acceptParent", acceptParentVersionMod);
136137
jo.put("suppressUpdates", suppressUpdates);
137138
jo.put("retries", retries);
139+
jo.put("silentExceptions", silentExceptions);
138140
PrintWriter pw = new PrintWriter("cf.json");
139141
pw.write(jo.toJSONString());
140142

@@ -143,7 +145,7 @@ public static void save() {
143145

144146
if (!directory.exists()) directory.mkdir();
145147
} catch (Exception e) {
146-
e.printStackTrace();
148+
if (!silentExceptions) e.printStackTrace();
147149
}
148150
}
149151
}

src/ml/northwestwind/Constants.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
public class Constants {
88
public static final String CURSEFORGE_API = "https://northwestwind.ml/api/curseforge/mods/";
9-
public static final String VERSION = "1.3.3";
9+
public static final String VERSION = "1.3.4";
1010
private static final String OS = System.getProperty("os.name").toLowerCase();
1111
public static final boolean IS_WINDOWS = (OS.contains("win"));
1212
public static final boolean IS_MAC = (OS.contains("mac"));

src/ml/northwestwind/Mod.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ private static void search(String[] keywords) {
4747
pw.close();
4848
System.out.println(Ansi.ansi().fg(Ansi.Color.GREEN).a("Exported search results to search.txt"));
4949
} catch (Exception e) {
50-
e.printStackTrace();
50+
if (!Config.silentExceptions) e.printStackTrace();
5151
}
5252
}
5353

src/ml/northwestwind/Modpack.java

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,7 @@
99
import java.io.*;
1010
import java.nio.file.FileSystemException;
1111
import java.rmi.NoSuchObjectException;
12-
import java.time.LocalDate;
1312
import java.time.LocalDateTime;
14-
import java.time.LocalTime;
15-
import java.time.ZoneId;
1613
import java.time.format.DateTimeFormatter;
1714
import java.util.*;
1815
import java.util.concurrent.atomic.AtomicInteger;
@@ -100,7 +97,7 @@ private static void install(String[] args) {
10097
genProfile(name, packFolder.getAbsolutePath(), thumb, getModVersion(manifestJson));
10198
System.out.println(Ansi.ansi().fg(Ansi.Color.GREEN).a("Finished download of " + name).reset());
10299
} catch (Exception e) {
103-
e.printStackTrace();
100+
if (!Config.silentExceptions) e.printStackTrace();
104101
}
105102
}
106103
}
@@ -125,13 +122,14 @@ public static void downloadMods(String folder, boolean force) {
125122
File manifest = new File(folder + File.separator + "manifest.json");
126123
JSONObject json = (JSONObject) parser.parse(new FileReader(manifest));
127124
JSONArray array = (JSONArray) json.get("files");
128-
int i = 0, suc = 0, fai = 0, ski = 0;
125+
int i = 0, suc = 0, fai = 0, ski = 0, lastSuc = 0, lastFai = 0, lastSki = 0;
126+
Map<String, String> failed = new HashMap<>();
129127
for (Object o : array) {
130128
String name = "";
129+
JSONObject obj = (JSONObject) o;
130+
String project = Long.toString((long) obj.get("projectID"));
131+
String file = Long.toString((long) obj.get("fileID"));
131132
try {
132-
JSONObject obj = (JSONObject) o;
133-
String project = Long.toString((long) obj.get("projectID"));
134-
String file = Long.toString((long) obj.get("fileID"));
135133
if (!force && mods.containsKey(project) && mods.get(project).equalsIgnoreCase(file)) ski++;
136134
else {
137135
JSONObject j = Utils.runRetry(() -> (JSONObject) Utils.readJsonFromUrl(Constants.CURSEFORGE_API + project + "/files/" + file));
@@ -148,14 +146,25 @@ public static void downloadMods(String folder, boolean force) {
148146
}
149147
} catch (Exception e) {
150148
fai++;
151-
e.printStackTrace();
149+
failed.put(project, file);
150+
if (!Config.silentExceptions) e.printStackTrace();
152151
} finally {
153-
System.out.println(Ansi.ansi().fg(Ansi.Color.GREEN).a(String.format("[%d/%d] [S/F/S: %d/%d/%d] Downloaded %s", ++i, array.size(), suc, fai, ski, name)));
152+
if (suc > lastSuc) System.out.println(Ansi.ansi().fg(Ansi.Color.GREEN).a(String.format("[%d/%d] [S/F/S: %d/%d/%d] Downloaded %s", ++i, array.size(), suc, fai, ski, name)));
153+
else if (fai > lastFai) System.out.println(Ansi.ansi().fg(Ansi.Color.RED).a(String.format("[%d/%d] [S/F/S: %d/%d/%d] Failed to download %s", ++i, array.size(), suc, fai, ski, name)));
154+
else if (ski > lastSki) System.out.println(Ansi.ansi().fg(Ansi.Color.YELLOW).a(String.format("[%d/%d] [S/F/S: %d/%d/%d] Skipped %s", ++i, array.size(), suc, fai, ski, name)));
155+
lastSuc = suc;
156+
lastFai = fai;
157+
lastSki = ski;
154158
}
155159
}
156160
System.out.println(Ansi.ansi().fg(Ansi.Color.YELLOW).a(String.format("Iterated through %d projects. %d success, %d failed, %d skipped", i, suc, fai, ski)));
161+
if (fai > 0) {
162+
System.out.println(Ansi.ansi().fg(Ansi.Color.RED).a("Mods that failed to update:").reset());
163+
for (Map.Entry<String, String> entry : failed.entrySet())
164+
System.out.println(Ansi.ansi().a("Project: ").fg(Ansi.Color.YELLOW).a(entry.getKey()).reset().a(", File: ").fg(Ansi.Color.CYAN).a(entry.getValue()).reset());
165+
}
157166
} catch (Exception e) {
158-
e.printStackTrace();
167+
if (!Config.silentExceptions) e.printStackTrace();
159168
}
160169
}
161170

@@ -264,7 +273,7 @@ private static void genProfile(String name, String path, String icon, String loa
264273
System.out.println(Ansi.ansi().fg(Ansi.Color.RED).a("Forge: ").fg(Ansi.Color.CYAN).a("https://files.minecraftforge.net/").reset());
265274
System.out.println(Ansi.ansi().fg(Ansi.Color.RED).a("Fabric: ").fg(Ansi.Color.CYAN).a("https://fabricmc.net/use/installer/").reset());
266275
} catch (Exception e) {
267-
e.printStackTrace();
276+
if (!Config.silentExceptions) e.printStackTrace();
268277
System.out.println(Ansi.ansi().fg(Ansi.Color.RED).a("Failed to generate installation profile for " + name + ". Please be reminded to make one yourself.").reset());
269278
}
270279
}
@@ -291,7 +300,7 @@ private static void delete(String[] ids) {
291300
}
292301
folders.put(name, packName);
293302
} catch (Exception e) {
294-
e.printStackTrace();
303+
if (!Config.silentExceptions) e.printStackTrace();
295304
}
296305
}
297306
if (folders.size() < 1) {
@@ -313,7 +322,7 @@ private static void delete(String[] ids) {
313322
try {
314323
FileUtils.deleteDirectory(new File(Config.modpackDir.getAbsolutePath() + File.separator + key));
315324
} catch (Exception e) {
316-
e.printStackTrace();
325+
if (!Config.silentExceptions) e.printStackTrace();
317326
failed.getAndIncrement();
318327
}
319328
});
@@ -389,7 +398,7 @@ private static void update(String[] ids, boolean force) {
389398
downloadMods(packFolder.getAbsolutePath(), force);
390399
System.out.println(Ansi.ansi().fg(Ansi.Color.GREEN).a("Finished download of " + name).reset());
391400
} catch (Exception e) {
392-
e.printStackTrace();
401+
if (!Config.silentExceptions) e.printStackTrace();
393402
}
394403
}
395404
}
@@ -436,7 +445,7 @@ private static void convert(String[] ids) {
436445
manifest.delete();
437446
System.out.println(Ansi.ansi().fg(Ansi.Color.GREEN).a("Converted modpack " + slug + " into profile."));
438447
} catch (Exception e) {
439-
e.printStackTrace();
448+
if (!Config.silentExceptions) e.printStackTrace();
440449
}
441450
}
442451
}

src/ml/northwestwind/Profile.java

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ private static void create() {
8989
System.out.println(Ansi.ansi().fg(Ansi.Color.CYAN).a("The slug of the profile is ").a(profile.getName()));
9090
} catch (Exception e) {
9191
System.err.println(Ansi.ansi().fg(Ansi.Color.RED).a("Failed to create profile " + profile));
92-
e.printStackTrace();
92+
if (!Config.silentExceptions) e.printStackTrace();
9393
}
9494
}
9595

@@ -104,7 +104,7 @@ private static void edit(String profile) {
104104
json = (JSONObject) parser.parse(new FileReader(config));
105105
} catch (IOException | ParseException e) {
106106
System.err.println(Ansi.ansi().fg(Ansi.Color.RED).a("Cannot read config of profile " + profile));
107-
e.printStackTrace();
107+
if (!Config.silentExceptions) e.printStackTrace();
108108
return;
109109
}
110110
String name = (String) json.getOrDefault("name", "");
@@ -155,7 +155,7 @@ private static void edit(String profile) {
155155
System.out.println(Ansi.ansi().fg(Ansi.Color.GREEN).a("Edited profile " + profile));
156156
} catch (Exception e) {
157157
System.err.println(Ansi.ansi().fg(Ansi.Color.RED).a("Failed to edit profile " + profile));
158-
e.printStackTrace();
158+
if (!Config.silentExceptions) e.printStackTrace();
159159
}
160160
}
161161

@@ -167,7 +167,7 @@ private static void delete(String[] names) {
167167
if (!profiles.contains(name)) throw new NoSuchObjectException("Cannot find profile with name " + name);
168168
folders.add(name);
169169
} catch (Exception e) {
170-
e.printStackTrace();
170+
if (!Config.silentExceptions) e.printStackTrace();
171171
}
172172
}
173173
if (folders.size() < 1) {
@@ -189,7 +189,7 @@ private static void delete(String[] names) {
189189
try {
190190
FileUtils.deleteDirectory(new File(Config.profileDir.getAbsolutePath() + File.separator + s));
191191
} catch (Exception e) {
192-
e.printStackTrace();
192+
if (!Config.silentExceptions) e.printStackTrace();
193193
failed.getAndIncrement();
194194
}
195195
});
@@ -212,7 +212,7 @@ private static void add(String[] ids) {
212212
try {
213213
config = (JSONObject) parser.parse(new FileReader(profileConfig));
214214
} catch (ParseException | IOException e) {
215-
e.printStackTrace();
215+
if (!Config.silentExceptions) e.printStackTrace();
216216
return;
217217
}
218218
File modsFolder = new File(Config.profileDir.getAbsolutePath() + File.separator + profile + File.separator + "mods");
@@ -253,7 +253,7 @@ private static void add(String[] ids) {
253253
String loc = Utils.downloadFile(downloadUrl, modsFolder.getAbsolutePath(), ((String) bestFile.get("fileName")).replace(".jar", "_" + id + "_" + bestFile.get("id") + ".jar"));
254254
System.out.println(Ansi.ansi().fg(Ansi.Color.GREEN).a("Downloaded " + loc));
255255
} catch (Exception e) {
256-
e.printStackTrace();
256+
if (!Config.silentExceptions) e.printStackTrace();
257257
}
258258
}
259259
System.out.println(Ansi.ansi().fg(Ansi.Color.YELLOW).a("Finished all mod downloads."));
@@ -288,7 +288,7 @@ private static void remove(String[] ids) {
288288
}
289289
files.put(name + ".jar", modName);
290290
} catch (Exception e) {
291-
e.printStackTrace();
291+
if (!Config.silentExceptions) e.printStackTrace();
292292
}
293293
}
294294
if (files.size() < 1) {
@@ -310,7 +310,7 @@ private static void remove(String[] ids) {
310310
try {
311311
new File(Config.profileDir + File.separator + profile + File.separator + "mods" + File.separator + key).delete();
312312
} catch (Exception e) {
313-
e.printStackTrace();
313+
if (!Config.silentExceptions) e.printStackTrace();
314314
failed.getAndIncrement();
315315
}
316316
});
@@ -332,15 +332,15 @@ private static void export(String[] args) {
332332
try {
333333
config = (JSONObject) parser.parse(new FileReader(profileConfig));
334334
} catch (ParseException | IOException e) {
335-
e.printStackTrace();
335+
if (!Config.silentExceptions) e.printStackTrace();
336336
return;
337337
}
338338
File modsFolder = new File(Config.profileDir.getAbsolutePath() + File.separator + profile + File.separator + "mods");
339339
File modsCopy = new File(modsFolder.getParent() + File.separator + "mods_copy");
340340
try {
341341
FileUtils.copyDirectory(modsFolder, modsCopy);
342342
} catch (Exception e) {
343-
e.printStackTrace();
343+
if (!Config.silentExceptions) e.printStackTrace();
344344
return;
345345
}
346346
Map<Integer, Map.Entry<Integer, String>> mods = Config.loadMods(profile);
@@ -382,7 +382,7 @@ private static void export(String[] args) {
382382
pw.close();
383383
} catch (Exception e) {
384384
System.err.println(Ansi.ansi().fg(Ansi.Color.RED).a("Failed to create manifest.json."));
385-
e.printStackTrace();
385+
if (!Config.silentExceptions) e.printStackTrace();
386386
return;
387387
}
388388
List<String> overridesDir = new ArrayList<>(), overridesFile = new ArrayList<>();
@@ -409,7 +409,7 @@ private static void export(String[] args) {
409409
}
410410
} catch (Exception e) {
411411
System.out.println(Ansi.ansi().fg(Ansi.Color.RED).a("Failed to copy files to overrides."));
412-
e.printStackTrace();
412+
if (!Config.silentExceptions) e.printStackTrace();
413413
return;
414414
}
415415
String zipName = config.get("name") + "-" + version + ".zip";
@@ -423,7 +423,7 @@ private static void export(String[] args) {
423423
fos.close();
424424
} catch (Exception e) {
425425
System.out.println(Ansi.ansi().fg(Ansi.Color.RED).a("Failed to zip everything."));
426-
e.printStackTrace();
426+
if (!Config.silentExceptions) e.printStackTrace();
427427
return;
428428
}
429429
try {
@@ -432,7 +432,7 @@ private static void export(String[] args) {
432432
FileUtils.deleteDirectory(modsCopy);
433433
} catch (Exception e) {
434434
System.out.println(Ansi.ansi().fg(Ansi.Color.YELLOW).a("Failed to clean up, but we can keep running."));
435-
e.printStackTrace();
435+
if (!Config.silentExceptions) e.printStackTrace();
436436
}
437437
System.out.println(Ansi.ansi().fg(Ansi.Color.GREEN).a("Exported profile " + profile + " to " + zipName));
438438
}
@@ -452,7 +452,7 @@ private static void update(String[] args) {
452452
try {
453453
config = (JSONObject) parser.parse(new FileReader(profileConfig));
454454
} catch (ParseException | IOException e) {
455-
e.printStackTrace();
455+
if (!Config.silentExceptions) e.printStackTrace();
456456
return;
457457
}
458458
Map<Integer, Map.Entry<Integer, String>> mods = Config.loadMods(profile);
@@ -488,7 +488,7 @@ private static void update(String[] args) {
488488
}
489489
} catch (Exception e) {
490490
System.out.println(Ansi.ansi().fg(Ansi.Color.RED).a("Having trouble with mod " + entry.getKey()));
491-
e.printStackTrace();
491+
if (!Config.silentExceptions) e.printStackTrace();
492492
}
493493
}
494494
if (!doUpdate) {
@@ -503,7 +503,7 @@ private static void update(String[] args) {
503503
pw.close();
504504
System.out.println(Ansi.ansi().fg(Ansi.Color.GREEN).a("Exported mods with update available to mod_updates.txt"));
505505
} catch (Exception e) {
506-
e.printStackTrace();
506+
if (!Config.silentExceptions) e.printStackTrace();
507507
}
508508
}
509509
return;
@@ -553,16 +553,16 @@ private static void update(String[] args) {
553553
System.out.println(Ansi.ansi().fg(Ansi.Color.GREEN).a("Downloaded " + loc));
554554
}
555555
} catch (Exception e) {
556-
e.printStackTrace();
556+
if (!Config.silentExceptions) e.printStackTrace();
557557
}
558558
}
559559
}
560560

561561
private static void importProf(String[] paths) {
562-
importProf(paths, false, false);
562+
importProf(paths, false);
563563
}
564564

565-
private static boolean importProf(String[] paths, boolean silent, boolean toCD) {
565+
private static boolean importProf(String[] paths, boolean toCD) {
566566
if (toCD && paths.length > 1) return false;
567567
boolean imported = false;
568568
for (String path : paths) {
@@ -620,7 +620,7 @@ private static boolean importProf(String[] paths, boolean silent, boolean toCD)
620620
System.out.println(Ansi.ansi().fg(Ansi.Color.GREEN).a("Converted modpack " + slug + " into profile."));
621621
imported = true;
622622
} catch (Exception e) {
623-
if (!silent) e.printStackTrace();
623+
if (!Config.silentExceptions) e.printStackTrace();
624624
}
625625
try {
626626
if (Config.tempDir.exists() && Config.tempDir.isDirectory()) FileUtils.deleteDirectory(Config.tempDir);
@@ -633,7 +633,7 @@ private static boolean importProf(String[] paths, boolean silent, boolean toCD)
633633
public static boolean findAndImport() {
634634
try {
635635
File currentDir = new File(Constants.ABSOLUTE_PATH);
636-
return importProf(currentDir.list((dir, name) -> name.endsWith(".zip")), true, true);
636+
return importProf(currentDir.list((dir, name) -> name.endsWith(".zip")), true);
637637
} catch (Exception ignored) {
638638
}
639639
return false;

0 commit comments

Comments
 (0)