Merge remote-tracking branch 'origin/master'

This commit is contained in:
Anuken
2025-06-03 15:37:27 -04:00
3 changed files with 70 additions and 24 deletions

View File

@@ -73,28 +73,57 @@ public class AndroidLauncher extends AndroidApplication{
@Override @Override
public ClassLoader loadJar(Fi jar, ClassLoader parent) throws Exception{ public ClassLoader loadJar(Fi jar, ClassLoader parent) throws Exception{
//Required to load jar files in Android 14: https://developer.android.com/about/versions/14/behavior-changes-14#safer-dynamic-code-loading //Required to load jar files in Android 14: https://developer.android.com/about/versions/14/behavior-changes-14#safer-dynamic-code-loading
jar.file().setReadOnly(); try{
return new DexClassLoader(jar.file().getPath(), getFilesDir().getPath(), null, parent){ jar.file().setReadOnly();
@Override return new DexClassLoader(jar.file().getPath(), getFilesDir().getPath(), null, parent){
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException{ @Override
//check for loaded state protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException{
Class<?> loadedClass = findLoadedClass(name); //check for loaded state
if(loadedClass == null){ Class<?> loadedClass = findLoadedClass(name);
try{ if(loadedClass == null){
//try to load own class first try{
loadedClass = findClass(name); //try to load own class first
}catch(ClassNotFoundException | NoClassDefFoundError e){ loadedClass = findClass(name);
//use parent if not found }catch(ClassNotFoundException | NoClassDefFoundError e){
return parent.loadClass(name); //use parent if not found
return parent.loadClass(name);
}
} }
}
if(resolve){ if(resolve){
resolveClass(loadedClass); resolveClass(loadedClass);
}
return loadedClass;
} }
return loadedClass; };
}catch(SecurityException e){
//`setReadOnly` to jar file in `/sdcard/Android/data/...` does not work on some Android 14 device
//But in `/data/...` it works
if(Build.VERSION.SDK_INT < VERSION_CODES.O_MR1){
throw e;
} }
};
Fi cacheDir = new Fi(getCacheDir()).child("mods");
cacheDir.mkdirs();
//long file name support
Fi modCacheDir = cacheDir.child(jar.nameWithoutExtension());
Fi modCache = modCacheDir.child(Long.toHexString(jar.lastModified()) + ".zip");
if(modCacheDir.equals(jar.parent())){
//should not reach here, just in case
throw e;
}
//Cache will be deleted when mod is removed
if(!modCache.exists() || jar.length() != modCache.length()){
modCacheDir.mkdirs();
jar.copyTo(modCache);
}
modCache.file().setReadOnly();
return loadJar(modCache, parent);
}
} }
@Override @Override

View File

@@ -182,3 +182,4 @@ MonoChronos
RushieWashie RushieWashie
ITY ITY
Iniquit Iniquit
DSFdsfWxp

View File

@@ -413,11 +413,22 @@ public class Mods implements Loadable{
/** Removes a mod file and marks it for requiring a restart. */ /** Removes a mod file and marks it for requiring a restart. */
public void removeMod(LoadedMod mod){ public void removeMod(LoadedMod mod){
if(!android && mod.loader != null){ boolean deleted = true;
try{
ClassLoaderCloser.close(mod.loader); if(mod.loader != null){
}catch(Exception e){ if(android){
Log.err(e); //Try to remove cache for Android 14 security problem
Fi cacheDir = new Fi(Core.files.getCachePath()).child("mods");
Fi modCacheDir = cacheDir.child(mod.file.nameWithoutExtension());
if(modCacheDir.exists()){
deleted = modCacheDir.deleteDirectory();
}
}else{
try{
ClassLoaderCloser.close(mod.loader);
}catch(Exception e){
Log.err(e);
}
} }
} }
@@ -425,7 +436,7 @@ public class Mods implements Loadable{
mod.root.delete(); mod.root.delete();
} }
boolean deleted = mod.file.isDirectory() ? mod.file.deleteDirectory() : mod.file.delete(); deleted &= mod.file.isDirectory() ? mod.file.deleteDirectory() : mod.file.delete();
if(!deleted){ if(!deleted){
ui.showErrorMessage("@mod.delete.error"); ui.showErrorMessage("@mod.delete.error");
@@ -1112,6 +1123,11 @@ public class Mods implements Loadable{
//close the classloader for jar mods //close the classloader for jar mods
if(!android){ if(!android){
ClassLoaderCloser.close(other.loader); ClassLoaderCloser.close(other.loader);
}else if(other.loader != null){
//Try to remove cache for Android 14 security problem
Fi cacheDir = new Fi(Core.files.getCachePath()).child("mods");
Fi modCacheDir = cacheDir.child(other.file.nameWithoutExtension());
modCacheDir.deleteDirectory();
} }
//close zip file //close zip file