diff --git a/.gitignore b/.gitignore
index 254749d..aaf2c13 100644
--- a/.gitignore
+++ b/.gitignore
@@ -118,6 +118,7 @@ $RECYCLE.BIN/
# IntelliJ
/out/
+.idea/
# mpeltonen/sbt-idea plugin
.idea_modules/
diff --git a/build.gradle b/build.gradle
index 6dbb083..9d3f879 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,39 +1,34 @@
buildscript {
repositories {
- jcenter()
mavenCentral()
- maven {
- url 'http://maven.ferenyr.info/artifactory/plugins-release'
- credentials {
- username = "${artifactory_user}"
- password = "${artifactory_password}"
- }
- }
}
dependencies {
- classpath "org.jfrog.buildinfo:build-info-extractor-gradle:4.0.0"
}
}
repositories {
- mavenCentral()
- maven {
- url = 'https://oss.sonatype.org/content/repositories/releases/'
- }
- maven {
- url "http://files.minecraftforgefrance.fr/maven/"
- }
- maven {
- url = 'https://oss.sonatype.org/content/repositories/snapshots/'
- }
+ mavenCentral()
+ maven {
+ url = 'https://oss.sonatype.org/content/repositories/releases/'
}
+ maven {
+ url "http://files.minecraftforgefrance.fr/maven/"
+ }
+ maven {
+ url = 'https://oss.sonatype.org/content/repositories/snapshots/'
+ }
+ maven {
+ name = "leviathan"
+ url = "http://maven.ferenyr.info/artifactory/Leviathan/"
+ }
+}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
group = "com.leviathanstudio.mineide"
-archivesBaseName = 'MineIDE-Compiler'
+archivesBaseName = 'MineIDE-UI'
version = '0.0.1'
compileJava.options.encoding = 'UTF-8'
sourceCompatibility = 1.8
@@ -51,34 +46,19 @@ sourceSets {
}
dependencies {
+ compile group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.5'
+ compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.5'
+ compile group: 'com.leviathanstudio.mineide', name: 'MineIDE-Compiler', version: '0.0.1'
+ compile 'com.google.code.gson:gson:2.7'
+ compile 'de.jensd:fontawesomefx:8.9'
+ compile 'com.jfoenix:jfoenix:0.0.0-SNAPSHOT'
+ compile 'utybo:minkj:1.0'
+ compile 'com.squareup:javapoet:1.7.0'
+ compile 'org.reflections:reflections:0.9.10'
+
+ compile group: 'org.codehaus.groovy', name: 'groovy-all', version: '2.4.7'
}
task wrapper(type: Wrapper) {
gradleVersion = '2.13'
-}
-
-apply plugin: 'maven-publish'
-apply plugin: 'com.jfrog.artifactory'
-
-artifactory {
- contextUrl = "${artifactory_contextUrl}"
- publish {
- repository {
- repoKey = 'Leviathan'
- username = "${artifactory_user}"
- password = "${artifactory_password}"
- maven = true
- }
- defaults {
- publications ('mavenJava')
- }
- }
-}
-
-publishing {
- publications {
- mavenJava(MavenPublication) {
- from components.java
- }
- }
}
\ No newline at end of file
diff --git a/runtime/TestGroovyPlugin.groovy b/runtime/TestGroovyPlugin.groovy
new file mode 100644
index 0000000..33d82da
--- /dev/null
+++ b/runtime/TestGroovyPlugin.groovy
@@ -0,0 +1,32 @@
+import com.leviathanstudio.plugin.MineIDEPlugin
+import com.leviathanstudio.plugin.PluginInfos
+
+class TestGroovyPlugin extends MineIDEPlugin {
+ @Override
+ void populateInfos(PluginInfos infos) {
+ infos.authors = {"jglrxavpok"}
+ infos.credits = {"jglrxavpok"}
+ infos.description = "A test plugin made in Groovy"
+ infos.name = {"Groovy Test Plugin"}
+ }
+
+ @Override
+ void onPrePluginInit() {
+ logger.info("Hi from pre-init in Groovy!")
+ }
+
+ @Override
+ void onPluginInit() {
+ logger.info("Hi from init in Groovy!")
+ }
+
+ @Override
+ void onPostPluginInit() {
+ logger.info("Hi from post-init in Groovy!")
+ }
+
+ @Override
+ String getID() {
+ return "test_groovy"
+ }
+}
diff --git a/src/main/java/com/leviathanstudio/plugin/MineIDEPlugin.java b/src/main/java/com/leviathanstudio/plugin/MineIDEPlugin.java
index faa2d59..1abde2e 100644
--- a/src/main/java/com/leviathanstudio/plugin/MineIDEPlugin.java
+++ b/src/main/java/com/leviathanstudio/plugin/MineIDEPlugin.java
@@ -1,127 +1,70 @@
package com.leviathanstudio.plugin;
+import org.apache.logging.log4j.Logger;
+
import java.util.ArrayList;
import java.util.List;
+/**
+ * Represents a MineIDE plugin. Loaded at the launch of the {@link PluginSystem Plugin System}.
+ * Starting point of any plugin.
+ * WARNING: In order for your plugin to be loaded, its core class must extend with one.
+ *
+ */
public abstract class MineIDEPlugin
{
- private String pluginName, pluginDescription, pluginAuthor, pluginCredits;
- private List nullPluginList = new ArrayList();
- private boolean informationIncomplete;
-
- public String getPluginName()
- {
- return pluginName;
- }
-
- public void setPluginName(String pluginName)
- {
- this.pluginName = pluginName;
- }
-
- public String getPluginDescription()
- {
- return pluginDescription;
- }
-
- public void setPluginDescription(String pluginDescription)
- {
- this.pluginDescription = pluginDescription;
- }
-
- public String getPluginAuthor()
- {
- return pluginAuthor;
- }
-
- public void setPluginAuthor(String pluginAuthor)
- {
- this.pluginAuthor = pluginAuthor;
- }
-
- public String getPluginCredits()
- {
- return pluginCredits;
- }
-
- public void setPluginCredits(String pluginCredits)
- {
- this.pluginCredits = pluginCredits;
- }
-
- public boolean isInformationIncomplete()
- {
- return informationIncomplete;
- }
-
- public void setInformationIncomplete(boolean informationIncomplete)
- {
- this.informationIncomplete = informationIncomplete;
- }
-
- public abstract void preInitPlugin();
-
- public abstract void initPlugin();
-
- public abstract void initPlugin(String[] args);
-
- public void executePlugin()
- {
- this.preInitPlugin();
- this.checkPluginInformation();
-
- if(!this.isInformationIncomplete())
- {
- this.initPlugin();
- }
- else
- {
- System.err.println("[MineIDE-Plugin] Incomplete Plugin Information {");
- for(int i = 0; i < nullPluginList.size(); i++)
- System.err.println(nullPluginList.get(i));
-
- System.err.println("}");
- }
- }
-
- public void executePlugin(String[] args)
+ /**
+ * The informations about the plugin, filled at pre-initialization and by {@link #populateInfos(PluginInfos)}
+ */
+ protected PluginInfos infos;
+
+ /**
+ * The logger dedicated to this plugin, assigned at loading
+ */
+ protected Logger logger;
+
+ public MineIDEPlugin()
{
- this.preInitPlugin();
- this.checkPluginInformation();
-
- if(!this.isInformationIncomplete())
- this.initPlugin(args);
- else
- {
- System.err.println("[MineIDE-Plugin] Incomplete Plugin Information {");
- for(int i = 0; i < nullPluginList.size(); i++)
- System.err.println(nullPluginList.get(i));
-
- System.err.println("}");
- }
+
}
-
- private void checkPluginInformation()
+
+ /**
+ * Populate the infos object with informations about this mod.
+ * @param infos
+ * The object storing the informations
+ */
+ public abstract void populateInfos(PluginInfos infos);
+
+ /**
+ * Called before all plugins are initialized
+ */
+ public abstract void onPrePluginInit();
+
+ /**
+ * Called when the plugin needs to initialize
+ */
+ public abstract void onPluginInit();
+
+ /**
+ * Called after all plugins have been initialized
+ */
+ public abstract void onPostPluginInit();
+
+ /**
+ * Returns the ID of this mod.
+ * To be consistent across plugins, follow the snake case naming convention (e.g. "test_plugin", "my_super_duper_awesome_plugin", etc.)
+ * @return
+ * The ID of this mod
+ */
+ public abstract String getID();
+
+ /**
+ * Called when an exception is raised because of this mod, prints the error message by default
+ * @param e
+ * The exception
+ */
+ public void onPluginException(Exception e)
{
- if(this.getPluginName() == null || this.getPluginName().isEmpty())
- {
- nullPluginList.add("Plugin Name is null or empty");
- this.setInformationIncomplete(true);
- }
- else if(this.getPluginAuthor() == null || this.getPluginAuthor().isEmpty())
- {
- nullPluginList.add("Plugin Author is null or empty");
- this.setInformationIncomplete(true);
- }
- else if(this.getPluginDescription() == null || this.getPluginDescription().isEmpty())
- {
- nullPluginList.add("Plugin Description is null or empty");
- this.setInformationIncomplete(true);
- }
- else if(this.getPluginCredits() == null || this.getPluginCredits().isEmpty())
- {
- nullPluginList.add("Plugin Credits is null or empty");
- this.setInformationIncomplete(true);
- }
+ logger.error("Plugin crashed, ask the developer(s):", e);
}
}
\ No newline at end of file
diff --git a/src/main/java/com/leviathanstudio/plugin/PluginInfos.java b/src/main/java/com/leviathanstudio/plugin/PluginInfos.java
new file mode 100644
index 0000000..7bde329
--- /dev/null
+++ b/src/main/java/com/leviathanstudio/plugin/PluginInfos.java
@@ -0,0 +1,118 @@
+package com.leviathanstudio.plugin;
+
+import java.util.Arrays;
+
+/**
+ * Object storing all the informations about a plugin
+ */
+public class PluginInfos
+{
+ private final MineIDEPlugin plugin;
+ private String id;
+ private PluginState state;
+ private String name;
+ private String[] authors;
+ private String[] credits;
+ private String description;
+
+ /**
+ * The constructor, should not be called outside of {@link PluginSystem}
+ * @param plugin
+ */
+ PluginInfos(MineIDEPlugin plugin)
+ {
+ state = PluginState.UNLOADED;
+ this.plugin = plugin;
+ authors = new String[] {"unknown"};
+ credits = Arrays.copyOf(authors, authors.length);
+ description = "";
+ name = plugin.getClass().getSimpleName();
+ id = name.toLowerCase();
+ }
+
+ /**
+ * Returns the instance of the represented mod
+ * @return
+ * The instance of the mod
+ */
+ public MineIDEPlugin getInstance()
+ {
+ return plugin;
+ }
+
+ /**
+ * Returns the ID of the mod
+ * @return
+ * The ID of the mod
+ */
+ public String getID()
+ {
+ return id;
+ }
+
+ public void setID(String id)
+ {
+ this.id = id;
+ }
+
+ public String[] getAuthors()
+ {
+ return authors;
+ }
+
+ public String[] getCredits()
+ {
+ return credits;
+ }
+
+ public String getDescription()
+ {
+ return description;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public PluginState getState()
+ {
+ return state;
+ }
+
+ public void setName(String pluginName)
+ {
+ this.name = pluginName;
+ }
+
+ public void setAuthors(String... pluginAuthor)
+ {
+ this.authors = pluginAuthor;
+ }
+
+ public void setCredits(String... pluginCredits)
+ {
+ this.credits = pluginCredits;
+ }
+
+ public void setDescription(String pluginDescription)
+ {
+ this.description = pluginDescription;
+ }
+
+ public void setState(PluginState pluginState)
+ {
+ this.state = pluginState;
+ }
+
+ /**
+ * Order: UNLOADED->UNINITIALIZED->INITIALIZED->LOADED
+ */
+ public enum PluginState
+ {
+ UNLOADED,
+ UNINITIALIZED,
+ INITIALIZED,
+ LOADED
+ }
+}
diff --git a/src/main/java/com/leviathanstudio/plugin/PluginSystem.java b/src/main/java/com/leviathanstudio/plugin/PluginSystem.java
new file mode 100644
index 0000000..eb51850
--- /dev/null
+++ b/src/main/java/com/leviathanstudio/plugin/PluginSystem.java
@@ -0,0 +1,314 @@
+package com.leviathanstudio.plugin;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.reflect.ClassPath;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+import groovy.lang.GroovyClassLoader;
+import groovy.lang.GroovyCodeSource;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.reflections.Reflections;
+import org.reflections.util.ClasspathHelper;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import java.util.function.Consumer;
+
+/**
+ * The Plugin System is the entity that handles loading, initialization and coordination of plugins.
+ * Plugins can be loaded from a folder as ".jar" files or from the classpath
+ */
+public class PluginSystem
+{
+
+ /**
+ * Used as a placeholder while loading the plugins. Prevents crashes if a plugin tries to access its logger before
+ * being initialized or after an exception preventing said plugin to properly load
+ */
+ private final Logger temporaryLogger;
+ private final GroovyClassLoader groovyLoader;
+ private File pluginFolder;
+ private static PluginSystem instance;
+ private List loadedPlugins;
+
+ /**
+ * Creates a new plugin system
+ * @param pluginFolder
+ */
+ private PluginSystem(File pluginFolder)
+ {
+ loadedPlugins = new ArrayList<>();
+ this.pluginFolder = pluginFolder;
+ temporaryLogger = LogManager.getLogger(this);
+ groovyLoader = new GroovyClassLoader(getClass().getClassLoader());
+ }
+
+ /**
+ * Returns the folder used to search for plugins
+ * @return
+ * The folder to search plugins in
+ */
+ public File getPluginFolder()
+ {
+ return pluginFolder;
+ }
+
+ /**
+ * Starts the Plugin System, loads the plugins and returns the created instance.
+ * Warning: It is only possible to have one instance of a Plugin System at a time
+ * @param pluginFolder
+ * The folder to search plugins in, can be null for none
+ * @return
+ * The created instance
+ *
+ * @throws IllegalStateException
+ * If an instance already exists
+ */
+ public static PluginSystem kickoff(File pluginFolder)
+ {
+ if(instance == null)
+ {
+ PluginSystem system = new PluginSystem(pluginFolder);
+ instance = system;
+ system.loadPluginFromFolder();
+ system.loadPluginFromClasspath();
+ return system;
+ }
+ else
+ {
+ throw new IllegalStateException("The plugin system is a singleton, don't try to start it twice!");
+ }
+ }
+
+ /**
+ * Checks if a given plugin has been found by the system
+ * @param id
+ * The ID of the plugin
+ * @return
+ * true if the plugin is present, false otherwise
+ */
+ public boolean isPluginPresent(String id)
+ {
+ return getPlugin(id).isPresent();
+ }
+
+ /**
+ * Checks if a given plugin has been found by the system and loaded
+ * @param id
+ * The ID of the plugin
+ * @return
+ * true if the plugin is loaded, false otherwise
+ */
+ public boolean isPluginLoaded(String id)
+ {
+ Optional plugin = getPlugin(id);
+ if(plugin.isPresent())
+ {
+ return plugin.get().infos.getState() == PluginInfos.PluginState.LOADED;
+ }
+ return false;
+ }
+
+ /**
+ * Returns a potential plugin with the given id
+ * @param id
+ * The id of the plugin
+ * @return
+ * The potential plugin
+ */
+ public Optional getPlugin(String id)
+ {
+ return loadedPlugins.stream()
+ .filter(p -> p.getID().equals(id))
+ .findFirst();
+ }
+
+ private void loadPluginFromClasspath()
+ {
+ loadGroovyPlugins();
+
+ Reflections reflections = new Reflections(Thread.currentThread().getContextClassLoader());
+ for(Class extends MineIDEPlugin> pluginClass : reflections.getSubTypesOf(MineIDEPlugin.class))
+ {
+ loadPluginClass(pluginClass);
+ }
+ }
+
+ private void loadPluginClass(Class extends MineIDEPlugin> pluginClass)
+ {
+ try
+ {
+ MineIDEPlugin plugin = pluginClass.newInstance();
+ PluginInfos infos = new PluginInfos(plugin);
+ infos.setID(plugin.getID());
+ plugin.logger = temporaryLogger;
+
+ Package pluginPackage = pluginClass.getPackage();
+ if(pluginPackage != null)
+ {
+ String path = "/"+pluginPackage.getName().replace(".", "/")+"/plugin_infos.json";
+ InputStream stream = PluginSystem.class.getResourceAsStream(path);
+ if(stream != null)
+ {
+ try
+ {
+ Gson gson = new GsonBuilder().setLenient().create();
+ JsonObject pluginInfos = gson.fromJson(new InputStreamReader(stream), JsonObject.class);
+
+ JsonArray authors = pluginInfos.getAsJsonArray("authors");
+ String[] authorList = new String[authors.size()];
+ for (int i = 0; i < authorList.length; i++)
+ {
+ authorList[i] = authors.get(i).getAsString();
+ }
+ infos.setAuthors(authorList);
+
+ JsonArray credits = pluginInfos.getAsJsonArray("credits");
+ String[] creditsList = new String[authors.size()];
+ for (int i = 0; i < creditsList.length; i++)
+ {
+ creditsList[i] = credits.get(i).getAsString();
+ }
+ infos.setCredits(creditsList);
+
+ infos.setName(pluginInfos.get("name").getAsString());
+ infos.setDescription(pluginInfos.get("description").getAsString());
+ }
+ catch (Exception e)
+ {
+ plugin.onPluginException(e);
+ }
+ finally
+ {
+ try
+ {
+ stream.close();
+ }
+ catch (IOException e)
+ {
+ }
+ }
+ }
+ else
+ {
+ temporaryLogger.info("Could not find plugin_infos.json for "+plugin.getClass().getCanonicalName()+
+ " with path: "+path+". Automatic info loading could not be performed for this plugin");
+ }
+ }
+
+ plugin.populateInfos(infos);
+ plugin.logger = LogManager.getLogger(infos.getName());
+ plugin.infos = infos;
+ loadedPlugins.add(plugin);
+ }
+ catch (InstantiationException | IllegalAccessException e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ private void loadGroovyPlugins()
+ {
+ try
+ {
+ ImmutableSet resources = ClassPath.from(getClass().getClassLoader()).getResources();
+ for(ClassPath.ResourceInfo info : resources)
+ {
+ if(info.getResourceName().endsWith(".groovy"))
+ {
+ loadGroovyPlugin(info.url());
+ }
+ }
+ } catch (IOException e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ private void loadGroovyPlugin(URL url)
+ {
+ GroovyCodeSource source = new GroovyCodeSource(url);
+ Class> clazz = groovyLoader.parseClass(source);
+ if(clazz.getSuperclass().equals(MineIDEPlugin.class))
+ {
+ loadPluginClass((Class extends MineIDEPlugin>) clazz);
+ }
+ }
+
+ private void loadPluginFromFolder()
+ {
+ if(pluginFolder == null)
+ return;
+ File[] subfiles = pluginFolder.listFiles(f -> f.getName().endsWith(".jar") || f.getName().endsWith(".zip") || f.getName().endsWith(".groovy"));
+ if(subfiles != null && subfiles.length > 0)
+ {
+ URLClassLoader loader = URLClassLoader.newInstance(new URL[0], getClass().getClassLoader());
+ try
+ {
+ Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
+ method.setAccessible(true);
+ for(File f : subfiles)
+ {
+ try
+ {
+ if(f.getName().endsWith(".groovy"))
+ {
+ loadGroovyPlugin(f.toURI().toURL());
+ }
+ else
+ {
+ method.invoke(loader, f.toURI().toURL());
+ }
+ }
+ catch (IOException | InvocationTargetException | IllegalAccessException e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+ catch (NoSuchMethodException e)
+ {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ /**
+ * Launches the initialization process of plugins
+ */
+ public void initPlugins()
+ {
+ forAllPlugins(p -> p.infos.setState(PluginInfos.PluginState.UNINITIALIZED));
+ forAllPlugins(MineIDEPlugin::onPrePluginInit);
+ forAllPlugins(MineIDEPlugin::onPluginInit);
+ forAllPlugins(p -> p.infos.setState(PluginInfos.PluginState.INITIALIZED));
+ forAllPlugins(MineIDEPlugin::onPostPluginInit);
+ forAllPlugins(p -> p.infos.setState(PluginInfos.PluginState.LOADED));
+ }
+
+ private void forAllPlugins(Consumer action)
+ {
+ loadedPlugins.forEach(p -> {
+ try
+ {
+ action.accept(p);
+ }
+ catch (Exception e)
+ {
+ p.onPluginException(e);
+ }
+ });
+ }
+}
diff --git a/src/main/java/com/leviathanstudio/plugin/RunPluginTest.java b/src/main/java/com/leviathanstudio/plugin/RunPluginTest.java
deleted file mode 100644
index 2d7f4af..0000000
--- a/src/main/java/com/leviathanstudio/plugin/RunPluginTest.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package com.leviathanstudio.plugin;
-
-import plugin.fr.scarex.obfuscatednamefinder.ui.ObfuscatedNameFinderFrame;
-
-public class RunPluginTest extends MineIDEPlugin
-{
-
- @Override
- public void preInitPlugin()
- {
- this.setPluginName("Obfuscated Name Finder");
- this.setPluginAuthor("SCAREX");
- this.setPluginCredits("SCAREX");
- this.setPluginDescription("Simple plugin to find the properly name of an obfuscated field or method");
- System.out.println(this.getPluginAuthor() + System.lineSeparator() + this.getPluginName() + System.lineSeparator() + this.getPluginDescription() + System.lineSeparator() + this.getPluginCredits());
- }
-
- @Override
- public void initPlugin()
- {}
-
- @Override
- public void initPlugin(String[] args)
- {
- ObfuscatedNameFinderFrame.main(args);
- }
-
- // Debug
- public static void main(String[] args)
- {
- RunPluginTest test = new RunPluginTest();
- test.executePlugin(args);
- test.executePlugin();
- }
-
-}
diff --git a/src/main/java/plugin/fr/scarex/obfuscatednamefinder/ui/ObfuscatedNameFinderFrame.java b/src/main/java/plugin/fr/scarex/obfuscatednamefinder/ui/ObfuscatedNameFinderFrame.java
index 231e044..1f261ac 100644
--- a/src/main/java/plugin/fr/scarex/obfuscatednamefinder/ui/ObfuscatedNameFinderFrame.java
+++ b/src/main/java/plugin/fr/scarex/obfuscatednamefinder/ui/ObfuscatedNameFinderFrame.java
@@ -50,7 +50,7 @@ public void start(Stage stage) throws Exception
searchTextField.setTooltip(new Tooltip("Name of field/method to find"));
ArrayList data = new ArrayList();
if(this.forgeVersions.get(this.forgeVersionComboBox.getItems().size()).getName().startsWith("1.8"))
- data = parseCSV(new File(this.getGradleLocation(), "caches/minecraft/de/oceanlabs/mcp/mcp_snapshot/" + (new File(this.forgeVersions.get(this.forgeVersionComboBox.getItems().size()), "snapshot")).list()[0] + "/" + ((String)this.typeList) + ".csv"));
+ data = parseCSV(new File(this.getGradleLocation(), "caches/minecraft/de/oceanlabs/mcp/mcp_snapshot/" + (new File(this.forgeVersions.get(this.forgeVersionComboBox.getItems().size()), "snapshot")).list()[0] + "/" + ((String)this.typeList.getItems().get(0)) + ".csv"));
else
data = parseCSV(new File(this.forgeVersions.get(this.forgeVersionComboBox.getItems().size()), "unpacked/conf/" + ((String)this.typeList.getPromptText()) + ".csv"));
this.csvData.clear();
diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml
new file mode 100644
index 0000000..fbf8394
--- /dev/null
+++ b/src/main/resources/log4j2.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/test/java/com/leviathanstudio/plugin/RunnableTestPlugin.java b/src/test/java/com/leviathanstudio/plugin/RunnableTestPlugin.java
new file mode 100644
index 0000000..0aedae0
--- /dev/null
+++ b/src/test/java/com/leviathanstudio/plugin/RunnableTestPlugin.java
@@ -0,0 +1,54 @@
+package com.leviathanstudio.plugin;
+
+import plugin.fr.scarex.obfuscatednamefinder.ui.ObfuscatedNameFinderFrame;
+
+import java.io.File;
+import java.util.Arrays;
+
+public class RunnableTestPlugin extends MineIDEPlugin
+{
+
+ @Override
+ public void populateInfos(PluginInfos infos)
+ {
+ infos.setName("Obfuscated Name Finder");
+ infos.setAuthors("SCAREX");
+ infos.setCredits("SCAREX");
+ infos.setDescription("Simple plugin to find the properly name of an obfuscated field or method");
+ }
+
+ @Override
+ public void onPrePluginInit()
+ {
+ logger.info("Name: "+infos.getName());
+ logger.info("Authors:" + Arrays.toString(infos.getAuthors()));
+ logger.info("Credits:" + Arrays.toString(infos.getCredits()));
+ logger.info("Description: "+infos.getDescription());
+ }
+
+ @Override
+ public void onPluginInit()
+ {
+ ObfuscatedNameFinderFrame.main(new String[0]);
+ }
+
+ @Override
+ public void onPostPluginInit()
+ {
+
+ }
+
+ @Override
+ public String getID()
+ {
+ return "obfuscated_name_finder";
+ }
+
+ // Debug
+ public static void main(String[] args)
+ {
+ PluginSystem pluginSystem = PluginSystem.kickoff(new File("./runtime"));
+ pluginSystem.initPlugins();
+ }
+
+}
diff --git a/src/test/java/com/leviathanstudio/plugin/testplugin/TestPlugin.java b/src/test/java/com/leviathanstudio/plugin/testplugin/TestPlugin.java
new file mode 100644
index 0000000..a165fda
--- /dev/null
+++ b/src/test/java/com/leviathanstudio/plugin/testplugin/TestPlugin.java
@@ -0,0 +1,44 @@
+package com.leviathanstudio.plugin.testplugin;
+
+import com.leviathanstudio.plugin.MineIDEPlugin;
+import com.leviathanstudio.plugin.PluginInfos;
+
+import java.util.Arrays;
+
+public class TestPlugin extends MineIDEPlugin
+{
+ @Override
+ public void populateInfos(PluginInfos infos)
+ {
+ ; // nop, done automatically via plugin_infos.json
+ }
+
+ @Override
+ public void onPrePluginInit()
+ {
+ logger.debug("Hi from the pre-initialisation method!");
+ logger.debug("Infos are:");
+ logger.debug("\tName: "+infos.getName());
+ logger.debug("\tDescription: "+infos.getDescription());
+ logger.debug("\tAuthors: "+ Arrays.toString(infos.getAuthors()));
+ logger.debug("\tCredits: "+ Arrays.toString(infos.getCredits()));
+ }
+
+ @Override
+ public void onPluginInit()
+ {
+ logger.debug("Hi from the initialisation method!");
+ }
+
+ @Override
+ public void onPostPluginInit()
+ {
+ logger.debug("Hi from the post-initialisation method!");
+ }
+
+ @Override
+ public String getID()
+ {
+ return "test_plugin";
+ }
+}
diff --git a/src/test/resources/com/leviathanstudio/plugin/testplugin/plugin_infos.json b/src/test/resources/com/leviathanstudio/plugin/testplugin/plugin_infos.json
new file mode 100644
index 0000000..e97fb05
--- /dev/null
+++ b/src/test/resources/com/leviathanstudio/plugin/testplugin/plugin_infos.json
@@ -0,0 +1,6 @@
+{
+ "authors": ["jglrxavpok"],
+ "credits": ["jglrxavpok", "The Leviathan-Studio Team"],
+ "name": "Test plugin",
+ "description": "Just a simple test plugin to implement new features into the plugin system"
+}
\ No newline at end of file