Skip to content

Commit

Permalink
Add the mod manager part of duskers mod manager
Browse files Browse the repository at this point in the history
  • Loading branch information
juanmuscaria committed Feb 13, 2024
1 parent e5f7c07 commit baf7f71
Show file tree
Hide file tree
Showing 20 changed files with 772 additions and 120 deletions.
42 changes: 40 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ plugins {
id 'io.micronaut.application' version '4.2.1'
}

version = "0.1"
ext.gitInfoCached = null
version = "0.0.1--${gitInfo('branch')}-${gitInfo('hash')}"
group = "com.juanmuscaria"
var os = DefaultNativePlatform.currentOperatingSystem

Expand All @@ -30,6 +31,11 @@ dependencies {
implementation("io.github.mkpaz:atlantafx-base:2.0.1")
compileOnly("org.projectlombok:lombok")
implementation("ch.qos.logback:logback-classic")
implementation('org.apache.tika:tika-core:2.9.1')
implementation('org.apache.commons:commons-collections4:4.4')
implementation('com.fasterxml.jackson.core:jackson-databind:2.16.1')
implementation('com.fasterxml.jackson.core:jackson-annotations:2.16.1')
implementation('com.fasterxml.jackson.dataformat:jackson-dataformat-toml:2.16.1')
}

graalvmNative {
Expand Down Expand Up @@ -146,11 +152,43 @@ tasks.register("buildModloader", Exec) {
processResources {
dependsOn("repackBepInEx", "buildModloader")
from("$buildDir/repack")
from("$projectDir/modloader/bin/Debug/net35/modloader.dll")

inputs.property "version", project.version
from(sourceSets.main.resources.srcDirs) {
include 'application.properties'

expand 'version':project.version
}

duplicatesStrategy = DuplicatesStrategy.INCLUDE
}

run {
//jvmArgs += "-agentlib:native-image-agent=config-merge-dir=src/main/resources/META-INF/native-image"
//jvmArgs += "-agentlib:native-image-agent=config-merge-dir=../src/main/resources/META-INF/native-image"
jvmArgs += '-Ddmm.forceLauncher=true'
jvmArgs += '-Djansi.mode=force'
jvmArgs += '-Dpicocli.ansi=true'
workingDir = buildDir
}

def gitInfo(String key) {
if (!gitInfoCached) {
if (file('.git').exists()) {
gitInfoCached = [
hash : ['git', 'log', "--format=%h", '-n', '1'].execute().text.trim(),
fullHash: ['git', 'log', "--format=%H", '-n', '1'].execute().text.trim(),
branch : ['git', 'symbolic-ref', '--short', 'HEAD'].execute().text.trim(),
message : ['git', 'log', "--format=%B", '-n', '1'].execute().text.trim()
]
} else {
gitInfoCached = [
hash : 'NOT_A_GIT',
fullHash: 'NOT_A_GIT',
branch : 'NOT_A_GIT',
message : 'NOT_A_GIT'
]
}
}
return key ? gitInfoCached[key] : gitInfoCached
}
File renamed without changes.
2 changes: 1 addition & 1 deletion modloader/modloader.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<PropertyGroup>
<TargetFramework>net35</TargetFramework>
<AssemblyName>modloader</AssemblyName>
<Description>My first plugin</Description>
<Description>Small loader for patched assemblies</Description>
<Version>1.0.0</Version>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<LangVersion>latest</LangVersion>
Expand Down
56 changes: 15 additions & 41 deletions src/main/java/com/juanmuscaria/dmm/ModManagerApplication.java
Original file line number Diff line number Diff line change
@@ -1,53 +1,27 @@
package com.juanmuscaria.dmm;

import com.juanmuscaria.dmm.util.DialogHelper;
import com.juanmuscaria.dmm.util.DuskersHelper;
import com.juanmuscaria.dmm.event.FXEvent;
import io.micronaut.context.ApplicationContext;
import io.micronaut.context.event.ApplicationEventPublisher;
import jakarta.inject.Singleton;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;

import atlantafx.base.theme.CupertinoLight;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.nio.file.Path;
import java.util.Objects;

@Singleton
public class ModManagerApplication extends Application {
private static final Logger logger = LoggerFactory.getLogger(ModManagerApplication.class);
@Override
public void start(Stage stage) {
setUserAgentStylesheet(new CupertinoLight().getUserAgentStylesheet());
try {
Scene scene;
if (DuskersHelper.isInstalled(Path.of(".")) || Boolean.getBoolean("dmm.forceLauncher")) {
scene = new Scene(FXMLLoader.load(
Objects.requireNonNull(getClass().getResource("/ui/duskers_launcher.fxml"),
"Unable to load JavaFX resources")));
stage.setTitle("Duskers Mod Manager");
} else {
scene = new Scene(FXMLLoader.load(
Objects.requireNonNull(getClass().getResource("/ui/installer.fxml"),
"Unable to load JavaFX resources")));
stage.setTitle("Duskers Mod Manager Installer");
}
stage.setScene(scene);
stage.show();
stage.setMinWidth(stage.getWidth());
stage.setMinHeight(stage.getHeight());
} catch (Throwable e) {
logger.error("Unable to start GUI", e);
DialogHelper.reportAndExit(e);
}
static ApplicationContext context;

public ModManagerApplication() {
}

public static void main(String[] args) {
launch(args);
@Override
public void init() {
context.registerSingleton(this);
context.getEventPublisher(FXEvent.FXInit.class).publishEvent(new FXEvent.FXInit(this));
}

public static Path getSelfPath() {
return Path.of(ModManagerApplication.class.getProtectionDomain()
.getCodeSource().getLocation().getPath()).toAbsolutePath();
@Override
public void start(Stage primaryStage) {
context.getEventPublisher(FXEvent.FXStart.class).publishEvent(new FXEvent.FXStart(this, primaryStage));
}
}
16 changes: 9 additions & 7 deletions src/main/java/com/juanmuscaria/dmm/ModManagerCommand.java
Original file line number Diff line number Diff line change
@@ -1,32 +1,34 @@
package com.juanmuscaria.dmm;

import io.micronaut.configuration.picocli.PicocliRunner;
import org.graalvm.nativeimage.IsolateThread;
import io.micronaut.context.ApplicationContext;
import io.micronaut.core.annotation.ReflectiveAccess;
import jakarta.inject.Inject;
import picocli.CommandLine.Command;
import picocli.CommandLine.Help.Ansi;
import picocli.CommandLine.Option;

import org.graalvm.nativeimage.c.function.CEntryPoint;
import java.util.concurrent.CountDownLatch;

@Command(name = "dmm", description = "...",
mixinStandardHelpOptions = true)
public class ModManagerCommand implements Runnable {
public static final CountDownLatch stopLatch = new CountDownLatch(1);
@Inject
@ReflectiveAccess
protected ApplicationContext context;
@Option(names = {"--no-gui", "-G"}, description = "Enables CLI mode", defaultValue = "false")
boolean noGui;

public static void main(String[] args) {
PicocliRunner.run(ModManagerCommand.class, args);
}

@CEntryPoint(name = "dmm_main")
public static void dmm_main(IsolateThread thread) {
ModManagerApplication.launch(ModManagerApplication.class);
}

public void run() {
if (noGui) {
System.out.println(Ansi.AUTO.string("@|red CLI mode is not implemented yet!|@"));
} else {
ModManagerApplication.context = context;
ModManagerApplication.launch(ModManagerApplication.class);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import static io.micronaut.core.annotation.TypeHint.AccessType.*;

@ReflectionConfig(type = org.fusesource.jansi.AnsiConsole.class, accessType = {ALL_PUBLIC, ALL_DECLARED_CONSTRUCTORS, ALL_DECLARED_FIELDS, ALL_DECLARED_METHODS})
@ReflectionConfig(type = java.util.concurrent.ConcurrentSkipListSet.class, accessType = {ALL_PUBLIC, ALL_DECLARED_CONSTRUCTORS, ALL_DECLARED_FIELDS, ALL_DECLARED_METHODS})
@ReflectionConfig(type = javafx.geometry.Insets.class, accessType = {ALL_PUBLIC, ALL_DECLARED_CONSTRUCTORS, ALL_DECLARED_FIELDS, ALL_DECLARED_METHODS})
@ReflectionConfig(type = javafx.scene.control.Button.class, accessType = {ALL_PUBLIC, ALL_DECLARED_CONSTRUCTORS, ALL_DECLARED_FIELDS, ALL_DECLARED_METHODS})
@ReflectionConfig(type = javafx.scene.control.ComboBox.class, accessType = {ALL_PUBLIC, ALL_DECLARED_CONSTRUCTORS, ALL_DECLARED_FIELDS, ALL_DECLARED_METHODS})
Expand Down Expand Up @@ -52,6 +53,12 @@
@ReflectionConfig(type = javafx.scene.control.TextArea.class, accessType = {ALL_PUBLIC, ALL_DECLARED_CONSTRUCTORS, ALL_DECLARED_FIELDS, ALL_DECLARED_METHODS})
@ReflectionConfig(type = javafx.scene.control.TextInputControl.class, accessType = {ALL_PUBLIC, ALL_DECLARED_CONSTRUCTORS, ALL_DECLARED_FIELDS, ALL_DECLARED_METHODS})
@ReflectionConfig(type = javafx.scene.layout.AnchorPane.class, accessType = {ALL_PUBLIC, ALL_DECLARED_CONSTRUCTORS, ALL_DECLARED_FIELDS, ALL_DECLARED_METHODS})
@ReflectionConfig(type = javafx.scene.control.ListView.class, accessType = {ALL_PUBLIC, ALL_DECLARED_CONSTRUCTORS, ALL_DECLARED_FIELDS, ALL_DECLARED_METHODS})
@ReflectionConfig(type = javafx.scene.control.ScrollPane.class, accessType = {ALL_PUBLIC, ALL_DECLARED_CONSTRUCTORS, ALL_DECLARED_FIELDS, ALL_DECLARED_METHODS})
@ReflectionConfig(type = javafx.scene.control.ScrollPane.ScrollBarPolicy.class, accessType = {ALL_PUBLIC, ALL_DECLARED_CONSTRUCTORS, ALL_DECLARED_FIELDS, ALL_DECLARED_METHODS})
@ReflectionConfig(type = javafx.scene.layout.ColumnConstraints.class, accessType = {ALL_PUBLIC, ALL_DECLARED_CONSTRUCTORS, ALL_DECLARED_FIELDS, ALL_DECLARED_METHODS})
@ReflectionConfig(type = javafx.scene.layout.GridPane.class, accessType = {ALL_PUBLIC, ALL_DECLARED_CONSTRUCTORS, ALL_DECLARED_FIELDS, ALL_DECLARED_METHODS})
@ReflectionConfig(type = javafx.scene.layout.RowConstraints.class, accessType = {ALL_PUBLIC, ALL_DECLARED_CONSTRUCTORS, ALL_DECLARED_FIELDS, ALL_DECLARED_METHODS})
//@ReflectionConfig(type = .class, accessType = {ALL_PUBLIC, ALL_DECLARED_CONSTRUCTORS, ALL_DECLARED_FIELDS, ALL_DECLARED_METHODS})
public class JavaFXReflectionConfig {
public class ReflectiveConfig {
}
34 changes: 34 additions & 0 deletions src/main/java/com/juanmuscaria/dmm/data/ModEntry.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.juanmuscaria.dmm.data;

import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import io.micronaut.core.annotation.ReflectiveAccess;
import lombok.*;
import lombok.EqualsAndHashCode.Exclude;
import lombok.extern.jackson.Jacksonized;

import java.nio.file.Path;

@JsonSerialize
@AllArgsConstructor
@Builder
@Jacksonized
@Getter
@Setter
@EqualsAndHashCode
@ToString
@ReflectiveAccess
public class ModEntry implements Comparable<ModEntry> {
@ReflectiveAccess
private final String modPath;
@Exclude
@ReflectiveAccess
private final ModMetadata metadata;
@Exclude // We don't want to compare state
@ReflectiveAccess
private boolean enabled;

@Override
public int compareTo(ModEntry other) {
return this.getModPath().compareTo(other.getModPath());
}
}
48 changes: 48 additions & 0 deletions src/main/java/com/juanmuscaria/dmm/data/ModList.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.juanmuscaria.dmm.data;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import io.micronaut.core.annotation.ReflectiveAccess;
import javafx.collections.FXCollections;
import javafx.collections.ObservableSet;
import lombok.Getter;
import lombok.ToString;

import java.util.concurrent.ConcurrentSkipListSet;

@JsonSerialize
@ToString
@ReflectiveAccess
public class ModList {
/**
* This will be the actual backing set that will be written to disk, it must be both thread safe and sorted
*/
@JsonProperty("mods")
@ReflectiveAccess
private ConcurrentSkipListSet<ModEntry> backend;

/**
* Observable wrapper to be used with javafx, changes must be done on the platform thread
*/
@JsonIgnore
@Getter
private ObservableSet<ModEntry> mods;

public ModList() {
this(new ConcurrentSkipListSet<>());
}

public ModList(ConcurrentSkipListSet<ModEntry> mods) {
this.backend = mods;
this.mods = FXCollections.observableSet(backend);
}

/**
* Will be called by jackson
*/
protected void setBackend(ConcurrentSkipListSet<ModEntry> backend) {
this.backend = backend;
this.mods = FXCollections.observableSet(backend);
}
}
10 changes: 10 additions & 0 deletions src/main/java/com/juanmuscaria/dmm/data/ModMetadata.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.juanmuscaria.dmm.data;

import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import io.micronaut.core.annotation.ReflectiveAccess;

@JsonSerialize
@ReflectiveAccess
public record ModMetadata(String name, String id, String version) {
}

28 changes: 28 additions & 0 deletions src/main/java/com/juanmuscaria/dmm/event/FXEvent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.juanmuscaria.dmm.event;

import io.micronaut.context.event.ApplicationEvent;
import io.micronaut.core.annotation.NonNull;
import javafx.stage.Stage;
import lombok.Getter;

public class FXEvent extends ApplicationEvent {
public FXEvent(Object source) {
super(source);
}

public static class FXInit extends FXEvent {
public FXInit(Object source) {
super(source);
}
}

@Getter
public static class FXStart extends @NonNull FXEvent {
private final Stage primaryStage;

public FXStart(Object source, Stage primaryStage) {
super(source);
this.primaryStage = primaryStage;
}
}
}
20 changes: 20 additions & 0 deletions src/main/java/com/juanmuscaria/dmm/service/FXMLLoaderFactory.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.juanmuscaria.dmm.service;

import io.micronaut.context.ApplicationContext;
import io.micronaut.context.annotation.Factory;
import io.micronaut.context.annotation.Prototype;
import jakarta.inject.Inject;
import javafx.fxml.FXMLLoader;

@Factory
class FXMLLoaderFactory {
@Inject
protected ApplicationContext context;

@Prototype
public FXMLLoader getLoader() {
var loader = new FXMLLoader();
loader.setControllerFactory(context::getBean);
return loader;
}
}
Loading

0 comments on commit baf7f71

Please sign in to comment.