Support for Android java mods
This commit is contained in:
@@ -7,7 +7,6 @@ import android.content.pm.*;
|
|||||||
import android.net.*;
|
import android.net.*;
|
||||||
import android.os.Build.*;
|
import android.os.Build.*;
|
||||||
import android.os.*;
|
import android.os.*;
|
||||||
import android.provider.Settings.*;
|
|
||||||
import android.telephony.*;
|
import android.telephony.*;
|
||||||
import arc.*;
|
import arc.*;
|
||||||
import arc.backend.android.*;
|
import arc.backend.android.*;
|
||||||
@@ -15,7 +14,7 @@ import arc.files.*;
|
|||||||
import arc.func.*;
|
import arc.func.*;
|
||||||
import arc.scene.ui.layout.*;
|
import arc.scene.ui.layout.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import arc.util.serialization.*;
|
import dalvik.system.*;
|
||||||
import mindustry.*;
|
import mindustry.*;
|
||||||
import mindustry.game.Saves.*;
|
import mindustry.game.Saves.*;
|
||||||
import mindustry.io.*;
|
import mindustry.io.*;
|
||||||
@@ -23,7 +22,6 @@ import mindustry.net.*;
|
|||||||
import mindustry.ui.dialogs.*;
|
import mindustry.ui.dialogs.*;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.lang.System;
|
|
||||||
import java.lang.Thread.*;
|
import java.lang.Thread.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@@ -73,12 +71,25 @@ public class AndroidLauncher extends AndroidApplication{
|
|||||||
public void shareFile(Fi file){
|
public void shareFile(Fi file){
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<?> loadJar(Fi jar, String mainClass) throws Exception{
|
||||||
|
DexClassLoader loader = new DexClassLoader(jar.file().getPath(), getFilesDir().getPath(), null, getClassLoader());
|
||||||
|
return Class.forName(mainClass, true, loader);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void showFileChooser(boolean open, String extension, Cons<Fi> cons){
|
public void showFileChooser(boolean open, String extension, Cons<Fi> cons){
|
||||||
|
showFileChooser(open, cons, extension);
|
||||||
|
}
|
||||||
|
|
||||||
|
void showFileChooser(boolean open, Cons<Fi> cons, String... extensions){
|
||||||
|
String extension = extensions[0];
|
||||||
|
|
||||||
if(VERSION.SDK_INT >= VERSION_CODES.Q){
|
if(VERSION.SDK_INT >= VERSION_CODES.Q){
|
||||||
Intent intent = new Intent(open ? Intent.ACTION_OPEN_DOCUMENT : Intent.ACTION_CREATE_DOCUMENT);
|
Intent intent = new Intent(open ? Intent.ACTION_OPEN_DOCUMENT : Intent.ACTION_CREATE_DOCUMENT);
|
||||||
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||||
intent.setType(extension.equals("zip") && !open ? "application/zip" : "*/*");
|
intent.setType(extension.equals("zip") && !open && extensions.length == 1 ? "application/zip" : "*/*");
|
||||||
|
|
||||||
addResultListener(i -> startActivityForResult(intent, i), (code, in) -> {
|
addResultListener(i -> startActivityForResult(intent, i), (code, in) -> {
|
||||||
if(code == Activity.RESULT_OK && in != null && in.getData() != null){
|
if(code == Activity.RESULT_OK && in != null && in.getData() != null){
|
||||||
Uri uri = in.getData();
|
Uri uri = in.getData();
|
||||||
@@ -108,7 +119,7 @@ public class AndroidLauncher extends AndroidApplication{
|
|||||||
});
|
});
|
||||||
}else if(VERSION.SDK_INT >= VERSION_CODES.M && !(checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED &&
|
}else if(VERSION.SDK_INT >= VERSION_CODES.M && !(checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED &&
|
||||||
checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)){
|
checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)){
|
||||||
chooser = new FileChooser(open ? "@open" : "@save", file -> file.extension().equalsIgnoreCase(extension), open, file -> {
|
chooser = new FileChooser(open ? "@open" : "@save", file -> Structs.contains(extensions, file.extension().toLowerCase()), open, file -> {
|
||||||
if(!open){
|
if(!open){
|
||||||
cons.get(file.parent().child(file.nameWithoutExtension() + "." + extension));
|
cons.get(file.parent().child(file.nameWithoutExtension() + "." + extension));
|
||||||
}else{
|
}else{
|
||||||
@@ -125,10 +136,19 @@ public class AndroidLauncher extends AndroidApplication{
|
|||||||
}
|
}
|
||||||
requestPermissions(perms.toArray(new String[0]), PERMISSION_REQUEST_CODE);
|
requestPermissions(perms.toArray(new String[0]), PERMISSION_REQUEST_CODE);
|
||||||
}else{
|
}else{
|
||||||
super.showFileChooser(open, extension, cons);
|
if(open){
|
||||||
|
new FileChooser("@open", file -> Structs.contains(extensions, file.extension().toLowerCase()), true, cons).show();
|
||||||
|
}else{
|
||||||
|
super.showFileChooser(open, extension, cons);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showMultiFileChooser(Cons<Fi> cons, String... extensions){
|
||||||
|
showFileChooser(true, cons, extensions);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void beginForceLandscape(){
|
public void beginForceLandscape(){
|
||||||
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
|
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
|
||||||
|
|||||||
@@ -14,10 +14,18 @@ import mindustry.type.*;
|
|||||||
import mindustry.ui.dialogs.*;
|
import mindustry.ui.dialogs.*;
|
||||||
import rhino.*;
|
import rhino.*;
|
||||||
|
|
||||||
|
import java.net.*;
|
||||||
|
|
||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
public interface Platform{
|
public interface Platform{
|
||||||
|
|
||||||
|
/** Dynamically loads a jar file. */
|
||||||
|
default Class<?> loadJar(Fi jar, String mainClass) throws Exception{
|
||||||
|
URLClassLoader classLoader = new URLClassLoader(new URL[]{jar.file().toURI().toURL()}, ClassLoader.getSystemClassLoader());
|
||||||
|
return classLoader.loadClass(mainClass);
|
||||||
|
}
|
||||||
|
|
||||||
/** Steam: Update lobby visibility.*/
|
/** Steam: Update lobby visibility.*/
|
||||||
default void updateLobby(){}
|
default void updateLobby(){}
|
||||||
|
|
||||||
@@ -121,7 +129,7 @@ public interface Platform{
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show a file chooser for multiple file types. Only supported on desktop.
|
* Show a file chooser for multiple file types.
|
||||||
* @param cons Selection listener
|
* @param cons Selection listener
|
||||||
* @param extensions File extensions to filter
|
* @param extensions File extensions to filter
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ import mindustry.type.*;
|
|||||||
import mindustry.ui.*;
|
import mindustry.ui.*;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.net.*;
|
|
||||||
|
|
||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
@@ -634,12 +633,11 @@ public class Mods implements Loadable{
|
|||||||
//make sure the main class exists before loading it; if it doesn't just don't put it there
|
//make sure the main class exists before loading it; if it doesn't just don't put it there
|
||||||
if(mainFile.exists()){
|
if(mainFile.exists()){
|
||||||
//mobile versions don't support class mods
|
//mobile versions don't support class mods
|
||||||
if(mobile){
|
if(ios){
|
||||||
throw new IllegalArgumentException("Java class mods are not supported on mobile.");
|
throw new IllegalArgumentException("Java class mods are not supported on iOS.");
|
||||||
}
|
}
|
||||||
|
|
||||||
URLClassLoader classLoader = new URLClassLoader(new URL[]{sourceFile.file().toURI().toURL()}, ClassLoader.getSystemClassLoader());
|
Class<?> main = platform.loadJar(sourceFile, mainClass);
|
||||||
Class<?> main = classLoader.loadClass(mainClass);
|
|
||||||
metas.put(main, meta);
|
metas.put(main, meta);
|
||||||
mainMod = (Mod)main.getDeclaredConstructor().newInstance();
|
mainMod = (Mod)main.getDeclaredConstructor().newInstance();
|
||||||
}else{
|
}else{
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ public class CrashSender{
|
|||||||
+ "OS: " + System.getProperty("os.name") + " x" + (OS.is64Bit ? "64" : "32") + "\n"
|
+ "OS: " + System.getProperty("os.name") + " x" + (OS.is64Bit ? "64" : "32") + "\n"
|
||||||
+ "Java Version: " + System.getProperty("java.version") + "\n"
|
+ "Java Version: " + System.getProperty("java.version") + "\n"
|
||||||
+ "Java Architecture: " + System.getProperty("sun.arch.data.model") + "\n"
|
+ "Java Architecture: " + System.getProperty("sun.arch.data.model") + "\n"
|
||||||
+ mods.list().size + " Mods: " + mods.list().toString(", ", mod -> mod.name + ":" + mod.meta.version)
|
+ mods.list().size + " Mods: " + (mods.list().isEmpty() ? "none" : mods.list().toString(", ", mod -> mod.name + ":" + mod.meta.version))
|
||||||
+ "\n\n" + error;
|
+ "\n\n" + error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user