This commit is contained in:
Anuken
2020-08-22 09:00:55 -04:00
parent 467d995aed
commit c1cd27b9da
5 changed files with 65 additions and 55 deletions

View File

@@ -588,59 +588,68 @@ public class Mods implements Loadable{
private LoadedMod loadMod(Fi sourceFile) throws Exception{
Time.mark();
Fi zip = sourceFile.isDirectory() ? sourceFile : new ZipFi(sourceFile);
if(zip.list().length == 1 && zip.list()[0].isDirectory()){
zip = zip.list()[0];
}
ZipFi rootZip = null;
Fi metaf = zip.child("mod.json").exists() ? zip.child("mod.json") : zip.child("mod.hjson").exists() ? zip.child("mod.hjson") : zip.child("plugin.json");
if(!metaf.exists()){
Log.warn("Mod @ doesn't have a 'mod.json'/'mod.hjson'/'plugin.json' file, skipping.", sourceFile);
throw new IllegalArgumentException("Invalid file: No mod.json found.");
}
ModMeta meta = json.fromJson(ModMeta.class, Jval.read(metaf.readString()).toString(Jformat.plain));
meta.cleanup();
String camelized = meta.name.replace(" ", "");
String mainClass = meta.main == null ? camelized.toLowerCase() + "." + camelized + "Mod" : meta.main;
String baseName = meta.name.toLowerCase().replace(" ", "-");
if(mods.contains(m -> m.name.equals(baseName))){
throw new IllegalArgumentException("A mod with the name '" + baseName + "' is already imported.");
}
Mod mainMod;
Fi mainFile = zip;
String[] path = (mainClass.replace('.', '/') + ".class").split("/");
for(String str : path){
if(!str.isEmpty()){
mainFile = mainFile.child(str);
}
}
//make sure the main class exists before loading it; if it doesn't just don't put it there
if(mainFile.exists()){
//mobile versions don't support class mods
if(mobile){
throw new IllegalArgumentException("Java class mods are not supported on mobile.");
try{
Fi zip = sourceFile.isDirectory() ? sourceFile : (rootZip = new ZipFi(sourceFile));
if(zip.list().length == 1 && zip.list()[0].isDirectory()){
zip = zip.list()[0];
}
URLClassLoader classLoader = new URLClassLoader(new URL[]{sourceFile.file().toURI().toURL()}, ClassLoader.getSystemClassLoader());
Class<?> main = classLoader.loadClass(mainClass);
metas.put(main, meta);
mainMod = (Mod)main.getDeclaredConstructor().newInstance();
}else{
mainMod = null;
}
Fi metaf = zip.child("mod.json").exists() ? zip.child("mod.json") : zip.child("mod.hjson").exists() ? zip.child("mod.hjson") : zip.child("plugin.json");
if(!metaf.exists()){
Log.warn("Mod @ doesn't have a 'mod.json'/'mod.hjson'/'plugin.json' file, skipping.", sourceFile);
throw new IllegalArgumentException("Invalid file: No mod.json found.");
}
//all plugins are hidden implicitly
if(mainMod instanceof Plugin){
meta.hidden = true;
}
ModMeta meta = json.fromJson(ModMeta.class, Jval.read(metaf.readString()).toString(Jformat.plain));
meta.cleanup();
String camelized = meta.name.replace(" ", "");
String mainClass = meta.main == null ? camelized.toLowerCase() + "." + camelized + "Mod" : meta.main;
String baseName = meta.name.toLowerCase().replace(" ", "-");
Log.info("Loaded mod '@' in @", meta.name, Time.elapsed());
return new LoadedMod(sourceFile, zip, mainMod, meta);
if(mods.contains(m -> m.name.equals(baseName))){
throw new IllegalArgumentException("A mod with the name '" + baseName + "' is already imported.");
}
Mod mainMod;
Fi mainFile = zip;
String[] path = (mainClass.replace('.', '/') + ".class").split("/");
for(String str : path){
if(!str.isEmpty()){
mainFile = mainFile.child(str);
}
}
//make sure the main class exists before loading it; if it doesn't just don't put it there
if(mainFile.exists()){
//mobile versions don't support class mods
if(mobile){
throw new IllegalArgumentException("Java class mods are not supported on mobile.");
}
URLClassLoader classLoader = new URLClassLoader(new URL[]{sourceFile.file().toURI().toURL()}, ClassLoader.getSystemClassLoader());
Class<?> main = classLoader.loadClass(mainClass);
metas.put(main, meta);
mainMod = (Mod)main.getDeclaredConstructor().newInstance();
}else{
mainMod = null;
}
//all plugins are hidden implicitly
if(mainMod instanceof Plugin){
meta.hidden = true;
}
Log.info("Loaded mod '@' in @", meta.name, Time.elapsed());
return new LoadedMod(sourceFile, zip, mainMod, meta);
}catch(Exception e){
//delete root zip file so it can be closed on windows
if(rootZip != null) rootZip.delete();
throw e;
}
}
/** Represents a mod's state. May be a jar file, folder or zip. */