From b42c0b905b48220b234a3af4dbd198ce51d4256e Mon Sep 17 00:00:00 2001 From: Blatzar <46196380+Blatzar@users.noreply.github.com> Date: Sat, 6 Aug 2022 17:48:00 +0200 Subject: [PATCH] Converted Pluginmanager to kotlin --- .../lagradost/cloudstream3/plugins/Plugin.kt | 28 ++-- .../cloudstream3/plugins/PluginManager.kt | 151 +++++++++--------- 2 files changed, 88 insertions(+), 91 deletions(-) diff --git a/app/src/main/java/com/lagradost/cloudstream3/plugins/Plugin.kt b/app/src/main/java/com/lagradost/cloudstream3/plugins/Plugin.kt index e81a7a20..a2f29a55 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/plugins/Plugin.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/plugins/Plugin.kt @@ -1,24 +1,24 @@ -package com.lagradost.cloudstream3.plugins; +package com.lagradost.cloudstream3.plugins -import android.content.Context; -import android.content.res.Resources; - -public abstract class Plugin { - public Plugin() {} +import android.content.Context +import android.content.res.Resources +import kotlin.Throws +abstract class Plugin { /** * Called when your Plugin is loaded * @param context Context */ - public void load(Context context) throws Throwable {} - - public static class Manifest { - public String name; - public String pluginClassName; + @Throws(Throwable::class) + open fun load(context: Context?) { } - public Resources resources; - public boolean needsResources = false; + class Manifest { + var name: String? = null + var pluginClassName: String? = null + } - public String __filename; + var resources: Resources? = null + var needsResources = false + var __filename: String? = null } \ No newline at end of file diff --git a/app/src/main/java/com/lagradost/cloudstream3/plugins/PluginManager.kt b/app/src/main/java/com/lagradost/cloudstream3/plugins/PluginManager.kt index d8b39548..3a8c34b0 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/plugins/PluginManager.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/plugins/PluginManager.kt @@ -1,108 +1,105 @@ -package com.lagradost.cloudstream3.plugins; +package com.lagradost.cloudstream3.plugins -import android.content.Context; -import android.content.res.AssetManager; -import android.content.res.Resources; +import android.content.Context +import dalvik.system.PathClassLoader +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; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.*; -import android.os.Environment; -import com.google.gson.Gson; - -import dalvik.system.PathClassLoader; - - -public class PluginManager { - public static final String PLUGINS_PATH = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Cloudstream3/plugins"; - - public static final Map plugins = new LinkedHashMap<>(); - public static final Map classLoaders = new HashMap<>(); - public static final Map 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); +object PluginManager { + private val PLUGINS_PATH = + Environment.getExternalStorageDirectory().absolutePath + "/Cloudstream3/plugins" + private val plugins: MutableMap = + LinkedHashMap() + private val classLoaders: MutableMap = + HashMap() + private val failedToLoad: MutableMap = LinkedHashMap() + var loadedPlugins = false + private val gson = Gson() + fun loadAllPlugins(context: Context) { + println("LOAD PLUGINS") + val dir = File(PLUGINS_PATH) if (!dir.exists()) { - boolean res = dir.mkdirs(); + val res = dir.mkdirs() if (!res) { //logger.error("Failed to create directories!", null); - return; + return } } - - File[] sortedPlugins = dir.listFiles(); + val sortedPlugins = dir.listFiles() // Always sort plugins alphabetically for reproducible results - Arrays.sort(sortedPlugins, Comparator.comparing(File::getName)); - for (File f : sortedPlugins) { - String name = f.getName(); - if (name.endsWith(".zip")) { - PluginManager.loadPlugin(context, f); - } else if (!name.equals("oat")) { // Some roms create this - if (f.isDirectory()) { - //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")) { - //Utils.showToast(String.format("Found extracted plugin file %s in your plugins folder. DO NOT EXTRACT PLUGIN ZIPS!", name), true); + sortedPlugins?.sortedBy { it.name }?.forEach { file -> + val name = file.name + if (file.extension == "zip" || file.extension == "cs3") { + loadPlugin(context, file) + } else if (name != "oat") { // Some roms create this + if (file.isDirectory) { + // Utils.showToast(String.format("Found directory %s in your plugins folder. DO NOT EXTRACT PLUGIN ZIPS!", name), true); + } 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); } - //rmrf(f); + // rmrf(f); } } - loadedPlugins = true; + + loadedPlugins = true //if (!PluginManager.failedToLoad.isEmpty()) - //Utils.showToast("Some plugins failed to load."); + //Utils.showToast("Some plugins failed to load."); } - @SuppressWarnings({ "JavaReflectionMemberAccess", "unchecked" }) - public static void loadPlugin(Context context, File file) { - String fileName = file.getName().replace(".zip", ""); + private fun loadPlugin(context: Context, file: File) { + val fileName = file.nameWithoutExtension //logger.info("Loading plugin: " + fileName); try { - PathClassLoader loader = new PathClassLoader(file.getAbsolutePath(), context.getClassLoader()); - - Plugin.Manifest manifest; - - try (InputStream stream = loader.getResourceAsStream("manifest.json")) { + val loader = PathClassLoader(file.absolutePath, context.classLoader) + var manifest: Plugin.Manifest + loader.getResourceAsStream("manifest.json").use { stream -> 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); - return; + return } - - try (InputStreamReader reader = new InputStreamReader(stream)) { - manifest = gson.fromJson(reader, Plugin.Manifest.class); + InputStreamReader(stream).use { reader -> + manifest = gson.fromJson( + reader, + Plugin.Manifest::class.java + ) } } - - String name = manifest.name; - - Class pluginClass = (Class) loader.loadClass(manifest.pluginClassName); - - Plugin pluginInstance = (Plugin)pluginClass.newInstance(); + val name: String = manifest.name ?: "NO NAME" + val pluginClass: Class<*> = + loader.loadClass(manifest.pluginClassName) as Class + val pluginInstance: Plugin = + pluginClass.newInstance() as Plugin if (plugins.containsKey(name)) { //logger.error("Plugin with name " + name + " already exists", null); - return; + return } - - pluginInstance.__filename = fileName; + pluginInstance.__filename = fileName if (pluginInstance.needsResources) { // based on https://stackoverflow.com/questions/7483568/dynamic-resource-loading-from-other-apk - AssetManager assets = AssetManager.class.newInstance(); - Method addAssetPath = AssetManager.class.getMethod("addAssetPath", String.class); - addAssetPath.invoke(assets, file.getAbsolutePath()); - pluginInstance.resources = new Resources(assets, context.getResources().getDisplayMetrics(), context.getResources().getConfiguration()); + val assets = AssetManager::class.java.newInstance() + val addAssetPath = + AssetManager::class.java.getMethod("addAssetPath", String::class.java) + addAssetPath.invoke(assets, file.absolutePath) + pluginInstance.resources = Resources( + assets, + context.resources.displayMetrics, + context.resources.configuration + ) } - plugins.put(name, pluginInstance); - classLoaders.put(loader, pluginInstance); - pluginInstance.load(context); - } catch (Throwable e) { - failedToLoad.put(file, e); + plugins[name] = pluginInstance + classLoaders[loader] = pluginInstance + pluginInstance.load(context) + } catch (e: Throwable) { + failedToLoad[file] = e + e.printStackTrace() //logger.error("Failed to load plugin " + fileName + ":\n", e); } }