Merge pull request #3281 from thelounge/mcinkay/input-refactor

Refactor command API for plugins
This commit is contained in:
Pavel Djundik 2019-07-05 17:26:06 +03:00 committed by GitHub
commit 807856dbef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 68 additions and 21 deletions

View File

@ -12,6 +12,7 @@ const UAParser = require("ua-parser-js");
const uuidv4 = require("uuid/v4");
const escapeRegExp = require("lodash/escapeRegExp");
const inputs = require("./plugins/inputs");
const PublicClient = require("./plugins/packages/publicClient");
const MessageStorage = require("./plugins/messageStorage/sqlite");
const TextFileMessageStorage = require("./plugins/messageStorage/text");
@ -336,20 +337,19 @@ Client.prototype.inputLine = function(data) {
const irc = target.network.irc;
let connected = irc && irc.connection && irc.connection.connected;
if (Object.prototype.hasOwnProperty.call(inputs.userInputs, cmd) && typeof inputs.userInputs[cmd].input === "function") {
const plugin = inputs.userInputs[cmd];
if (inputs.userInputs.has(cmd)) {
const plugin = inputs.userInputs.get(cmd);
if (connected || plugin.allowDisconnected) {
if (typeof plugin.input === "function" && (connected || plugin.allowDisconnected)) {
connected = true;
plugin.input.apply(client,
[
target.network,
target.chan,
cmd,
args,
(command) => this.inputLine({target: data.target, text: command}),
]
);
plugin.input.apply(client, [target.network, target.chan, cmd, args]);
}
} else if (inputs.pluginCommands.has(cmd)) {
const plugin = inputs.pluginCommands.get(cmd);
if (typeof plugin.input === "function" && (connected || plugin.allowDisconnected)) {
connected = true;
plugin.input(new PublicClient(client), {network: target.network, chan: target.chan}, cmd, args);
}
} else if (connected) {
irc.raw(text);

View File

@ -37,18 +37,25 @@ const userInputs = [
"whois",
].reduce(function(plugins, name) {
const plugin = require(`./${name}`);
plugin.commands.forEach((command) => (plugins[command] = plugin));
plugin.commands.forEach((command) => plugins.set(command, plugin));
return plugins;
}, {});
}, new Map());
const pluginCommands = new Map();
const getCommands = () =>
Object.keys(userInputs)
Array.from(userInputs.keys())
.concat(Array.from(pluginCommands.keys()))
.map((command) => `/${command}`)
.concat(clientSideCommands)
.concat(passThroughCommands)
.sort();
const addPluginCommand = (command, func) => pluginCommands.set(command, func);
module.exports = {
addPluginCommand,
getCommands,
pluginCommands,
userInputs,
};

View File

@ -16,14 +16,14 @@ module.exports = {
loadPackages,
};
const packageApis = function(clientManager, packageName) {
const packageApis = function(packageName) {
return {
Stylesheets: {
addFile: addStylesheet.bind(this, packageName),
},
Commands: {
add: (command, func) => inputs.userInputs[command] = func,
runAsUser: (line, userName, target) => clientManager.findClient(userName).inputLine({target, text: line}),
add: inputs.addPluginCommand,
runAsUser: (command, targetId, client) => client.inputLine({target: targetId, text: command}),
},
Config: {
getConfig: () => Helper.config,
@ -43,7 +43,7 @@ function getPackage(name) {
return packageMap.get(name);
}
function loadPackages(clientManager) {
function loadPackages() {
const packageJson = path.join(Helper.getPackagesPath(), "package.json");
let packages;
let anyPlugins = false;
@ -83,7 +83,7 @@ function loadPackages(clientManager) {
}
if (packageFile.onServerStart) {
packageFile.onServerStart(packageApis(clientManager, packageName));
packageFile.onServerStart(packageApis(packageName));
}
log.info(`Package ${colors.bold(packageName)} loaded`);

View File

@ -0,0 +1,40 @@
module.exports = class PublicClient {
constructor(client) {
this.client = client;
}
/**
*
* @param {String} command - IRC command to run, this is in the same format that a client would send to the server (eg: JOIN #test)
* @param {String} targetId - The id of the channel to simulate the command coming from. Replies will go to this channel if appropriate
*/
runAsUser(command, targetId) {
this.client.inputLine({target: targetId, text: command});
}
/**
*
* @param {Object} attributes
*/
createChannel(attributes) {
return this.client.createChannel(attributes);
}
/**
* Emits an `event` to the browser client, with `data` in the body of the event.
*
* @param {String} event - Name of the event, must be something the browser will recognise
* @param {Object} data - Body of the event, can be anything, but will need to be properly interpreted by the client
*/
sendToBrowser(event, data) {
this.client.emit(event, data);
}
/**
*
* @param {Number} chanId
*/
getChannel(chanId) {
return this.client.find(chanId);
}
};

View File

@ -173,7 +173,7 @@ module.exports = function() {
});
manager = new ClientManager();
packages.loadPackages(manager);
packages.loadPackages();
new Identification((identHandler) => {
manager.init(identHandler, sockets);