Skip to content

Enhance mod loading to respect dependency declarations starting with ~ which indicates dependencies that don't affect mod loading order. Relates to issues #37 and #42. #44

New issue

Have a question about this project? No Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “No Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? No Sign in to your account

Merged
merged 1 commit into from
Jan 4, 2023
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
69 changes: 56 additions & 13 deletions FactorioDataWrapper/src/com/demod/factorio/ModInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,66 @@

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.json.JSONArray;
import org.json.JSONObject;

public class ModInfo {
public static final Pattern DEPENDENCY_REGEX = Pattern.compile(
"(^(?:(\\?|\\(\\?\\)|!|~) *)?(.+?)(?: *([<>=]=?) *([0-9.]+))?$)");

// https://wiki.factorio.com/Tutorial:Mod_structure#dependencies
public static enum DependencyType {
// ! for incompatibility
INCOMPATIBLE,
// ? for an optional dependency
OPTIONAL,
// (?) for a hidden optional dependency
HIDDEN_OPTIONAL,
// ~ for a dependency that does not affect load order
DOES_NOT_AFFECT_LOAD_ORDER,
// no prefix for a hard requirement for the other mod.
REQUIRED,
;

private static DependencyType fromSymbol(String symbol) {
if (symbol == null) {
return REQUIRED;
}
switch (symbol) {
case "!":
return INCOMPATIBLE;
case "?":
return OPTIONAL;
case "(?)":
return HIDDEN_OPTIONAL;
case "~":
return DOES_NOT_AFFECT_LOAD_ORDER;
default:
throw new RuntimeException("Invalid dependency symbol: " + symbol);
}
}
}

public static class Dependency {
private final boolean optional;
private final DependencyType type;
private final String name;
private final String conditional;
private final String version;

private Dependency(boolean optional, String name, String conditional, String version) {
this.optional = optional;
private Dependency(DependencyType type, String name, String conditional, String version) {
this.type = type;
this.name = name;
this.conditional = conditional;
this.version = version;
}

public DependencyType getType() {
return this.type;
}

public String getConditional() {
return conditional;
}
Expand All @@ -33,7 +75,7 @@ public String getVersion() {
}

public boolean isOptional() {
return optional;
return this.type == DependencyType.OPTIONAL || this.type == DependencyType.HIDDEN_OPTIONAL;
}
}

Expand All @@ -60,15 +102,16 @@ public ModInfo(JSONObject json) {
}
for (int i = 0; i < dependenciesJson.length(); i++) {
String depString = dependenciesJson.getString(i);
String[] depSplit = depString.split("\\s");
if (depSplit.length == 1) {
dependencies.add(new Dependency(false, depSplit[0], null, null));
} else if (depSplit.length == 2) {
dependencies.add(new Dependency(true, depSplit[1], null, null));
} else if (depSplit.length == 3) {
dependencies.add(new Dependency(false, depSplit[0], depSplit[1], depSplit[2]));
} else if (depSplit.length == 4) {
dependencies.add(new Dependency(true, depSplit[1], depSplit[2], depSplit[3]));
Matcher matcher = DEPENDENCY_REGEX.matcher(depString);
if (matcher.matches()) {
String symbol = matcher.group(2);
DependencyType type = DependencyType.fromSymbol(symbol);
String name = matcher.group(3);
String conditional = matcher.group(4);
String version = matcher.group(5);
dependencies.add(new Dependency(type, name, conditional, version));
} else {
throw new RuntimeException("Invalid dependency string: " + depString);
}
}
}
Expand Down
6 changes: 4 additions & 2 deletions FactorioDataWrapper/src/com/demod/factorio/ModLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
import org.json.JSONException;

import com.demod.factorio.ModInfo.Dependency;
import com.demod.factorio.ModInfo.DependencyType;

import com.google.common.io.ByteStreams;

public class ModLoader {
Expand Down Expand Up @@ -145,11 +147,11 @@ public List<Mod> getModsInLoadOrder() {
for (Dependency dependency : mod.getInfo().getDependencies()) {
String depName = dependency.getName();
if (getMod(depName).isPresent()) {
if (!order.contains(depName)) {
if (!order.contains(depName) && dependency.getType() != DependencyType.DOES_NOT_AFFECT_LOAD_ORDER) {
missingDep = true;
break;
}
} else if (!dependency.isOptional()) {
} else if (!dependency.isOptional() && dependency.getType() != DependencyType.INCOMPATIBLE) {
throw new InternalError("MISSING DEPENDENCY FOR " + mod.getInfo().getName() + " : " + depName);
}
}
Expand Down