first rudimentary gui implementation
This commit is contained in:
parent
a163a5ef89
commit
ef6e0136f1
|
@ -12,7 +12,7 @@ credits = [
|
|||
|
||||
[frog.dependencies]
|
||||
depends = [
|
||||
{ id = "other_mod", versions = ">=0.2.0 <0.5.2 || 0.1.1 || 1.x || 3 || ~5 || ^6.x" }
|
||||
{ id = "other_mod", versions = ">=0.2.0 <0.5.2 || 0.1.1 || 1.x || 3 || ~5 || ^6.x", link = "https://example.com" }
|
||||
]
|
||||
breaks = [
|
||||
{ id = "old_mod", versions = "*" }
|
||||
|
|
|
@ -7,7 +7,7 @@ import java.util.Optional;
|
|||
import org.ecorous.esnesnon.nonsense.loader.api.env.Env;
|
||||
import org.ecorous.esnesnon.nonsense.loader.api.mod.ModProperties;
|
||||
import org.ecorous.esnesnon.nonsense.loader.impl.LoaderImpl;
|
||||
import org.ecorous.esnesnon.nonsense.loader.impl.plugin.NonsensePlugin;
|
||||
import org.ecorous.esnesnon.nonsense.loader.api.plugin.NonsensePlugin;
|
||||
|
||||
public interface Loader {
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ public final class ModDependencies {
|
|||
for (Type type : Type.values()) {
|
||||
for (Entry entry : getForType(type)) {
|
||||
if (entry.id.equals(id)) {
|
||||
entries.add(new ModEntry(type, entry.range));
|
||||
entries.add(new ModEntry(type, entry.range, entry.link));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -32,10 +32,12 @@ public final class ModDependencies {
|
|||
public static class ModEntry {
|
||||
private final Type type;
|
||||
private final String range;
|
||||
private final String link;
|
||||
|
||||
private ModEntry(Type type, String range) {
|
||||
private ModEntry(Type type, String range, String link) {
|
||||
this.type = type;
|
||||
this.range = range;
|
||||
this.link = link;
|
||||
}
|
||||
|
||||
public Type type() {
|
||||
|
@ -45,9 +47,13 @@ public final class ModDependencies {
|
|||
public String range() {
|
||||
return range;
|
||||
}
|
||||
|
||||
public String link(){
|
||||
return link;
|
||||
}
|
||||
}
|
||||
|
||||
public record Entry(String id, String range) {
|
||||
public record Entry(String id, String range, String link) {
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -3,12 +3,17 @@ package org.ecorous.esnesnon.nonsense.loader.api.mod;
|
|||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public interface ModProperties {
|
||||
|
||||
String id();
|
||||
|
||||
String name();
|
||||
|
||||
@Nullable
|
||||
String icon();
|
||||
|
||||
SemVer version();
|
||||
|
||||
String license();
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package org.ecorous.esnesnon.nonsense.loader.impl.plugin;
|
||||
package org.ecorous.esnesnon.nonsense.loader.api.plugin;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import org.ecorous.esnesnon.nonsense.loader.api.Loader;
|
||||
import org.ecorous.esnesnon.nonsense.loader.api.mod.ModProperties;
|
||||
import org.ecorous.esnesnon.nonsense.loader.impl.LoaderImpl;
|
||||
|
||||
public interface NonsensePlugin extends Runnable {
|
||||
|
||||
|
@ -18,7 +18,7 @@ public interface NonsensePlugin extends Runnable {
|
|||
return false;
|
||||
}
|
||||
|
||||
default void init(LoaderImpl loader) throws Exception {
|
||||
default void init(Loader loader) throws Exception {
|
||||
}
|
||||
|
||||
Collection<ModProperties> getMods();
|
|
@ -1,9 +1,6 @@
|
|||
package org.ecorous.esnesnon.nonsense.loader.impl;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
|
@ -20,7 +17,7 @@ import org.ecorous.esnesnon.nonsense.loader.api.env.Env;
|
|||
import org.ecorous.esnesnon.nonsense.loader.api.mod.ModProperties;
|
||||
import org.ecorous.esnesnon.nonsense.loader.impl.launch.MixinClassLoader;
|
||||
import org.ecorous.esnesnon.nonsense.loader.impl.mod.ModUtil;
|
||||
import org.ecorous.esnesnon.nonsense.loader.impl.plugin.NonsensePlugin;
|
||||
import org.ecorous.esnesnon.nonsense.loader.api.plugin.NonsensePlugin;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.spongepowered.asm.mixin.MixinEnvironment;
|
||||
|
@ -99,27 +96,8 @@ public class LoaderImpl implements Loader {
|
|||
}
|
||||
|
||||
private void discoverPlugins() {
|
||||
List<String> classes = new ArrayList<>();
|
||||
this.getClass().getClassLoader().resources("META-INF/services/" + NonsensePlugin.class.getName()).distinct().forEach(url -> {
|
||||
try (InputStream inputStream = url.openStream()) {
|
||||
new BufferedReader(new InputStreamReader(inputStream)).lines().forEach(classes::add);
|
||||
} catch (IOException e) {
|
||||
LOGGER.error("Failed to load plugin: ", e);
|
||||
}
|
||||
});
|
||||
LOGGER.info("Found plugins: \n{}", String.join("\t\n", classes));
|
||||
|
||||
for (Class<?> c : classes.stream().map((String className) -> {
|
||||
ServiceLoader.load(NonsensePlugin.class).forEach(plugin -> {
|
||||
try {
|
||||
return classloader.findClass(className);
|
||||
} catch (ClassNotFoundException e) {
|
||||
LOGGER.error("Failed to load plugin: ", e);
|
||||
return null;
|
||||
}
|
||||
}).filter(Objects::nonNull).filter(NonsensePlugin.class::isAssignableFrom).toList()) {
|
||||
try {
|
||||
MethodHandle ctor = MethodHandles.publicLookup().findConstructor(c, MethodType.methodType(void.class));
|
||||
NonsensePlugin plugin = (NonsensePlugin) ctor.invoke();
|
||||
if (plugin.isApplicable()) {
|
||||
plugin.init(this);
|
||||
plugins.add(plugin);
|
||||
|
@ -128,7 +106,7 @@ public class LoaderImpl implements Loader {
|
|||
LOGGER.error("Error during plugin initialisation: ", e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (plugins.isEmpty()) {
|
||||
// TODO display error
|
||||
|
|
|
@ -0,0 +1,125 @@
|
|||
package org.ecorous.esnesnon.nonsense.loader.impl.gui;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.net.URI;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.ecorous.esnesnon.nonsense.loader.impl.LoaderImpl;
|
||||
import org.ecorous.esnesnon.nonsense.loader.impl.mod.ModDependencyResolver;
|
||||
import org.ecorous.esnesnon.nonsense.loader.impl.mod.ModUtil;
|
||||
import org.ecorous.esnesnon.nonsense.loader.impl.util.URLUtil;
|
||||
|
||||
public class LoaderGui {
|
||||
|
||||
public static Builder builder(){
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
private final JFrame frame = getFrame();
|
||||
|
||||
public <T> Builder setContent(ContentType<T> type, T argument){
|
||||
type.contentSetter.accept(frame, argument);
|
||||
return this;
|
||||
}
|
||||
|
||||
public LoaderGui build(){
|
||||
return new LoaderGui(frame);
|
||||
}
|
||||
}
|
||||
|
||||
private final JFrame frame;
|
||||
private LoaderGui(JFrame frame){
|
||||
this.frame = frame;
|
||||
}
|
||||
|
||||
private static JFrame getFrame(){
|
||||
var frame = new JFrame();
|
||||
frame.setTitle("FrogLoader " + LoaderGui.class.getPackage().getImplementationVersion());
|
||||
frame.setSize(952, 560);
|
||||
frame.setLocationRelativeTo(null);
|
||||
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
|
||||
return frame;
|
||||
}
|
||||
|
||||
public void show(){
|
||||
frame.setVisible(true);
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
public static class ContentType<T> {
|
||||
public static ContentType<ModDependencyResolver.UnfulfilledDependencyException> INFO_UNFULFILLED_DEP = new ContentType<>((frame, ex) -> {
|
||||
JPanel pane = new JPanel(new BorderLayout());
|
||||
JTextPane title = new JTextPane();
|
||||
title.setContentType("text/html");
|
||||
title.setBackground(pane.getBackground());
|
||||
title.setEditable(false);
|
||||
int size = ex.getDependencies().size();
|
||||
title.setText("<html><h3>Found "+size+" Error"+(size > 1 ? "s:":":")+"</h3></html>");
|
||||
pane.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
|
||||
pane.add(title, BorderLayout.NORTH);
|
||||
|
||||
for (ModDependencyResolver.UnfulfilledDependencyException.Entry e : ex.getDependencies()) {
|
||||
String descriptionText;
|
||||
if (e.presentVersion() != null){
|
||||
descriptionText = String.format("Mod %s (%s) depends on a Mod with id %s with a version matching %s, but a different version is present or provided: %s", e.source().id(), e.source().name(), e.dependency(), printVersionRange(e.range()), e.presentVersion());
|
||||
} else {
|
||||
descriptionText = String.format("Mod %s (%s) depends on a Mod with id %s with a version matching %s. \nNo version is currently available.", e.source().id(), e.source().name(), e.dependency(), printVersionRange(e.range()));
|
||||
}
|
||||
SwingWidget text = new SwingWidget(descriptionText);
|
||||
if (e.link() != null) {
|
||||
boolean install = e.link().endsWith(LoaderImpl.MOD_FILE_EXTENSION);
|
||||
String name = install ? "Install" : "Open mod page";
|
||||
JButton urlButton = new JButton(new AbstractAction(name) {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
if (install){
|
||||
ModUtil.installMod(e.link());
|
||||
} else {
|
||||
URLUtil.open(URI.create(e.link()));
|
||||
}
|
||||
}
|
||||
});
|
||||
text.add(urlButton); // TODO ??? fix this bs
|
||||
}
|
||||
pane.add(text);
|
||||
}
|
||||
pane.setSize(pane.getHeight(), frame.getWidth());
|
||||
JScrollPane scroll = new JScrollPane(pane);
|
||||
scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
|
||||
frame.add(scroll);
|
||||
});
|
||||
public static ContentType<ModDependencyResolver.BreakingModException> INFO_BREAKING_DEP = new ContentType<>((frame, ex) -> {
|
||||
JPanel pane = new JPanel(new BorderLayout());
|
||||
JTextPane title = new JTextPane();
|
||||
title.setContentType("text/html");
|
||||
title.setBackground(pane.getBackground());
|
||||
title.setEditable(false);
|
||||
int size = ex.getBreaks().size();
|
||||
title.setText("<html><h3>Found "+size+" Error"+(size > 1 ? "s:":":")+"</h3></html>");
|
||||
pane.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
|
||||
pane.add(title, BorderLayout.NORTH);
|
||||
|
||||
for (ModDependencyResolver.BreakingModException.Entry e : ex.getBreaks()) {
|
||||
String descriptionText = String.format("Mod %s (%s) breaks with mod %s (%s) for versions matching %s \n(present: %s)", e.source().id(), e.source().name(), e.broken().id(), e.broken().name(), printVersionRange(e.range()), e.broken().version());
|
||||
SwingWidget text = new SwingWidget(descriptionText);
|
||||
pane.add(text);
|
||||
}
|
||||
pane.setSize(pane.getHeight(), frame.getWidth());
|
||||
JScrollPane scroll = new JScrollPane(pane);
|
||||
scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
|
||||
frame.add(scroll);
|
||||
});
|
||||
|
||||
private final BiConsumer<JFrame, T> contentSetter;
|
||||
}
|
||||
|
||||
private static String printVersionRange(ModDependencyResolver.VersionRange range){
|
||||
return "range: \n"+ range.toString().replace("||", "or")+" \n("+range+")";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
package org.ecorous.esnesnon.nonsense.loader.impl.gui;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
public class SwingWidget extends JComponent {
|
||||
|
||||
private final String description;
|
||||
|
||||
public SwingWidget(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintComponent(Graphics g) {
|
||||
super.paintComponent(g);
|
||||
Insets insets = getParent().getInsets();
|
||||
Graphics graphics = g.create();
|
||||
graphics.setColor(Color.LIGHT_GRAY);
|
||||
int width = getWidth()-insets.left-insets.right;
|
||||
graphics.fillRoundRect(getX(), getY(), width, 75, 32, 32);
|
||||
graphics.setColor(Color.BLACK);
|
||||
drawWrapped(graphics, description, getX()+5, getY()+20, width-20);
|
||||
paintChildren(g);
|
||||
}
|
||||
|
||||
private int drawWrapped(Graphics graphics, String text, int x, int y, int width){
|
||||
int lineHeight = graphics.getFontMetrics().getHeight();
|
||||
|
||||
int lineY = y;
|
||||
int lineX = x;
|
||||
StringBuilder builder = new StringBuilder();
|
||||
String[] split = text.split(" ");
|
||||
for (int i = 0, splitLength = split.length; i < splitLength; i++) {
|
||||
String s = split[i];
|
||||
int rt = s.indexOf('\n');
|
||||
if (rt != -1){
|
||||
builder.append(s, 0, rt);
|
||||
graphics.drawString(builder.toString(), lineX, lineY);
|
||||
lineY+=lineHeight;
|
||||
lineX= x+20;
|
||||
builder.delete(0, builder.length());
|
||||
builder.append(s.substring(rt)).append(" ");
|
||||
continue;
|
||||
}
|
||||
builder.append(s).append(" ");
|
||||
String next = i<splitLength-1 ? split[i + 1] : "";
|
||||
if (graphics.getFontMetrics().stringWidth(builder+next) >= width) {
|
||||
graphics.drawString(builder.toString(), lineX, lineY);
|
||||
lineY += lineHeight;
|
||||
lineX= x+20;
|
||||
builder.delete(0, builder.length());
|
||||
}
|
||||
}
|
||||
if (!builder.isEmpty()) {
|
||||
graphics.drawString(builder.toString(), lineX, lineY);
|
||||
}
|
||||
return lineY+lineHeight;
|
||||
}
|
||||
}
|
|
@ -29,6 +29,7 @@ public class MixinClassLoader extends URLClassLoader {
|
|||
excludePackage("com.sun");
|
||||
excludePackage("sun");
|
||||
excludePackage("jdk");
|
||||
excludePackage("javax");
|
||||
}
|
||||
|
||||
public boolean isClassLoaded(String name) {
|
||||
|
|
|
@ -20,6 +20,7 @@ public class JavaModProperties {
|
|||
if (INSTANCE == null) {
|
||||
INSTANCE = new ModPropertiesImpl("java",
|
||||
System.getProperty("java.vm.name"),
|
||||
"/duke.png",
|
||||
SemVerImpl.parse(System.getProperty("java.runtime.version")),
|
||||
"",
|
||||
Map.of(System.getProperty("java.vm.vendor"), Collections.singleton("Vendor")),
|
||||
|
|
|
@ -13,6 +13,7 @@ import org.ecorous.esnesnon.nonsense.loader.api.mod.ModProperties;
|
|||
import org.ecorous.esnesnon.nonsense.loader.api.mod.SemVer;
|
||||
import org.ecorous.esnesnon.nonsense.loader.impl.SemVerParseException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -35,13 +36,13 @@ public class ModDependencyResolver {
|
|||
private void load() throws ResolverException {
|
||||
for (ModProperties props : original) {
|
||||
for (ModDependencies.Entry entry : props.dependencies().getForType(ModDependencies.Type.DEPEND)) {
|
||||
dependencies.put(entry.id(), new DependencyEntry(entry.range(), props));
|
||||
dependencies.put(entry.id(), new DependencyEntry(entry.range(), props, entry.link()));
|
||||
}
|
||||
for (ModDependencies.Entry entry : props.dependencies().getForType(ModDependencies.Type.BREAK)) {
|
||||
breakings.put(entry.id(), new DependencyEntry(entry.range(), props));
|
||||
breakings.put(entry.id(), new DependencyEntry(entry.range(), props, entry.link()));
|
||||
}
|
||||
for (ModDependencies.Entry entry : props.dependencies().getForType(ModDependencies.Type.SUGGEST)) {
|
||||
suggests.put(entry.id(), new DependencyEntry(entry.range(), props));
|
||||
suggests.put(entry.id(), new DependencyEntry(entry.range(), props, entry.link()));
|
||||
}
|
||||
props.dependencies().getForType(ModDependencies.Type.PROVIDE).forEach(e -> {
|
||||
try {
|
||||
|
@ -114,7 +115,7 @@ public class ModDependencyResolver {
|
|||
if (!(presentMods.containsKey(s) && value.range.versionMatches(presentOrProvided.get(s)))) { // The dependency isn't fulfilled by any present mods
|
||||
if (!(provides.containsKey(s) && value.range.versionMatches(provides.get(s).version()))) { // The dependency also isn't fulfilled by any provided mods
|
||||
if (value.origin.extensions().getOrDefault(BuiltinExtensions.LOADING_TYPE, "required").equals("required")) {
|
||||
unfulfilled.add(new UnfulfilledDependencyException.Entry(value.origin, s, value.range));
|
||||
unfulfilled.add(new UnfulfilledDependencyException.Entry(value.origin, s, value.range, presentOrProvided.get(s), value.link()));
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
@ -126,10 +127,10 @@ public class ModDependencyResolver {
|
|||
|
||||
if (!unfulfilled.isEmpty()){
|
||||
unfulfilled.forEach(e -> {
|
||||
if (!presentOrProvided.containsKey(e.dependency)) {
|
||||
LOGGER.error("Mod {} ({}) depends on mod {} with a version matching {}", e.source().id(), e.source().name(), e.dependency(), e.range());
|
||||
if (e.presentVersion() == null) {
|
||||
LOGGER.error("Mod {} ({}) depends on mod {} with a version matching {} (No version available)", e.source().id(), e.source().name(), e.dependency(), e.range());
|
||||
} else {
|
||||
LOGGER.error("Mod {} ({}) depends on mod {} with a version matching {}, but a different version is present or provided: {}", e.source().id(), e.source().name(), e.dependency(), e.range(), presentOrProvided.get(e.dependency));
|
||||
LOGGER.error("Mod {} ({}) depends on mod {} with a version matching {}, but a different version is present or provided: {}", e.source().id(), e.source().name(), e.dependency(), e.range(), e.presentVersion());
|
||||
}
|
||||
});
|
||||
throw new UnfulfilledDependencyException(unfulfilled);
|
||||
|
@ -176,7 +177,7 @@ public class ModDependencyResolver {
|
|||
public static class UnfulfilledDependencyException extends Exception {
|
||||
private final Collection<Entry> dependencies;
|
||||
|
||||
public record Entry(ModProperties source, String dependency, VersionRange range){}
|
||||
public record Entry(ModProperties source, String dependency, VersionRange range, SemVer presentVersion, @Nullable String link){}
|
||||
}
|
||||
|
||||
public static class ResolverException extends Exception {
|
||||
|
@ -185,10 +186,10 @@ public class ModDependencyResolver {
|
|||
}
|
||||
}
|
||||
|
||||
private record DependencyEntry(VersionRange range, ModProperties origin) {
|
||||
private record DependencyEntry(VersionRange range, ModProperties origin, String link) {
|
||||
|
||||
public DependencyEntry(String range, ModProperties origin) throws ResolverException {
|
||||
this(VersionRange.parse(range), origin);
|
||||
public DependencyEntry(String range, ModProperties origin, @Nullable String link) throws ResolverException {
|
||||
this(VersionRange.parse(range), origin, link);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -218,7 +219,7 @@ public class ModDependencyResolver {
|
|||
}
|
||||
|
||||
public boolean versionMatches(SemVer version) {
|
||||
return type.comparator.compare(this.version, version);
|
||||
return type.comparator.compare(version, this.version);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -244,7 +245,7 @@ public class ModDependencyResolver {
|
|||
}
|
||||
}
|
||||
|
||||
private record VersionRange(Collection<ComparatorSet> sets) {
|
||||
public record VersionRange(Collection<ComparatorSet> sets) {
|
||||
|
||||
private static final Pattern NUMBER_EXTRACTOR = Pattern.compile("[^~]?(\\d+)(?:\\.(?:([\\dxX*]+)(?:\\.([\\dxX*]+)?)?)?)?(.*)");
|
||||
|
||||
|
@ -286,7 +287,7 @@ public class ModDependencyResolver {
|
|||
|
||||
private static void handleTilde(String s, List<String> ranges) throws ResolverException {
|
||||
{
|
||||
StringBuilder builder = new StringBuilder(">=" + s);
|
||||
StringBuilder builder = new StringBuilder(">=" + s.substring(1));
|
||||
while (builder.length() < 7) {
|
||||
if (builder.charAt(builder.length() - 1) == '.') {
|
||||
builder.append('0');
|
||||
|
|
|
@ -8,7 +8,7 @@ import org.ecorous.esnesnon.nonsense.loader.api.mod.ModExtensions;
|
|||
import org.ecorous.esnesnon.nonsense.loader.api.mod.ModProperties;
|
||||
import org.ecorous.esnesnon.nonsense.loader.api.mod.SemVer;
|
||||
|
||||
public record ModPropertiesImpl(String id, String name, SemVer version, String license,
|
||||
public record ModPropertiesImpl(String id, String name, String icon, SemVer version, String license,
|
||||
Map<String, Collection<String>> credits, ModDependencies dependencies,
|
||||
ModExtensions extensions) implements ModProperties {
|
||||
}
|
||||
|
|
|
@ -59,6 +59,7 @@ public class ModPropertiesReader {
|
|||
V1_0_0("1.0.0", config -> {
|
||||
String id = config.get("frog.mod.id");
|
||||
String name = config.get("frog.mod.name");
|
||||
String icon = config.get("frog.mod.icon");
|
||||
String version = config.get("frog.mod.version");
|
||||
String license = config.get("frog.mod.license");
|
||||
|
||||
|
@ -75,25 +76,25 @@ public class ModPropertiesReader {
|
|||
Collection<ModDependencies.Entry> depends = new HashSet<>();
|
||||
List<UnmodifiableConfig> dependsConfig = config.get("frog.dependencies.depends");
|
||||
if (dependsConfig != null) {
|
||||
dependsConfig.forEach(entry -> depends.add(new ModDependencies.Entry(entry.get("id"), entry.get("versions"))));
|
||||
dependsConfig.forEach(entry -> depends.add(new ModDependencies.Entry(entry.get("id"), entry.get("versions"), entry.get("link"))));
|
||||
}
|
||||
|
||||
Collection<ModDependencies.Entry> breaks = new HashSet<>();
|
||||
List<UnmodifiableConfig> breaksConfig = config.get("frog.dependencies.breaks");
|
||||
if (breaksConfig != null) {
|
||||
breaksConfig.forEach(entry -> breaks.add(new ModDependencies.Entry(entry.get("id"), entry.get("versions"))));
|
||||
breaksConfig.forEach(entry -> breaks.add(new ModDependencies.Entry(entry.get("id"), entry.get("versions"), entry.get("link"))));
|
||||
}
|
||||
|
||||
Collection<ModDependencies.Entry> suggests = new HashSet<>();
|
||||
List<UnmodifiableConfig> suggestsConfig = config.get("frog.dependencies.suggests");
|
||||
if (suggestsConfig != null) {
|
||||
suggestsConfig.forEach(entry -> suggests.add(new ModDependencies.Entry(entry.get("id"), entry.get("versions"))));
|
||||
suggestsConfig.forEach(entry -> suggests.add(new ModDependencies.Entry(entry.get("id"), entry.get("versions"), entry.get("link"))));
|
||||
}
|
||||
|
||||
Collection<ModDependencies.Entry> provides = new HashSet<>();
|
||||
List<UnmodifiableConfig> providesConfig = config.get("frog.dependencies.provides");
|
||||
if (providesConfig != null) {
|
||||
providesConfig.forEach(entry -> provides.add(new ModDependencies.Entry(entry.get("id"), entry.get("version"))));
|
||||
providesConfig.forEach(entry -> provides.add(new ModDependencies.Entry(entry.get("id"), entry.get("version"), entry.get("link"))));
|
||||
}
|
||||
|
||||
UnmodifiableConfig extensionsConfig = config.get("frog.extensions");
|
||||
|
@ -102,7 +103,7 @@ public class ModPropertiesReader {
|
|||
extensionsConfig.entrySet().forEach(entry -> extensions.put(entry.getKey(), entry.getValue()));
|
||||
}
|
||||
|
||||
return new ModPropertiesImpl(id, name, SemVerImpl.parse(version), license, Collections.unmodifiableMap(credits), new ModDependencies(depends, breaks, suggests, provides), ModExtensions.of(extensions));
|
||||
return new ModPropertiesImpl(id, name, icon, SemVerImpl.parse(version), license, Collections.unmodifiableMap(credits), new ModDependencies(depends, breaks, suggests, provides), ModExtensions.of(extensions));
|
||||
});
|
||||
|
||||
private static final Map<String, Parser> versions = Arrays.stream(values()).collect(Collectors.toMap(v -> v.version, v -> v.parser));
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
package org.ecorous.esnesnon.nonsense.loader.impl.mod;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.nio.file.Files;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.ecorous.esnesnon.nonsense.loader.api.Loader;
|
||||
import org.ecorous.esnesnon.nonsense.loader.api.mod.ModProperties;
|
||||
|
||||
public class ModUtil {
|
||||
|
@ -27,4 +32,13 @@ public class ModUtil {
|
|||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public static void installMod(String url) {
|
||||
try {
|
||||
Files.copy(URI.create(url).toURL().openStream(), Loader.getInstance().getModsDir().resolve(url.substring(url.lastIndexOf("/"+1))));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
// TODO handle better than this
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,18 +11,17 @@ import java.nio.file.*;
|
|||
import java.util.*;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import org.ecorous.esnesnon.nonsense.loader.api.Loader;
|
||||
import org.ecorous.esnesnon.nonsense.loader.api.extensions.PreLaunchExtension;
|
||||
import org.ecorous.esnesnon.nonsense.loader.api.mod.ModDependencies;
|
||||
import org.ecorous.esnesnon.nonsense.loader.api.mod.ModExtensions;
|
||||
import org.ecorous.esnesnon.nonsense.loader.api.mod.ModProperties;
|
||||
import org.ecorous.esnesnon.nonsense.loader.api.plugin.NonsensePlugin;
|
||||
import org.ecorous.esnesnon.nonsense.loader.impl.Discovery;
|
||||
import org.ecorous.esnesnon.nonsense.loader.impl.LoaderImpl;
|
||||
import org.ecorous.esnesnon.nonsense.loader.impl.gui.LoaderGui;
|
||||
import org.ecorous.esnesnon.nonsense.loader.impl.mixin.AWProcessor;
|
||||
import org.ecorous.esnesnon.nonsense.loader.impl.mod.BuiltinExtensions;
|
||||
import org.ecorous.esnesnon.nonsense.loader.impl.mod.ModPropertiesImpl;
|
||||
import org.ecorous.esnesnon.nonsense.loader.impl.mod.ModPropertiesReader;
|
||||
import org.ecorous.esnesnon.nonsense.loader.impl.mod.*;
|
||||
import org.ecorous.esnesnon.nonsense.loader.impl.plugin.NonsensePlugin;
|
||||
import org.ecorous.esnesnon.nonsense_remapper.NonsenseRemapper;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -48,7 +47,7 @@ public class Minecraft implements NonsensePlugin {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void init(LoaderImpl loader) throws Exception {
|
||||
public void init(Loader loader) throws Exception {
|
||||
if (gamePath == null) {
|
||||
throw new IllegalStateException("Game not found yet!");
|
||||
}
|
||||
|
@ -63,7 +62,7 @@ public class Minecraft implements NonsensePlugin {
|
|||
}
|
||||
|
||||
modProperties.add(JavaModProperties.get());
|
||||
modProperties.add(new ModPropertiesImpl("minecraft", "Minecraft",
|
||||
modProperties.add(new ModPropertiesImpl("minecraft", "Minecraft", "/assets/minecraft/textures/block/grass_block_side.png",
|
||||
MinecraftSemVerImpl.get(version), "MC-EULA",
|
||||
Map.of("Mojang AB", Collections.singleton("Author")),
|
||||
new ModDependencies(Collections.emptySet(), Collections.emptySet(), Collections.emptySet(), Collections.emptySet()),
|
||||
|
@ -83,8 +82,12 @@ public class Minecraft implements NonsensePlugin {
|
|||
try {
|
||||
modProperties.retainAll(new ModDependencyResolver(modProperties).solve());
|
||||
} catch (ModDependencyResolver.BreakingModException e) {
|
||||
LoaderGui.builder().setContent(LoaderGui.ContentType.INFO_BREAKING_DEP, e).build().show();
|
||||
throw e;
|
||||
// TODO handle
|
||||
} catch (ModDependencyResolver.UnfulfilledDependencyException e) {
|
||||
LoaderGui.builder().setContent(LoaderGui.ContentType.INFO_UNFULFILLED_DEP, e).build().show();
|
||||
throw e;
|
||||
// TODO handle (and display)
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
package org.ecorous.esnesnon.nonsense.loader.impl.util;
|
||||
|
||||
import java.awt.*;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class URLUtil {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(URLUtil.class);
|
||||
|
||||
public static void open(URI url){
|
||||
|
||||
try {
|
||||
Desktop.getDesktop().browse(url);
|
||||
} catch (IOException e) {
|
||||
ProcessBuilder builder = new ProcessBuilder("xdg-open", url.toString());
|
||||
try {
|
||||
builder.start();
|
||||
} catch (IOException ex) {
|
||||
ex.addSuppressed(e);
|
||||
LOGGER.error("Failed to open url: ", ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
BIN
src/main/resources/duke.png
Normal file
BIN
src/main/resources/duke.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.1 KiB |
Loading…
Reference in a new issue