@@ -41,21 +41,22 @@ public final class ModManager {
|
|||||||
LocalModFile fromFile(ModManager modManager, Path modFile, FileSystem fs) throws IOException, JsonParseException;
|
LocalModFile fromFile(ModManager modManager, Path modFile, FileSystem fs) throws IOException, JsonParseException;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Map<String, List<Pair<ModMetadataReader, Set<ModLoaderType>>>> READERS;
|
private static final Map<String, List<Pair<ModMetadataReader, ModLoaderType>>> READERS;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
var map = new HashMap<String, List<Pair<ModMetadataReader, Set<ModLoaderType>>>>();
|
var map = new HashMap<String, List<Pair<ModMetadataReader, ModLoaderType>>>();
|
||||||
var zipReaders = List.<Pair<ModMetadataReader, Set<ModLoaderType>>>of(
|
var zipReaders = List.<Pair<ModMetadataReader, ModLoaderType>>of(
|
||||||
pair(ForgeNewModMetadata::fromFile, EnumSet.of(ModLoaderType.FORGE, ModLoaderType.NEO_FORGED)),
|
pair(ForgeNewModMetadata::fromForgeFile, ModLoaderType.FORGE),
|
||||||
pair(ForgeOldModMetadata::fromFile, EnumSet.of(ModLoaderType.FORGE)),
|
pair(ForgeNewModMetadata::fromNeoForgeFile, ModLoaderType.NEO_FORGED),
|
||||||
pair(FabricModMetadata::fromFile, EnumSet.of(ModLoaderType.FABRIC)),
|
pair(ForgeOldModMetadata::fromFile, ModLoaderType.FORGE),
|
||||||
pair(QuiltModMetadata::fromFile, EnumSet.of(ModLoaderType.QUILT)),
|
pair(FabricModMetadata::fromFile, ModLoaderType.FABRIC),
|
||||||
pair(PackMcMeta::fromFile, EnumSet.of(ModLoaderType.PACK))
|
pair(QuiltModMetadata::fromFile, ModLoaderType.QUILT),
|
||||||
|
pair(PackMcMeta::fromFile, ModLoaderType.PACK)
|
||||||
);
|
);
|
||||||
|
|
||||||
map.put("zip", zipReaders);
|
map.put("zip", zipReaders);
|
||||||
map.put("jar", zipReaders);
|
map.put("jar", zipReaders);
|
||||||
map.put("litemod", List.of(pair(LiteModMetadata::fromFile, EnumSet.of(ModLoaderType.LITE_LOADER))));
|
map.put("litemod", List.of(pair(LiteModMetadata::fromFile, ModLoaderType.LITE_LOADER)));
|
||||||
|
|
||||||
READERS = map;
|
READERS = map;
|
||||||
}
|
}
|
||||||
@@ -102,7 +103,7 @@ public final class ModManager {
|
|||||||
String fileName = StringUtils.removeSuffix(FileUtils.getName(file), DISABLED_EXTENSION, OLD_EXTENSION);
|
String fileName = StringUtils.removeSuffix(FileUtils.getName(file), DISABLED_EXTENSION, OLD_EXTENSION);
|
||||||
String extension = fileName.substring(fileName.lastIndexOf(".") + 1);
|
String extension = fileName.substring(fileName.lastIndexOf(".") + 1);
|
||||||
|
|
||||||
List<Pair<ModMetadataReader, Set<ModLoaderType>>> readersMap = READERS.get(extension);
|
List<Pair<ModMetadataReader, ModLoaderType>> readersMap = READERS.get(extension);
|
||||||
if (readersMap == null) {
|
if (readersMap == null) {
|
||||||
// Is not a mod file.
|
// Is not a mod file.
|
||||||
return;
|
return;
|
||||||
@@ -113,16 +114,8 @@ public final class ModManager {
|
|||||||
var supportedReaders = new ArrayList<ModMetadataReader>();
|
var supportedReaders = new ArrayList<ModMetadataReader>();
|
||||||
var unsupportedReaders = new ArrayList<ModMetadataReader>();
|
var unsupportedReaders = new ArrayList<ModMetadataReader>();
|
||||||
|
|
||||||
for (Pair<ModMetadataReader, Set<ModLoaderType>> reader : readersMap) {
|
for (Pair<ModMetadataReader, ModLoaderType> reader : readersMap) {
|
||||||
boolean supported = false;
|
if (modLoaderTypes.contains(reader.getValue())) {
|
||||||
for (ModLoaderType type : reader.getValue()) {
|
|
||||||
if (modLoaderTypes.contains(type)) {
|
|
||||||
supported = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (supported) {
|
|
||||||
supportedReaders.add(reader.getKey());
|
supportedReaders.add(reader.getKey());
|
||||||
} else {
|
} else {
|
||||||
unsupportedReaders.add(reader.getKey());
|
unsupportedReaders.add(reader.getKey());
|
||||||
|
|||||||
@@ -110,23 +110,33 @@ public final class ForgeNewModMetadata {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final int ACC_FORGE = 0x01;
|
public static LocalModFile fromForgeFile(ModManager modManager, Path modFile, FileSystem fs) throws IOException {
|
||||||
|
return fromFile(modManager, modFile, fs, ModLoaderType.FORGE);
|
||||||
|
}
|
||||||
|
|
||||||
private static final int ACC_NEO_FORGED = 0x02;
|
public static LocalModFile fromNeoForgeFile(ModManager modManager, Path modFile, FileSystem fs) throws IOException {
|
||||||
|
return fromFile(modManager, modFile, fs, ModLoaderType.NEO_FORGED);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static LocalModFile fromFile(ModManager modManager, Path modFile, FileSystem fs, ModLoaderType modLoaderType) throws IOException {
|
||||||
|
if (modLoaderType != ModLoaderType.FORGE && modLoaderType != ModLoaderType.NEO_FORGED) {
|
||||||
|
throw new IOException("Invalid mod loader: " + modLoaderType);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (modLoaderType == ModLoaderType.NEO_FORGED) {
|
||||||
|
try {
|
||||||
|
return fromFile0("META-INF/neoforge.mods.toml", modLoaderType, modManager, modFile, fs);
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static LocalModFile fromFile(ModManager modManager, Path modFile, FileSystem fs) throws IOException, JsonParseException {
|
|
||||||
try {
|
try {
|
||||||
return fromFile0("META-INF/mods.toml", ACC_FORGE | ACC_NEO_FORGED, ModLoaderType.FORGE, modManager, modFile, fs);
|
return fromFile0("META-INF/mods.toml", modLoaderType, modManager, modFile, fs);
|
||||||
} catch (Exception ignored) {
|
} catch (Exception ignored) {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return fromFile0("META-INF/neoforge.mods.toml", ACC_NEO_FORGED, ModLoaderType.NEO_FORGED, modManager, modFile, fs);
|
return fromEmbeddedMod(modManager, modFile, fs, modLoaderType);
|
||||||
} catch (Exception ignored) {
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
return fromEmbeddedMod(modManager, modFile, fs);
|
|
||||||
} catch (Exception ignored) {
|
} catch (Exception ignored) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,8 +144,8 @@ public final class ForgeNewModMetadata {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static LocalModFile fromFile0(
|
private static LocalModFile fromFile0(
|
||||||
String tomlPath, int loaderACC,
|
String tomlPath,
|
||||||
ModLoaderType defaultLoader,
|
ModLoaderType modLoaderType,
|
||||||
ModManager modManager,
|
ModManager modManager,
|
||||||
Path modFile,
|
Path modFile,
|
||||||
FileSystem fs) throws IOException, JsonParseException {
|
FileSystem fs) throws IOException, JsonParseException {
|
||||||
@@ -158,7 +168,7 @@ public final class ForgeNewModMetadata {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ModLoaderType type = analyzeLoader(toml, mod.getModId(), loaderACC, defaultLoader);
|
ModLoaderType type = analyzeLoader(toml, mod.getModId(), modLoaderType);
|
||||||
|
|
||||||
return new LocalModFile(modManager, modManager.getLocalMod(mod.getModId(), type), modFile, mod.getDisplayName(), new LocalModFile.Description(mod.getDescription()),
|
return new LocalModFile(modManager, modManager.getLocalMod(mod.getModId(), type), modFile, mod.getDisplayName(), new LocalModFile.Description(mod.getDescription()),
|
||||||
mod.getAuthors(), jarVersion == null ? mod.getVersion() : mod.getVersion().replace("${file.jarVersion}", jarVersion), "",
|
mod.getAuthors(), jarVersion == null ? mod.getVersion() : mod.getVersion().replace("${file.jarVersion}", jarVersion), "",
|
||||||
@@ -166,7 +176,7 @@ public final class ForgeNewModMetadata {
|
|||||||
metadata.getLogoFile());
|
metadata.getLogoFile());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static LocalModFile fromEmbeddedMod(ModManager modManager, Path modFile, FileSystem fs) throws IOException {
|
private static LocalModFile fromEmbeddedMod(ModManager modManager, Path modFile, FileSystem fs, ModLoaderType modLoaderType) throws IOException {
|
||||||
Path manifestFile = fs.getPath("META-INF/MANIFEST.MF");
|
Path manifestFile = fs.getPath("META-INF/MANIFEST.MF");
|
||||||
if (!Files.isRegularFile(manifestFile))
|
if (!Files.isRegularFile(manifestFile))
|
||||||
throw new IOException("Missing MANIFEST.MF in file " + manifestFile);
|
throw new IOException("Missing MANIFEST.MF in file " + manifestFile);
|
||||||
@@ -190,7 +200,7 @@ public final class ForgeNewModMetadata {
|
|||||||
try {
|
try {
|
||||||
Files.copy(embeddedModFile, tempFile, StandardCopyOption.REPLACE_EXISTING);
|
Files.copy(embeddedModFile, tempFile, StandardCopyOption.REPLACE_EXISTING);
|
||||||
try (FileSystem embeddedFs = CompressingUtils.createReadOnlyZipFileSystem(tempFile)) {
|
try (FileSystem embeddedFs = CompressingUtils.createReadOnlyZipFileSystem(tempFile)) {
|
||||||
return fromFile(modManager, modFile, embeddedFs);
|
return fromFile(modManager, modFile, embeddedFs, modLoaderType);
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
LOG.warning("Failed to read embedded-dependencies-mod: " + embeddedModFile, e);
|
LOG.warning("Failed to read embedded-dependencies-mod: " + embeddedModFile, e);
|
||||||
@@ -200,33 +210,36 @@ public final class ForgeNewModMetadata {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ModLoaderType analyzeLoader(Toml toml, String modID, int loaderACC, ModLoaderType defaultLoader) throws IOException {
|
private static ModLoaderType analyzeLoader(Toml toml, String modID, ModLoaderType loader) throws IOException {
|
||||||
List<HashMap<String, Object>> dependencies = toml.getList("dependencies." + modID);
|
List<HashMap<String, Object>> dependencies = toml.getList("dependencies." + modID);
|
||||||
if (dependencies == null) {
|
if (dependencies == null) {
|
||||||
dependencies = toml.getList("dependencies"); // ??? I have no idea why some of the Forge mods use [[dependencies]]
|
dependencies = toml.getList("dependencies"); // ??? I have no idea why some of the Forge mods use [[dependencies]]
|
||||||
if (dependencies == null) {
|
if (dependencies == null) {
|
||||||
return defaultLoader;
|
return loader;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ModLoaderType result = null;
|
||||||
|
loop:
|
||||||
for (HashMap<String, Object> dependency : dependencies) {
|
for (HashMap<String, Object> dependency : dependencies) {
|
||||||
switch ((String) dependency.get("modId")) {
|
switch ((String) dependency.get("modId")) {
|
||||||
case "forge":
|
case "forge":
|
||||||
return checkLoaderACC(loaderACC, ACC_FORGE, ModLoaderType.FORGE);
|
result = ModLoaderType.FORGE;
|
||||||
|
break loop;
|
||||||
case "neoforge":
|
case "neoforge":
|
||||||
return checkLoaderACC(loaderACC, ACC_NEO_FORGED, ModLoaderType.NEO_FORGED);
|
result = ModLoaderType.NEO_FORGED;
|
||||||
|
break loop;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ??? I have no idea why some of the Forge mods doesn't provide this key.
|
if (result == loader)
|
||||||
return defaultLoader;
|
return result;
|
||||||
}
|
else if (result != null)
|
||||||
|
throw new IOException("Loader mismatch");
|
||||||
private static ModLoaderType checkLoaderACC(int current, int target, ModLoaderType res) throws IOException {
|
else {
|
||||||
if ((target & current) != 0) {
|
LOG.warning("Cannot determine the mod loader for mod " + modID + ", expected " + loader);
|
||||||
return res;
|
return loader;
|
||||||
} else {
|
|
||||||
throw new IOException("Mismatched loader.");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user