Separate plugin types #10
|
@ -115,7 +115,7 @@ public class FrogLoaderImpl implements FrogLoader {
|
||||||
gamePlugin = plugin;
|
gamePlugin = plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadModProviders() {
|
private void loadModProviders() throws Exception {
|
||||||
PluginLoader.discoverModProviders(gameDir, mods, modIds, modProviders);
|
PluginLoader.discoverModProviders(gameDir, mods, modIds, modProviders);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,13 +5,17 @@ import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.ServiceLoader;
|
import java.util.ServiceLoader;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import dev.frogmc.frogloader.api.FrogLoader;
|
import dev.frogmc.frogloader.api.FrogLoader;
|
||||||
import dev.frogmc.frogloader.api.mod.ModProperties;
|
import dev.frogmc.frogloader.api.mod.ModProperties;
|
||||||
import dev.frogmc.frogloader.api.plugin.FrogGamePlugin;
|
import dev.frogmc.frogloader.api.plugin.FrogGamePlugin;
|
||||||
import dev.frogmc.frogloader.api.plugin.FrogModProvider;
|
import dev.frogmc.frogloader.api.plugin.FrogModProvider;
|
||||||
|
import dev.frogmc.frogloader.impl.gui.LoaderGui;
|
||||||
import dev.frogmc.frogloader.impl.mixin.AWProcessor;
|
import dev.frogmc.frogloader.impl.mixin.AWProcessor;
|
||||||
import dev.frogmc.frogloader.impl.mod.BuiltinExtensions;
|
import dev.frogmc.frogloader.impl.mod.BuiltinExtensions;
|
||||||
|
import dev.frogmc.frogloader.impl.mod.ModDependencyResolver;
|
||||||
|
import dev.frogmc.frogloader.impl.util.CrashReportGenerator;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.spongepowered.asm.mixin.Mixins;
|
import org.spongepowered.asm.mixin.Mixins;
|
||||||
|
@ -19,7 +23,7 @@ import org.spongepowered.asm.mixin.Mixins;
|
||||||
public class PluginLoader {
|
public class PluginLoader {
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger("FrogLoader/Plugins");
|
private static final Logger LOGGER = LoggerFactory.getLogger("FrogLoader/Plugins");
|
||||||
|
|
||||||
public static void discoverModProviders(Path gameDir, Map<String, Map<String, ModProperties>> mods, Collection<String> modIds, Collection<FrogModProvider> modProviders) {
|
public static void discoverModProviders(Path gameDir, Map<String, Map<String, ModProperties>> mods, Collection<String> modIds, Collection<FrogModProvider> modProviders) throws ModDependencyResolver.ResolverException {
|
||||||
LOGGER.info("Discovering mod providers...");
|
LOGGER.info("Discovering mod providers...");
|
||||||
|
|
||||||
for (FrogModProvider plugin : ServiceLoader.load(FrogModProvider.class)) {
|
for (FrogModProvider plugin : ServiceLoader.load(FrogModProvider.class)) {
|
||||||
|
@ -44,6 +48,16 @@ public class PluginLoader {
|
||||||
LOGGER.error("Error during plugin initialisation: ", e);
|
LOGGER.error("Error during plugin initialisation: ", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Collection<ModProperties> properties = mods.values().stream().map(Map::values).flatMap(Collection::stream).collect(Collectors.toUnmodifiableSet());
|
||||||
|
try {
|
||||||
|
Collection<ModProperties> solved = new ModDependencyResolver(properties).solve();
|
||||||
|
mods.forEach((s, map) -> map.values().retainAll(solved));
|
||||||
|
} catch (ModDependencyResolver.UnfulfilledDependencyException e) {
|
||||||
|
LoaderGui.execUnfulfilledDep(CrashReportGenerator.writeReport(e, properties), e, false);
|
||||||
|
} catch (ModDependencyResolver.BreakingModException e) {
|
||||||
|
LoaderGui.execBreakingDep(CrashReportGenerator.writeReport(e, properties), e, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||||
|
|
|
@ -230,18 +230,10 @@ public class ModDependencyResolver {
|
||||||
throw new IllegalArgumentException(comparator);
|
throw new IllegalArgumentException(comparator);
|
||||||
}
|
}
|
||||||
var type = DependencyType.of(matcher.group(1));
|
var type = DependencyType.of(matcher.group(1));
|
||||||
StringBuilder version = new StringBuilder(matcher.group(2));
|
var version = matcher.group(2);
|
||||||
|
|
||||||
while (version.length() < 5) {
|
|
||||||
if (version.charAt(version.length() - 1) == '.') {
|
|
||||||
version.append('0');
|
|
||||||
} else {
|
|
||||||
version.append('.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return new Comparator(type, SemVerImpl.parse(version.toString()));
|
return new Comparator(type, SemVerImpl.parse(version));
|
||||||
} catch (SemVerParseException e) {
|
} catch (SemVerParseException e) {
|
||||||
throw new UncheckedIOException(e);
|
throw new UncheckedIOException(e);
|
||||||
}
|
}
|
||||||
|
@ -325,6 +317,7 @@ public class ModDependencyResolver {
|
||||||
public record VersionRange(Collection<ComparatorSet> sets) {
|
public record VersionRange(Collection<ComparatorSet> sets) {
|
||||||
|
|
||||||
private static final Pattern NUMBER_EXTRACTOR = Pattern.compile("[^~]?(\\d+)(?:\\.(?:([\\dxX*]+)(?:\\.([\\dxX*]+)?)?)?)?(.*)");
|
private static final Pattern NUMBER_EXTRACTOR = Pattern.compile("[^~]?(\\d+)(?:\\.(?:([\\dxX*]+)(?:\\.([\\dxX*]+)?)?)?)?(.*)");
|
||||||
|
private static final Pattern FILL_PATTERN = Pattern.compile("[><=]+(\\d+)\\.?(\\d+)?\\.?(\\d+)?");
|
||||||
|
|
||||||
public static VersionRange parse(String range) throws ResolverException {
|
public static VersionRange parse(String range) throws ResolverException {
|
||||||
|
|
||||||
|
@ -365,13 +358,7 @@ public class ModDependencyResolver {
|
||||||
private static void handleTilde(String s, List<String> ranges) throws ResolverException {
|
private static void handleTilde(String s, List<String> ranges) throws ResolverException {
|
||||||
{
|
{
|
||||||
StringBuilder builder = new StringBuilder(">=" + s.substring(1));
|
StringBuilder builder = new StringBuilder(">=" + s.substring(1));
|
||||||
while (builder.length() < 7) {
|
fillVersion(builder);
|
||||||
if (builder.charAt(builder.length() - 1) == '.') {
|
|
||||||
builder.append('0');
|
|
||||||
} else {
|
|
||||||
builder.append('.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ranges.add(builder.toString());
|
ranges.add(builder.toString());
|
||||||
}
|
}
|
||||||
ranges.add(" ");
|
ranges.add(" ");
|
||||||
|
@ -393,13 +380,7 @@ public class ModDependencyResolver {
|
||||||
private static void handleXRanges(String s, List<String> ranges) throws ResolverException {
|
private static void handleXRanges(String s, List<String> ranges) throws ResolverException {
|
||||||
{
|
{
|
||||||
StringBuilder builder = new StringBuilder(">=" + s.replaceAll("[xX*]", "0"));
|
StringBuilder builder = new StringBuilder(">=" + s.replaceAll("[xX*]", "0"));
|
||||||
while (builder.length() < 7) {
|
fillVersion(builder);
|
||||||
if (builder.charAt(builder.length() - 1) == '.') {
|
|
||||||
builder.append('0');
|
|
||||||
} else {
|
|
||||||
builder.append('.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ranges.add(builder.toString());
|
ranges.add(builder.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -424,13 +405,7 @@ public class ModDependencyResolver {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (builder.length() < 6) {
|
fillVersion(builder);
|
||||||
if (builder.charAt(builder.length() - 1) == '.') {
|
|
||||||
builder.append('0');
|
|
||||||
} else {
|
|
||||||
builder.append('.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ranges.add(builder.toString());
|
ranges.add(builder.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -456,26 +431,21 @@ public class ModDependencyResolver {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (builder.length() < 6) {
|
fillVersion(builder);
|
||||||
|
/*while (builder.length() < 6) {
|
||||||
if (builder.charAt(builder.length() - 1) == '.') {
|
if (builder.charAt(builder.length() - 1) == '.') {
|
||||||
builder.append('0');
|
builder.append('0');
|
||||||
} else {
|
} else {
|
||||||
builder.append('.');
|
builder.append('.');
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
ranges.add(builder.toString());
|
ranges.add(builder.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void handleHyphenRange(String s, List<String> ranges, String end) throws ResolverException {
|
private static void handleHyphenRange(String s, List<String> ranges, String end) throws ResolverException {
|
||||||
{
|
{
|
||||||
StringBuilder builder = new StringBuilder(">=" + s);
|
StringBuilder builder = new StringBuilder(">=" + s);
|
||||||
while (builder.length() < 7) {
|
fillVersion(builder);
|
||||||
if (builder.charAt(builder.length() - 1) == '.') {
|
|
||||||
builder.append('0');
|
|
||||||
} else {
|
|
||||||
builder.append('.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ranges.add(builder.toString());
|
ranges.add(builder.toString());
|
||||||
ranges.add(" ");
|
ranges.add(" ");
|
||||||
}
|
}
|
||||||
|
@ -499,19 +469,35 @@ public class ModDependencyResolver {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (builder.length() < 6) {
|
fillVersion(builder);
|
||||||
if (builder.charAt(builder.length() - 1) == '.') {
|
|
||||||
builder.append('0');
|
|
||||||
} else {
|
|
||||||
builder.append('.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ranges.add(builder.toString());
|
ranges.add(builder.toString());
|
||||||
} else {
|
} else {
|
||||||
ranges.add("<=" + end);
|
ranges.add("<=" + end);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void fillVersion(StringBuilder builder) {
|
||||||
|
Matcher matcher = FILL_PATTERN.matcher(builder);
|
||||||
|
if (!matcher.find()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (matcher.group(3) != null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (builder.charAt(builder.length() - 1) != '.') {
|
||||||
|
builder.append(".");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (matcher.group(2) == null) {
|
||||||
|
builder.append("0.0");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.append("0");
|
||||||
|
}
|
||||||
|
|
||||||
private static @NotNull List<String> extractRanges(String range) {
|
private static @NotNull List<String> extractRanges(String range) {
|
||||||
if (!range.contains(" ") && !range.contains(" - ") && !range.contains("||")) {
|
if (!range.contains(" ") && !range.contains(" - ") && !range.contains("||")) {
|
||||||
return List.of(range);
|
return List.of(range);
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
package dev.frogmc.frogloader.impl.plugin.game.minecraft;
|
package dev.frogmc.frogloader.impl.plugin.game.minecraft;
|
||||||
|
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import dev.frogmc.frogloader.api.mod.SemVer;
|
import dev.frogmc.frogloader.api.mod.SemVer;
|
||||||
import dev.frogmc.frogloader.impl.SemVerParseException;
|
import dev.frogmc.frogloader.impl.SemVerParseException;
|
||||||
import dev.frogmc.frogloader.impl.mod.SemVerImpl;
|
import dev.frogmc.frogloader.impl.mod.SemVerImpl;
|
||||||
|
@ -7,6 +10,7 @@ import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
public class MinecraftSemVerImpl implements SemVer {
|
public class MinecraftSemVerImpl implements SemVer {
|
||||||
|
|
||||||
|
private static final Pattern FILL_PATTERN = Pattern.compile("(\\d+)\\.?(\\d+)?\\.?(\\d+)?");
|
||||||
private final String version;
|
private final String version;
|
||||||
|
|
||||||
private MinecraftSemVerImpl(String version) {
|
private MinecraftSemVerImpl(String version) {
|
||||||
|
@ -15,12 +19,36 @@ public class MinecraftSemVerImpl implements SemVer {
|
||||||
|
|
||||||
static SemVer get(String version) {
|
static SemVer get(String version) {
|
||||||
try {
|
try {
|
||||||
return SemVerImpl.parse(version);
|
StringBuilder builder = new StringBuilder(version);
|
||||||
|
fillVersion(builder);
|
||||||
|
return SemVerImpl.parse(builder.toString());
|
||||||
} catch (SemVerParseException e) {
|
} catch (SemVerParseException e) {
|
||||||
return new MinecraftSemVerImpl(version);
|
return new MinecraftSemVerImpl(version);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void fillVersion(StringBuilder builder) {
|
||||||
|
Matcher matcher = FILL_PATTERN.matcher(builder);
|
||||||
|
if (!matcher.find()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (matcher.group(3) != null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (builder.charAt(builder.length() - 1) != '.') {
|
||||||
|
builder.append(".");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (matcher.group(2) == null) {
|
||||||
|
builder.append("0.0");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.append("0");
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int major() {
|
public int major() {
|
||||||
throw new UnsupportedOperationException("Minecraft version " + version + " does not represent a semver-compatible version");
|
throw new UnsupportedOperationException("Minecraft version " + version + " does not represent a semver-compatible version");
|
||||||
|
|
Loading…
Reference in a new issue