Merge remote-tracking branch 'origin/develop' into develop
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
-- Example plugin stub. This function is called and passed the input message.
|
-- Example plugin stub. This function is called and passed the input message.
|
||||||
-- If nil is returned, the plugin is considered to have not run, but if any
|
-- If nil is returned, the plugin is considered to have not run, but if any
|
||||||
-- other value is returned, it's interpreted as a string and sent back to the user.
|
-- other value is returned, it's interpreted as a string and sent back to the user.
|
||||||
|
-- 'local' variables inside of this file persiste between plugin calls.
|
||||||
function plugin(message)
|
function plugin(message)
|
||||||
return nil;
|
return nil;
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -74,35 +74,40 @@ public class CommandManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Calls the command but on a whole new thread!
|
// Calls the command but on a whole new thread!
|
||||||
public void InvokeOnNewThread(KittyGuild guild, KittyChannel channel, KittyUser user, UserInput input, Response responseContext)
|
public boolean InvokeOnNewThread(KittyGuild guild, KittyChannel channel, KittyUser user, UserInput input, Response responseContext)
|
||||||
{
|
{
|
||||||
// This is here to prevent spinning up a thread if this wasn't even a command.
|
// This is here to prevent spinning up a thread if this wasn't even a command.
|
||||||
if(input == null || !input.IsValid())
|
if(input == null || !input.IsValid())
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
// Spin up a thread and begin it. The thread carries the info needed to invoke the command.
|
Command command = commands.get(input.key);
|
||||||
CommandThread newThread = new CommandThread(this, input, guild, channel, user, responseContext);
|
if(command != null)
|
||||||
threadAccumulator.add(newThread);
|
{
|
||||||
newThread.start();
|
// Spin up a thread and begin it. The thread carries the info needed to invoke the command.
|
||||||
|
CommandThread newThread = new CommandThread(this, input, guild, channel, user, responseContext);
|
||||||
|
threadAccumulator.add(newThread);
|
||||||
|
newThread.start();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GlobalLog.Warn(LogFilter.Command, "User " + user.name + " tried to invoke command that doesn't exist: " + input.key);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calls the command specified with the key, providing user information arguments, etc.
|
// Calls the command specified with the key, providing user information arguments, etc.
|
||||||
public void Invoke(KittyGuild guild, KittyChannel channel, KittyUser user, UserInput input, Response responseContext)
|
void Invoke(KittyGuild guild, KittyChannel channel, KittyUser user, UserInput input, Response responseContext)
|
||||||
{
|
{
|
||||||
if(input == null || !input.IsValid())
|
if(input == null || !input.IsValid())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Command command = commands.get(input.key);
|
Command command = commands.get(input.key);
|
||||||
|
|
||||||
if(command != null)
|
if(command != null)
|
||||||
{
|
{
|
||||||
++invokeCount;
|
++invokeCount;
|
||||||
command.Invoke(guild, channel, user, input, responseContext);
|
command.Invoke(guild, channel, user, input, responseContext);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
GlobalLog.Warn(LogFilter.Command, "User " + user.name + " tried to invoke command that doesn't exist: " + input.key);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Looks up command by name. If it exists, dumps help text, otherwise returns null.
|
// Looks up command by name. If it exists, dumps help text, otherwise returns null.
|
||||||
|
|||||||
@@ -6,29 +6,61 @@ import java.nio.file.Files;
|
|||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
//To promote flexibility, plugins are lua file with predefined callbacks.
|
import org.luaj.vm2.Globals;
|
||||||
//They are executed between the initial built-in preprocessing and the command parsing.
|
import org.luaj.vm2.LuaValue;
|
||||||
|
import org.luaj.vm2.lib.jse.JsePlatform;
|
||||||
|
|
||||||
|
// To promote flexibility, plugins are lua file with predefined callbacks.
|
||||||
|
// They are executed between the initial built-in preprocessing and the command parsing.
|
||||||
|
// This class wraps the lua layer - provides all the processing and function calls to the lua binding.
|
||||||
public class Plugin
|
public class Plugin
|
||||||
{
|
{
|
||||||
public Path filepath;
|
public Path filepath;
|
||||||
public String contents;
|
public String contents;
|
||||||
|
private Globals globals;
|
||||||
|
private LuaValue func_plugin;
|
||||||
|
|
||||||
public Plugin(Path filepath)
|
public Plugin(Path filepath)
|
||||||
{
|
{
|
||||||
this.filepath = filepath;
|
this.filepath = filepath;
|
||||||
|
|
||||||
StringBuilder contentBuilder = new StringBuilder();
|
|
||||||
|
|
||||||
|
StringBuilder contentBuilder = new StringBuilder();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Stream<String> stream = Files.lines(filepath, StandardCharsets.UTF_8);
|
Stream<String> stream = Files.lines(filepath, StandardCharsets.UTF_8);
|
||||||
stream.forEach(str -> contentBuilder.append(str).append("\n"));
|
stream.forEach(str -> contentBuilder.append(str).append("\n"));
|
||||||
stream.close();
|
stream.close();
|
||||||
contents = contentBuilder.toString();
|
contents = contentBuilder.toString();
|
||||||
|
|
||||||
|
globals = JsePlatform.standardGlobals();
|
||||||
|
|
||||||
|
globals.load(contents).call();
|
||||||
|
func_plugin = globals.get("plugin");
|
||||||
|
|
||||||
|
String output = null;
|
||||||
}
|
}
|
||||||
catch (IOException e)
|
catch (IOException e)
|
||||||
{
|
{
|
||||||
PluginLog.Error(e.getMessage());
|
PluginLog.Error(e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String Run(String args)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
LuaValue res = func_plugin.call(LuaValue.valueOf(args));
|
||||||
|
|
||||||
|
if(!res.isnil())
|
||||||
|
return res.toString();
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
PluginLog.Error("Failed to run plugin from file " + filepath);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,42 +0,0 @@
|
|||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -9,7 +9,6 @@ import java.util.stream.Stream;
|
|||||||
// Reads in, handles, and manipulates plugins. Plugins are loaded in the order they appear in the folder.
|
// 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 final String pluginFolder;
|
||||||
public ArrayList<Plugin> plugins;
|
public ArrayList<Plugin> plugins;
|
||||||
|
|
||||||
@@ -22,8 +21,7 @@ public class PluginManager
|
|||||||
{
|
{
|
||||||
this.pluginFolder = folder;
|
this.pluginFolder = folder;
|
||||||
plugins = new ArrayList<Plugin>();
|
plugins = new ArrayList<Plugin>();
|
||||||
this.pluginLoader = new PluginLoader();
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
try (Stream<Path> paths = Files.walk(Paths.get(this.pluginFolder)))
|
try (Stream<Path> paths = Files.walk(Paths.get(this.pluginFolder)))
|
||||||
@@ -37,16 +35,18 @@ public class PluginManager
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String CallAll(String input)
|
// Runs all plugins, returning when it gets a non-nill result.
|
||||||
|
// Otherwise, returns null.
|
||||||
|
public String RunAll(String input)
|
||||||
{
|
{
|
||||||
for(int i = 0; i < plugins.size(); ++i)
|
for(int i = 0; i < plugins.size(); ++i)
|
||||||
{
|
{
|
||||||
Plugin script = plugins.get(i);
|
Plugin plugin = plugins.get(i);
|
||||||
String out = pluginLoader.Process(script, input);
|
String out = plugin.Run(input);
|
||||||
|
|
||||||
if(out != null)
|
if(out != null)
|
||||||
{
|
{
|
||||||
PluginLog.Log("Executed plugin at " + script.filepath);
|
PluginLog.Log("Executed plugin at " + plugin.filepath);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-7
@@ -76,14 +76,18 @@ public class Main extends ListenerAdapter
|
|||||||
// RP logging system
|
// RP logging system
|
||||||
RPManager.instance.addLine(channel, user, input);
|
RPManager.instance.addLine(channel, user, input);
|
||||||
|
|
||||||
// Run plugins right before invoking the commands but after all other setup
|
//
|
||||||
String output = pluginManager.CallAll(input.message);
|
|
||||||
|
|
||||||
// Spin up the command if no plugins ran. Otherwise, send a response.
|
|
||||||
if(output == null)
|
// Attempt to spin up a command. If the command doesn't exist.
|
||||||
commandManager.InvokeOnNewThread(guild, channel, user, input, response);
|
// Run plugins right before invoking the commands but after all other setup.
|
||||||
else
|
if(commandManager.InvokeOnNewThread(guild, channel, user, input, response) == false)
|
||||||
response.Call(output);
|
{
|
||||||
|
String pluginOutput = pluginManager.RunAll(input.message);
|
||||||
|
|
||||||
|
if(pluginOutput != null)
|
||||||
|
response.Call(pluginOutput);
|
||||||
|
}
|
||||||
|
|
||||||
// Run any upkeep we need to
|
// Run any upkeep we need to
|
||||||
PerCommandUpkeep();
|
PerCommandUpkeep();
|
||||||
|
|||||||
Reference in New Issue
Block a user