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.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
}

View file

@ -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<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);
object PluginManager {
private val PLUGINS_PATH =
Environment.getExternalStorageDirectory().absolutePath + "/Cloudstream3/plugins"
private val plugins: MutableMap<String, Plugin> =
LinkedHashMap<String, Plugin>()
private val classLoaders: MutableMap<PathClassLoader, Plugin> =
HashMap<PathClassLoader, Plugin>()
private val failedToLoad: MutableMap<File, Any> = 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<? extends Plugin>) 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<out Plugin?>
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);
}
}