+ Added plugin

This commit is contained in:
Matthew Cech
2019-04-20 02:00:32 -07:00
parent 25c1e9a1a2
commit 7e57ad79a0
9 changed files with 174 additions and 15 deletions
+1
View File
@@ -13,5 +13,6 @@
<classpathentry kind="lib" path="lib/slf4j-jdk14-1.7.25.jar"/> <classpathentry kind="lib" path="lib/slf4j-jdk14-1.7.25.jar"/>
<classpathentry kind="lib" path="lib/twitter4j-core-4.0.7-javadoc.jar"/> <classpathentry kind="lib" path="lib/twitter4j-core-4.0.7-javadoc.jar"/>
<classpathentry kind="lib" path="lib/twitter4j-core-4.0.7.jar"/> <classpathentry kind="lib" path="lib/twitter4j-core-4.0.7.jar"/>
<classpathentry kind="lib" path="lib/luaj-jse-3.0.1.jar"/>
<classpathentry kind="output" path="bin"/> <classpathentry kind="output" path="bin"/>
</classpath> </classpath>
Binary file not shown.
+14
View File
@@ -6,6 +6,7 @@ import java.util.List;
import java.util.concurrent.Semaphore; import java.util.concurrent.Semaphore;
import commands.*; import commands.*;
import core.lua.PluginManager;
import dataStructures.*; import dataStructures.*;
import net.dv8tion.jda.core.entities.Emote; import net.dv8tion.jda.core.entities.Emote;
import net.dv8tion.jda.core.entities.Member; import net.dv8tion.jda.core.entities.Member;
@@ -38,6 +39,9 @@ public class ObjectBuilderFactory
// RPManger for tracking RP system // RPManger for tracking RP system
private static RPManager rpManager; private static RPManager rpManager;
// Plugin manager
private static PluginManager pluginManager;
// Localization classes - these are singletons, but should be initialized before almost all other // Localization classes - these are singletons, but should be initialized before almost all other
// things so their inclusion in the factory is to ensure they're started at the correct time. // things so their inclusion in the factory is to ensure they're started at the correct time.
@SuppressWarnings("unused") private static LocStrings locStrings; @SuppressWarnings("unused") private static LocStrings locStrings;
@@ -408,6 +412,16 @@ public class ObjectBuilderFactory
return rpManager; return rpManager;
} }
public static PluginManager ConstructPluginManager()
{
LazyInit();
if(pluginManager == null)
pluginManager = new PluginManager("./plugins/");
return pluginManager;
}
public static Integer GetGuildCount() public static Integer GetGuildCount()
{ synchronized(guildCache) { synchronized(guildCache)
{ {
+28 -2
View File
@@ -1,8 +1,34 @@
package core.lua; package core.lua;
// To promote flexibility, plugins are lua file with predefined callbacks. import java.io.IOException;
// They are executed between the initial built-in preprocessing and the command parsing. import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.stream.Stream;
//To promote flexibility, plugins are lua file with predefined callbacks.
//They are executed between the initial built-in preprocessing and the command parsing.
public class Plugin public class Plugin
{ {
public Path filepath;
public String contents;
public Plugin(Path filepath)
{
this.filepath = filepath;
StringBuilder contentBuilder = new StringBuilder();
try
{
Stream<String> stream = Files.lines(filepath, StandardCharsets.UTF_8);
stream.forEach(str -> contentBuilder.append(str).append("\n"));
stream.close();
contents = contentBuilder.toString();
}
catch (IOException e)
{
PluginLog.Error(e.getMessage());
}
}
} }
+42
View File
@@ -0,0 +1,42 @@
package core.lua;
import org.luaj.vm2.Globals;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.lib.jse.JsePlatform;
// This class wraps the lua layer - provides all the processing and function
// calls to the lua binding.
public class PluginLoader
{
private Globals globals;
public PluginLoader()
{
globals = JsePlatform.standardGlobals();
PluginLog.Log("Created new PluginLoader lua environment");
}
public String Process(Plugin toProcess, String args)
{
globals.load(toProcess.contents).call();
LuaValue pluginFunc = globals.get("plugin");
String output = null;
try
{
LuaValue res = pluginFunc.call(LuaValue.valueOf(args));
if(res.isnil())
output = null;
else
output = res.toString();
}
catch(Exception e)
{
output = null;
}
return output;
}
}
+11
View File
@@ -0,0 +1,11 @@
package core.lua;
import utils.GlobalLog;
import utils.LogFilter;
public class PluginLog
{
public static void Log(String s) { GlobalLog.Log(LogFilter.Plugin, s); }
public static void Warn(String s) { GlobalLog.Warn(LogFilter.Plugin, s); }
public static void Error(String s) { GlobalLog.Error(LogFilter.Plugin, s); }
}
+58 -2
View File
@@ -1,8 +1,64 @@
package core.lua; package core.lua;
// Reads in, handles, and manipulates plugins. Plugins are import java.nio.file.Files;
// loaded in the order they appear in the folder. import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.function.Consumer;
import java.util.stream.Stream;
//Reads in, handles, and manipulates plugins. Plugins are
//loaded in the order they appear in the folder.
public class PluginManager public class PluginManager
{ {
public PluginLoader pluginLoader;
public final String pluginFolder;
public ArrayList<Plugin> plugins;
public void AddPlugin(Path path)
{
plugins.add(new Plugin(path));
}
public PluginManager(String folder)
{
this.pluginFolder = folder;
plugins = new ArrayList<Plugin>();
this.pluginLoader = new PluginLoader();
try
{
try (Stream<Path> paths = Files.walk(Paths.get(this.pluginFolder)))
{
paths.filter(Files::isRegularFile).forEach((path)->{ AddPlugin(path); });
}
}
catch(Exception e)
{
PluginLog.Error(e.getMessage());
}
}
public String CallAll(String input)
{
for(int i = 0; i < plugins.size(); ++i)
{
Plugin script = plugins.get(i);
String out = pluginLoader.Process(script, input);
if(out != null)
{
PluginLog.Log("Executed plugin at " + script.filepath);
return out;
}
}
return null;
}
public void PrintAll()
{
for(int i = 0; i < plugins.size(); ++i)
PluginLog.Log(plugins.get(i).contents.toString());
}
} }
+15 -6
View File
@@ -2,6 +2,7 @@ package main;
import javax.security.auth.login.LoginException; import javax.security.auth.login.LoginException;
import core.*; import core.*;
import core.lua.PluginManager;
import dataStructures.KittyChannel; import dataStructures.KittyChannel;
import dataStructures.KittyGuild; import dataStructures.KittyGuild;
import dataStructures.KittyRole; import dataStructures.KittyRole;
@@ -22,13 +23,14 @@ import net.dv8tion.jda.core.*;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class Main extends ListenerAdapter public class Main extends ListenerAdapter
{ {
// Variables and stuff // Variables and bot specific objects
private static JDA kitty; private static JDA kitty;
private static CommandManager commandManager;
private static CommandEnabler commandEnabler;
private static DatabaseManager databaseManager; private static DatabaseManager databaseManager;
private static CommandEnabler commandEnabler;
private static CommandManager commandManager;
private static Stats stats; private static Stats stats;
private static RPManager rpManager; private static RPManager rpManager;
private static PluginManager pluginManager;
// Main test location // Main test location
public static void main(String[] args) throws InterruptedException, LoginException, Exception public static void main(String[] args) throws InterruptedException, LoginException, Exception
@@ -37,8 +39,9 @@ public class Main extends ListenerAdapter
databaseManager = ObjectBuilderFactory.ConstructDatabaseManager(); databaseManager = ObjectBuilderFactory.ConstructDatabaseManager();
commandEnabler = ObjectBuilderFactory.ConstructCommandEnabler(); commandEnabler = ObjectBuilderFactory.ConstructCommandEnabler();
commandManager = ObjectBuilderFactory.ConstructCommandManager(commandEnabler); commandManager = ObjectBuilderFactory.ConstructCommandManager(commandEnabler);
rpManager = ObjectBuilderFactory.ConstructRPManager();
stats = ObjectBuilderFactory.ConstructStats(commandManager); stats = ObjectBuilderFactory.ConstructStats(commandManager);
rpManager = ObjectBuilderFactory.ConstructRPManager();
pluginManager = ObjectBuilderFactory.ConstructPluginManager();
// Bot startup // Bot startup
kitty = new JDABuilder(AccountType.BOT).setToken(Ref.TestToken).buildBlocking(); kitty = new JDABuilder(AccountType.BOT).setToken(Ref.TestToken).buildBlocking();
@@ -72,8 +75,14 @@ public class Main extends ListenerAdapter
// RP logging system // RP logging system
RPManager.instance.addLine(channel, user, input); RPManager.instance.addLine(channel, user, input);
// Issue the command // Run plugins right before invoking the commands but after all other setup
commandManager.InvokeOnNewThread(guild, channel, user, input, response); String output = pluginManager.CallAll(input.message);
// Spin up the command if no plugins ran. Otherwise, send a response.
if(output == null)
commandManager.InvokeOnNewThread(guild, channel, user, input, response);
else
response.Call(output);
// Run any upkeep we need to // Run any upkeep we need to
PerCommandUpkeep(); PerCommandUpkeep();
+1 -1
View File
@@ -3,7 +3,7 @@ package utils;
public enum LogFilter public enum LogFilter
{ {
// Assign numbers as flags, so we can | ('or') them together as necessary // Assign numbers as flags, so we can | ('or') them together as necessary
Debug(0), Command(1), Core(2), Util(4), Database(8), Response(16), Network(32), Strings(64); Debug(0), Command(1), Core(2), Util(4), Database(8), Response(16), Network(32), Strings(64), Plugin(128);
private final int value; private final int value;
private LogFilter(int value) private LogFilter(int value)