Converted Pluginmanager to kotlin

This commit is contained in:
Blatzar 2022-08-06 17:48:00 +02:00
parent b208b4e9ae
commit b42c0b905b
2 changed files with 88 additions and 91 deletions

View File

@ -1,24 +1,24 @@
package com.lagradost.cloudstream3.plugins; package com.lagradost.cloudstream3.plugins
import android.content.Context; import android.content.Context
import android.content.res.Resources; import android.content.res.Resources
import kotlin.Throws
public abstract class Plugin {
public Plugin() {}
abstract class Plugin {
/** /**
* Called when your Plugin is loaded * Called when your Plugin is loaded
* @param context Context * @param context Context
*/ */
public void load(Context context) throws Throwable {} @Throws(Throwable::class)
open fun load(context: Context?) {
public static class Manifest {
public String name;
public String pluginClassName;
} }
public Resources resources; class Manifest {
public boolean needsResources = false; var name: String? = null
var pluginClassName: String? = null
}
public String __filename; var resources: Resources? = null
var needsResources = false
var __filename: String? = null
} }

View File

@ -1,108 +1,105 @@
package com.lagradost.cloudstream3.plugins; package com.lagradost.cloudstream3.plugins
import android.content.Context; import android.content.Context
import android.content.res.AssetManager; import dalvik.system.PathClassLoader
import android.content.res.Resources; import com.google.gson.Gson
import com.lagradost.cloudstream3.plugins.PluginManager
import android.content.res.AssetManager
import android.content.res.Resources
import android.os.Environment
import java.io.File
import java.io.InputStreamReader
import java.util.*
import java.io.File; object PluginManager {
import java.io.InputStream; private val PLUGINS_PATH =
import java.io.InputStreamReader; Environment.getExternalStorageDirectory().absolutePath + "/Cloudstream3/plugins"
import java.lang.reflect.Field; private val plugins: MutableMap<String, Plugin> =
import java.lang.reflect.Method; LinkedHashMap<String, Plugin>()
import java.util.*; private val classLoaders: MutableMap<PathClassLoader, Plugin> =
import android.os.Environment; HashMap<PathClassLoader, Plugin>()
import com.google.gson.Gson; private val failedToLoad: MutableMap<File, Any> = LinkedHashMap()
var loadedPlugins = false
import dalvik.system.PathClassLoader; private val gson = Gson()
fun loadAllPlugins(context: Context) {
println("LOAD PLUGINS")
public class PluginManager { val dir = File(PLUGINS_PATH)
public static final String PLUGINS_PATH = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Cloudstream3/plugins";
public static final Map<String, Plugin> plugins = new LinkedHashMap<>();
public static final Map<PathClassLoader, Plugin> classLoaders = new HashMap<>();
public static final Map<File, Object> failedToLoad = new LinkedHashMap<>();
public static boolean loadedPlugins = false;
private static final Gson gson = new Gson();
public static void loadAllPlugins(Context context) {
File dir = new File(PLUGINS_PATH);
if (!dir.exists()) { if (!dir.exists()) {
boolean res = dir.mkdirs(); val res = dir.mkdirs()
if (!res) { if (!res) {
//logger.error("Failed to create directories!", null); //logger.error("Failed to create directories!", null);
return; return
} }
} }
val sortedPlugins = dir.listFiles()
File[] sortedPlugins = dir.listFiles();
// Always sort plugins alphabetically for reproducible results // Always sort plugins alphabetically for reproducible results
Arrays.sort(sortedPlugins, Comparator.comparing(File::getName));
for (File f : sortedPlugins) { sortedPlugins?.sortedBy { it.name }?.forEach { file ->
String name = f.getName(); val name = file.name
if (name.endsWith(".zip")) { if (file.extension == "zip" || file.extension == "cs3") {
PluginManager.loadPlugin(context, f); loadPlugin(context, file)
} else if (!name.equals("oat")) { // Some roms create this } else if (name != "oat") { // Some roms create this
if (f.isDirectory()) { if (file.isDirectory) {
//Utils.showToast(String.format("Found directory %s in your plugins folder. DO NOT EXTRACT PLUGIN ZIPS!", name), true); // Utils.showToast(String.format("Found directory %s in your plugins folder. DO NOT EXTRACT PLUGIN ZIPS!", name), true);
} else if (name.equals("classes.dex") || name.endsWith(".json")) { } else if (name == "classes.dex" || name.endsWith(".json")) {
//Utils.showToast(String.format("Found extracted plugin file %s in your plugins folder. DO NOT EXTRACT PLUGIN ZIPS!", name), true); // Utils.showToast(String.format("Found extracted plugin file %s in your plugins folder. DO NOT EXTRACT PLUGIN ZIPS!", name), true);
} }
//rmrf(f); // rmrf(f);
} }
} }
loadedPlugins = true;
loadedPlugins = true
//if (!PluginManager.failedToLoad.isEmpty()) //if (!PluginManager.failedToLoad.isEmpty())
//Utils.showToast("Some plugins failed to load."); //Utils.showToast("Some plugins failed to load.");
} }
@SuppressWarnings({ "JavaReflectionMemberAccess", "unchecked" }) private fun loadPlugin(context: Context, file: File) {
public static void loadPlugin(Context context, File file) { val fileName = file.nameWithoutExtension
String fileName = file.getName().replace(".zip", "");
//logger.info("Loading plugin: " + fileName); //logger.info("Loading plugin: " + fileName);
try { try {
PathClassLoader loader = new PathClassLoader(file.getAbsolutePath(), context.getClassLoader()); val loader = PathClassLoader(file.absolutePath, context.classLoader)
var manifest: Plugin.Manifest
Plugin.Manifest manifest; loader.getResourceAsStream("manifest.json").use { stream ->
try (InputStream stream = loader.getResourceAsStream("manifest.json")) {
if (stream == null) { if (stream == null) {
failedToLoad.put(file, "No manifest found"); failedToLoad[file] = "No manifest found"
//logger.error("Failed to load plugin " + fileName + ": No manifest found", null); //logger.error("Failed to load plugin " + fileName + ": No manifest found", null);
return; return
} }
InputStreamReader(stream).use { reader ->
try (InputStreamReader reader = new InputStreamReader(stream)) { manifest = gson.fromJson(
manifest = gson.fromJson(reader, Plugin.Manifest.class); reader,
Plugin.Manifest::class.java
)
} }
} }
val name: String = manifest.name ?: "NO NAME"
String name = manifest.name; val pluginClass: Class<*> =
loader.loadClass(manifest.pluginClassName) as Class<out Plugin?>
Class pluginClass = (Class<? extends Plugin>) loader.loadClass(manifest.pluginClassName); val pluginInstance: Plugin =
pluginClass.newInstance() as Plugin
Plugin pluginInstance = (Plugin)pluginClass.newInstance();
if (plugins.containsKey(name)) { if (plugins.containsKey(name)) {
//logger.error("Plugin with name " + name + " already exists", null); //logger.error("Plugin with name " + name + " already exists", null);
return; return
} }
pluginInstance.__filename = fileName
pluginInstance.__filename = fileName;
if (pluginInstance.needsResources) { if (pluginInstance.needsResources) {
// based on https://stackoverflow.com/questions/7483568/dynamic-resource-loading-from-other-apk // based on https://stackoverflow.com/questions/7483568/dynamic-resource-loading-from-other-apk
AssetManager assets = AssetManager.class.newInstance(); val assets = AssetManager::class.java.newInstance()
Method addAssetPath = AssetManager.class.getMethod("addAssetPath", String.class); val addAssetPath =
addAssetPath.invoke(assets, file.getAbsolutePath()); AssetManager::class.java.getMethod("addAssetPath", String::class.java)
pluginInstance.resources = new Resources(assets, context.getResources().getDisplayMetrics(), context.getResources().getConfiguration()); addAssetPath.invoke(assets, file.absolutePath)
pluginInstance.resources = Resources(
assets,
context.resources.displayMetrics,
context.resources.configuration
)
} }
plugins.put(name, pluginInstance); plugins[name] = pluginInstance
classLoaders.put(loader, pluginInstance); classLoaders[loader] = pluginInstance
pluginInstance.load(context); pluginInstance.load(context)
} catch (Throwable e) { } catch (e: Throwable) {
failedToLoad.put(file, e); failedToLoad[file] = e
e.printStackTrace()
//logger.error("Failed to load plugin " + fileName + ":\n", e); //logger.error("Failed to load plugin " + fileName + ":\n", e);
} }
} }