Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,4 @@ config/
build/
input/
/output/
modlist.html
modlist.md
manifest.json
*.mrpack
75 changes: 4 additions & 71 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,75 +12,8 @@ OR
2. Run `gradlew build`
3. Get file from path/build/libs/

## How to use - Modlist
## Detailed information

1. Put the ModListCreator file into a folder
2. Open terminal/cmd
3. Add `modlist` after `java -jar ModListCreator-<version>-fatjar.jar`
4. Set arguments listed below
5. After all arguments, set the input files (`folder/*` for whole folder)
6. Run it and wait for output file(s)

## Arguments you could use

| Argument | Output |
|------------|---------------------------------------------------------------------------------------------------------------------------------|
| no-header | Generates the file without pack name and version |
| detailed | Shows exact version of each mod |
| format | The output format to use (`txt`, `html`, or `md` (default)) |
| **output** | Defines the output path for generated files. If --pattern is set, describes a directory for output files, else a concrete file. |
| pattern | Defines the output file name pattern. %n is replaced with pack name, %v with pack version. |

## Examples
### Detailed

To use this argument, use the following command:

`$ java -jar ModListCreator-<version>-fatjar.jar --detailed`

| Without argument | With argument |
|---------------------------------|------------------------------------------|
| AIOT Botania (by MelanX) | aiotbotania-1.16.2-1.3.2.jar (by MelanX) |
| Automatic Tool Swap (by MelanX) | ToolSwap-1.16.2-1.2.0.jar (by MelanX) |
| Botania (by Vazkii) | Botania-1.16.3-409.jar (by Vazkii) |

### No Header

To use this argument, use the following command:

`$ java -jar ModListCreator-<version>-fatjar.jar --no-header`

| Without argument | With argument |
|---------------------------------------------|---------------|
| Garden of Glass (Questbook Edition) - 4.2.0 | _nothing_ |

### Pattern

To use this argument, use the following command:

`$ java -jar ModListCreator-<version>-fatjar.jar --pattern "This is %n in version %v`

> This is CaveStone in version 0.4.0

### Input

To use this argument, use the following command:

`$ java -jar ModListCreator-<version>-fatjar.jar --pattern "Name" --output output modpacks/*`

This will use the folder `modpacks` as input and tries to generate a modlist for each file in this folder.

### Output

To use this argument, use the following command:

`$ java -jar ModListCreator-<version>-fatjar.jar --output output.md`

This will generate a file called `output.md`. If you set `--pattern` argument, it will generate a folder
called `output.md`.

## Why use this instead of exported modlist?

- This tool sorts the project names alphabetically
- This tool links to the project and the author
- The official `modlist.html` contains broken links to the projects
This tool works for both, Modrinth and CurseForge modpacks.
- [Changelog](docs/changelogger.md)
- [Modlist](docs/modlist.md)
17 changes: 17 additions & 0 deletions docs/changelogger.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Changelog
## How to use

1. Put the ModListCreator file into a folder
2. Open terminal/cmd
3. Add `changelog` after `java -jar ModListCreator-<version>-fatjar.jar`
4. Set arguments listed below
5. Run it and wait for output file

## Arguments you could use

| Argument | Description |
|:----------:|--------------------------------------------------------------------------|
| **old** | Defines the old modpack zip or json file |
| **new** | Defines the new modpack zip or json file |
| **output** | Defines the output file name |
| format | The output format to use (`plain_text`, `html`, or `markdown` (default)) |
73 changes: 73 additions & 0 deletions docs/modlist.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Modlist
## How to use

1. Put the ModListCreator file into a folder
2. Open terminal/cmd
3. Add `modlist` after `java -jar ModListCreator-<version>-fatjar.jar`
4. Set arguments listed below
5. After all arguments, set the input files (`folder/*` for whole folder)
6. Run it and wait for output file(s)

## Arguments you could use

| Argument | Description |
|:------------:|---------------------------------------------------------------------------------------------------------------------------------|
| no-header | Generates the file without pack name and version |
| detailed | Shows exact version of each mod |
| format | The output format to use (`plain_text`, `html`, or `markdown` (default)) |
| **output** | Defines the output path for generated files. If --pattern is set, describes a directory for output files, else a concrete file. |
| pattern | Defines the output file name pattern. %n is replaced with pack name, %v with pack version. |

## Examples
### Detailed

To use this argument, use the following command:

`$ java -jar ModListCreator-<version>-fatjar.jar --detailed`

| Without argument | With argument |
|---------------------------------|------------------------------------------|
| AIOT Botania (by MelanX) | aiotbotania-1.16.2-1.3.2.jar (by MelanX) |
| Automatic Tool Swap (by MelanX) | ToolSwap-1.16.2-1.2.0.jar (by MelanX) |
| Botania (by Vazkii) | Botania-1.16.3-409.jar (by Vazkii) |

### No Header

To use this argument, use the following command:

`$ java -jar ModListCreator-<version>-fatjar.jar --no-header`

| Without argument | With argument |
|---------------------------------------------|---------------|
| Garden of Glass (Questbook Edition) - 4.2.0 | _nothing_ |

### Pattern

To use this argument, use the following command:

`$ java -jar ModListCreator-<version>-fatjar.jar --pattern "This is %n in version %v`

> This is CaveStone in version 0.4.0

### Input

To use this argument, use the following command:

`$ java -jar ModListCreator-<version>-fatjar.jar --pattern "Name" --output output modpacks/*`

This will use the folder `modpacks` as input and tries to generate a modlist for each file in this folder.

### Output

To use this argument, use the following command:

`$ java -jar ModListCreator-<version>-fatjar.jar --output output.md`

This will generate a file called `output.md`. If you set `--pattern` argument, it will generate a folder
called `output.md`.

## Why use this instead of exported modlist?

- This tool sorts the project names alphabetically
- This tool links to the project and the author
- The official `modlist.html` from CurseForge exports contains broken links to the projects
13 changes: 13 additions & 0 deletions src/main/java/org/moddingx/modlistcreator/Main.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,22 @@
package org.moddingx.modlistcreator;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.moddingx.modlistcreator.changelogger.Changelogger;
import org.moddingx.modlistcreator.modlist.ModListCreator;

import java.io.IOException;
import java.util.Locale;

public class Main {

public static final Gson GSON;

static {
GsonBuilder builder = new GsonBuilder();
builder.disableHtmlEscaping();
GSON = builder.create();
}

public static void main(String[] args) throws IOException {
String cmd = args.length == 0 ? "" : args[0];
Expand All @@ -15,9 +26,11 @@ public static void main(String[] args) throws IOException {
}
switch (cmd.toLowerCase(Locale.ROOT)) {
case "modlist" -> ModListCreator.run(newArgs);
case "changelog" -> Changelogger.run(newArgs);
default -> {
System.err.println("ModListCreator - Choose sub-command\n");
System.err.println(" modlist: Create a modlist file from a CurseForge or Modrinth modpack.");
System.err.println(" changelog: Create a changelog file from a CurseForge or Modrinth modpack.");
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package org.moddingx.modlistcreator.changelogger;

import org.moddingx.modlistcreator.output.OutputTarget;
import org.moddingx.modlistcreator.platform.Modpack;

import java.util.Comparator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.stream.Collectors;

public class ChangelogFormatter {

public static String format(Modpack from, Modpack to, OutputTarget.Type outputType) {
Map<String, Modpack.File> oldInfoBySlug = from.files().stream().collect(Collectors.toMap(Modpack.File::projectSlug, info -> info));
Map<String, Modpack.File> newInfoBySlug = to.files().stream().collect(Collectors.toMap(Modpack.File::projectSlug, info -> info));

boolean changedLoader = !from.minecraft().loaderVersion().equals(to.minecraft().loaderVersion());
List<Modpack.File> added = to.files().stream()
.filter(file -> !oldInfoBySlug.containsKey(file.projectSlug()))
.sorted(Comparator.comparing(o -> o.projectName().toLowerCase(Locale.ROOT)))
.toList();
List<Modpack.File> removed = from.files().stream()
.filter(file -> !newInfoBySlug.containsKey(file.projectSlug()))
.sorted(Comparator.comparing(o -> o.projectName().toLowerCase(Locale.ROOT)))
.toList();
record ChangedFile(Modpack.File oldFile, Modpack.File newFile) {}
List<ChangedFile> changed = to.files().stream()
.filter(info -> oldInfoBySlug.containsKey(info.projectSlug()))
.filter(info -> !oldInfoBySlug.get(info.projectSlug()).equals(info))
.sorted(Comparator.comparing(o -> o.projectName().toLowerCase(Locale.ROOT)))
.map(file -> new ChangedFile(oldInfoBySlug.get(file.projectSlug()), file))
.toList();

OutputTarget target = outputType.create();
target.addHeader(from.title() + " - " + from.version() + " -> " + to.version());
if (changedLoader) {
target.addSubHeader(from.minecraft().loader() + " - " + from.minecraft().loaderVersion() + " -> " + to.minecraft().loaderVersion());
}

if (added.isEmpty() && removed.isEmpty() && changed.isEmpty()) {
return target.result();
}

if (!added.isEmpty()) {
target.addSubHeader("Added");
target.beginList(false);
for (Modpack.File file : added) {
target.addListElement(target.formatLink(file.projectName(), file.projectWebsite()) + " (by " + target.formatLink(file.author(), file.authorWebsite()) + ")");
}
target.endList();
}

if (!removed.isEmpty()) {
target.addSubHeader("Removed");
target.beginList(false);
for (Modpack.File file : removed) {
target.addListElement(target.formatLink(file.projectName(), file.projectWebsite()) + " (by " + target.formatLink(file.author(), file.authorWebsite()) + ")");
}
target.endList();
}

if (!changed.isEmpty()) {
target.addSubHeader("Changed");
target.beginList(false);
for (ChangedFile changedFile : changed) {
String oldFile = target.formatLink(changedFile.oldFile.fileName(), changedFile.oldFile.fileWebsite());
String newFile = target.formatLink(changedFile.newFile.fileName(), changedFile.newFile.fileWebsite());
target.addListElement(oldFile + " -> " + newFile);
}
target.endList();
}

return target.result();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package org.moddingx.modlistcreator.changelogger;

import joptsimple.OptionException;
import joptsimple.OptionParser;
import joptsimple.OptionSet;
import joptsimple.OptionSpec;
import joptsimple.util.PathConverter;
import joptsimple.util.PathProperties;
import org.moddingx.modlistcreator.output.OutputTarget;
import org.moddingx.modlistcreator.platform.Modpack;
import org.moddingx.modlistcreator.util.EnumConverters;
import org.moddingx.modlistcreator.util.OptionUtil;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.List;

public class Changelogger {

public static void run(String[] args) throws IOException {
OptionParser options = new OptionParser();
OptionSpec<Path> specOld = options.acceptsAll(List.of("o", "old"), "Defines the old modpack zip or json file").withOptionalArg().withValuesConvertedBy(new PathConverter(PathProperties.FILE_EXISTING));
OptionSpec<Path> specNew = options.acceptsAll(List.of("n", "new"), "Defines the new modpack zip or json file").withOptionalArg().withValuesConvertedBy(new PathConverter(PathProperties.FILE_EXISTING));
OptionSpec<String> specOutput = options.accepts("output", "Defines the output file name").withOptionalArg().ofType(String.class);
OptionSpec<OutputTarget.Type> specFormat = options.accepts("format", "The output format to use").withRequiredArg().withValuesConvertedBy(EnumConverters.enumArg(OutputTarget.Type.class)).defaultsTo(OutputTarget.Type.MARKDOWN);

OptionSet set;
try {
set = options.parse(args);
if (!set.has(specOld)) OptionUtil.missing(options, specOld);
if (!set.has(specNew)) OptionUtil.missing(options, specNew);
if (!set.has(specOutput)) OptionUtil.missing(options, specOutput);
} catch (OptionException e) {
System.err.println(e.getMessage() + "\n");
options.printHelpOn(System.err);
System.exit(1);
throw new Error();
}

Modpack from = Modpack.fromPath(set.valueOf(specOld));
Modpack to = Modpack.fromPath(set.valueOf(specNew));
Path output = Paths.get(set.valueOf(specOutput));
Files.writeString(output, ChangelogFormatter.format(from, to, set.valueOf(specFormat)), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
System.exit(0);
}
}
Loading