mirror of
https://github.com/Anuken/Mindustry.git
synced 2025-02-10 02:37:12 +07:00
Added mod file tree, bundle loading
This commit is contained in:
parent
b3666ed2a8
commit
4f9ed73a59
@ -130,6 +130,7 @@ public class Vars implements Loadable{
|
||||
/** list of all locales that can be switched to */
|
||||
public static Locale[] locales;
|
||||
|
||||
public static FileTree filet;
|
||||
public static Net net;
|
||||
public static ContentLoader content;
|
||||
public static GameState state;
|
||||
@ -193,6 +194,7 @@ public class Vars implements Loadable{
|
||||
|
||||
Version.init();
|
||||
|
||||
filet = new FileTree();
|
||||
mods = new Mods();
|
||||
content = new ContentLoader();
|
||||
loops = new LoopControl();
|
||||
|
59
core/src/io/anuke/mindustry/core/FileTree.java
Normal file
59
core/src/io/anuke/mindustry/core/FileTree.java
Normal file
@ -0,0 +1,59 @@
|
||||
package io.anuke.mindustry.core;
|
||||
|
||||
import io.anuke.arc.*;
|
||||
import io.anuke.arc.collection.*;
|
||||
import io.anuke.arc.files.*;
|
||||
import io.anuke.arc.util.*;
|
||||
import io.anuke.arc.util.io.*;
|
||||
import io.anuke.mindustry.mod.Mods.*;
|
||||
|
||||
/** Handles files in a modded context. */
|
||||
public class FileTree{
|
||||
private ObjectMap<String, FileHandle> files = new ObjectMap<>();
|
||||
private ObjectMap<String, Array<FileHandle>> bundles = new ObjectMap<>();
|
||||
|
||||
public void buildFiles(Array<LoadedMod> mods){
|
||||
//TODO many files should not be replaced
|
||||
for(LoadedMod mod : mods){
|
||||
mod.root.walk(f -> {
|
||||
//TODO calling child/parent on these files will give you gibberish; create wrapper class.
|
||||
files.put(f.path(), f);
|
||||
});
|
||||
|
||||
//load up bundles.
|
||||
FileHandle folder = mod.root.child("bundles");
|
||||
if(folder.exists()){
|
||||
for(FileHandle file : folder.list()){
|
||||
if(file.name().startsWith("bundle") && file.extension().equals("properties")){
|
||||
String name = file.nameWithoutExtension();
|
||||
bundles.getOr(name, Array::new).add(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//add new keys to each bundle
|
||||
I18NBundle bundle = Core.bundle;
|
||||
while(bundle != null){
|
||||
String str = bundle.getLocale().toString();
|
||||
String locale = "bundle" + (str.isEmpty() ? "" : "_" + str);
|
||||
for(FileHandle file : bundles.getOr(locale, Array::new)){
|
||||
try{
|
||||
PropertiesUtils.load(bundle.getProperties(), file.reader());
|
||||
}catch(Exception e){
|
||||
throw new RuntimeException("Error loading bundle: " + file + "/" + locale, e);
|
||||
}
|
||||
}
|
||||
bundle = bundle.getParent();
|
||||
}
|
||||
}
|
||||
|
||||
/** Gets an asset file.*/
|
||||
public FileHandle get(String path){
|
||||
if(files.containsKey(path)){
|
||||
return files.get(path);
|
||||
}else{
|
||||
return Core.files.internal(path);
|
||||
}
|
||||
}
|
||||
}
|
@ -23,15 +23,15 @@ public class Mods{
|
||||
return modDirectory.child(load.name).child("config.json");
|
||||
}
|
||||
|
||||
/** @return the loaded plugin found by class, or null if not found. */
|
||||
/** @return the loaded mod found by class, or null if not found. */
|
||||
public @Nullable LoadedMod getMod(Class<? extends Mod> type){
|
||||
return loaded.find(l -> l.mod.getClass() == type);
|
||||
}
|
||||
|
||||
/** Loads all plugins from the folder, but does call any methods on them.*/
|
||||
/** Loads all mods from the folder, but does call any methods on them.*/
|
||||
public void load(){
|
||||
for(FileHandle file : modDirectory.list()){
|
||||
if(!file.extension().equals("jar") || !file.extension().equals("zi[")) continue;
|
||||
if(!file.extension().equals("jar") || !file.extension().equals("zip")) continue;
|
||||
|
||||
try{
|
||||
loaded.add(loadmod(file));
|
||||
@ -41,16 +41,18 @@ public class Mods{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
filet.buildFiles(loaded);
|
||||
}
|
||||
|
||||
/** @return all loaded plugins. */
|
||||
/** @return all loaded mods. */
|
||||
public Array<LoadedMod> all(){
|
||||
return loaded;
|
||||
}
|
||||
|
||||
/** Iterates through each plugin.*/
|
||||
/** Iterates through each mod with a main class.*/
|
||||
public void each(Consumer<Mod> cons){
|
||||
loaded.each(p -> cons.accept(p.mod));
|
||||
loaded.each(p -> p.mod != null, p -> cons.accept(p.mod));
|
||||
}
|
||||
|
||||
private LoadedMod loadmod(FileHandle jar) throws Exception{
|
||||
@ -63,23 +65,37 @@ public class Mods{
|
||||
}
|
||||
|
||||
ModMeta meta = JsonIO.read(ModMeta.class, metaf.readString());
|
||||
String camelized = meta.name.replace(" ", "");
|
||||
String mainClass = meta.main == null ? camelized.toLowerCase() + "." + camelized + "Mod" : meta.main;
|
||||
Mod mainMod;
|
||||
|
||||
URLClassLoader classLoader = new URLClassLoader(new URL[]{jar.file().toURI().toURL()}, ClassLoader.getSystemClassLoader());
|
||||
Class<?> main = classLoader.loadClass(meta.main);
|
||||
metas.put(main, meta);
|
||||
return new LoadedMod(jar, zip, (Mod)main.getDeclaredConstructor().newInstance(), meta);
|
||||
//make sure the main class exists before loading it; if it doesn't just don't put it there
|
||||
if(zip.child(mainClass.replace('.', '/') + ".class").exists()){
|
||||
URLClassLoader classLoader = new URLClassLoader(new URL[]{jar.file().toURI().toURL()}, ClassLoader.getSystemClassLoader());
|
||||
Class<?> main = classLoader.loadClass(mainClass);
|
||||
metas.put(main, meta);
|
||||
mainMod = (Mod)main.getDeclaredConstructor().newInstance();
|
||||
}else{
|
||||
mainMod = null;
|
||||
}
|
||||
|
||||
return new LoadedMod(jar, zip, mainMod, meta);
|
||||
}
|
||||
|
||||
/** Represents a plugin that has been loaded from a jar file.*/
|
||||
public static class LoadedMod{
|
||||
public final FileHandle jarFile;
|
||||
public final FileHandle zipRoot;
|
||||
/** The location of this mod's zip file on the disk. */
|
||||
public final FileHandle file;
|
||||
/** The root zip file; points to the contents of this mod. */
|
||||
public final FileHandle root;
|
||||
/** The mod's main class; may be null. */
|
||||
public final @Nullable Mod mod;
|
||||
/** This mod's metadata. */
|
||||
public final ModMeta meta;
|
||||
|
||||
public LoadedMod(FileHandle jarFile, FileHandle zipRoot, Mod mod, ModMeta meta){
|
||||
this.zipRoot = zipRoot;
|
||||
this.jarFile = jarFile;
|
||||
public LoadedMod(FileHandle file, FileHandle root, Mod mod, ModMeta meta){
|
||||
this.root = root;
|
||||
this.file = file;
|
||||
this.mod = mod;
|
||||
this.meta = meta;
|
||||
}
|
||||
@ -88,5 +104,6 @@ public class Mods{
|
||||
/** Plugin metadata information.*/
|
||||
public static class ModMeta{
|
||||
public String name, author, description, version, main;
|
||||
public String[] dependencies = {}; //TODO implement
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,3 @@
|
||||
org.gradle.daemon=true
|
||||
org.gradle.jvmargs=-Xms256m -Xmx1024m
|
||||
archash=5bf89742e927d1951c58cc2743814874c1c9ad25
|
||||
archash=9f30453676bf2b582c01a46a60965305321dcb9d
|
||||
|
@ -332,7 +332,7 @@ public class ServerControl implements ApplicationListener{
|
||||
info("Name: &ly{0}", mod.meta.name);
|
||||
info("Version: &ly{0}", mod.meta.version);
|
||||
info("Author: &ly{0}", mod.meta.author);
|
||||
info("Path: &ly{0}", mod.jarFile.path());
|
||||
info("Path: &ly{0}", mod.file.path());
|
||||
info("Description: &ly{0}", mod.meta.description);
|
||||
}else{
|
||||
info("No mod with name &ly'{0}'&lg found.");
|
||||
|
Loading…
Reference in New Issue
Block a user