Compare commits

..

5 Commits

Author SHA1 Message Date
jay
5b3804893b feat(command): fix to show web (including extra [MODE]) messages
There's no way to remove `bot.addChatPattern`, so only does once on load
2021-04-29 08:37:46 +05:00
jay
9f6fea2423 feat(command): 🔊 add system (non-chat) messages to console log
This includes anything that doesn't return a `.text`.
Such as an `extra`, `translate` or other `json` formatted message.
Ex:
- afk
- errors
- player leave and joins
2021-04-29 08:24:51 +05:00
jay
3686bab167 fix: 🐛 fix plugin reload for multi-file/dir based plugins
Now, it also (un-)loads the whole plugin (sub and master).

This appears to be the most stable option.
Loading behaviour is unchanged from before (load only top level plugin).
However as a precaution, loading tries to unload bad plugins on error.
This helps to not end up in a bad state during reload.
2021-04-29 08:14:40 +05:00
jay
e0c477a46f feat: 🔨 make fs.watch recursive, so it reloadplugin works also on directories 2021-04-27 11:47:25 +05:00
jay
6046123074 build: ⬆️ update deps 2021-04-25 07:13:55 +05:00
3 changed files with 51 additions and 17 deletions

View File

@ -29,21 +29,22 @@ cfg.botOptions = options
let plugins = {} let plugins = {}
function loadplugin(pluginname, pluginpath) { function loadplugin(pluginname, pluginpath = './plugins/' + pluginname) {
try { try {
plugins[pluginname] = require(pluginpath) plugins[pluginname] = require(pluginpath)
plugins[pluginname].load(cfg) plugins[pluginname].load(cfg)
} catch (error) { } catch (error) {
if (error.code == 'MODULE_NOT_FOUND') { if (error.code == 'MODULE_NOT_FOUND') {
console.warn('plugin not used:', pluginpath) console.warn('plugin not used:', pluginpath)
} else if (plugins[pluginname] && !plugins[pluginname].load) {
unloadplugin(pluginname, pluginpath)
} else { } else {
console.error(error) console.error(error)
} }
} }
} }
function unloadplugin(pluginname, pluginpath) { function unloadplugin(pluginname, pluginpath = './plugins/' + pluginname) {
pluginpath = pluginpath ? pluginpath : './plugins/' + pluginname
const plugin = require.resolve(pluginpath) const plugin = require.resolve(pluginpath)
try { try {
if (plugin && require.cache[plugin]) { if (plugin && require.cache[plugin]) {
@ -58,20 +59,28 @@ function unloadplugin(pluginname, pluginpath) {
} }
} }
reloadplugin = (event, filename, pluginpath) => { function reloadplugin(event, filename, pluginpath = './plugins/') {
if (!/\.js$/.test(filename)) { return } if (!/\.js$/.test(filename)) { return }
filename = filename.replace("\\", "/") // windows
if (!cfg.fsTimeout) { if (!cfg.fsTimeout) {
console.info(event, filename) console.info(event, filename)
pluginpath = (pluginpath ? pluginpath : './plugins/') + filename const fullpluginpath = pluginpath + filename
const pluginname = (filename.split(".js")[0]).replace(/\/.+/, "")
pluginpath = pluginpath + pluginname
const hassubplugin = fullpluginpath.replace(/\.js$/, "") !== pluginpath
const check = Object.keys(cfg.plugins) const check = Object.keys(cfg.plugins)
console.info(`reload file: ./lib/${pluginpath}`) console.info(`reload file: ./lib/${fullpluginpath}`)
const plugin = require.resolve(pluginpath) const plugin = require.resolve(fullpluginpath)
if (plugin && require.cache[plugin]) { if (plugin && require.cache[plugin]) {
// console.debug(Object.keys(cfg.plugins)) // console.debug(Object.keys(cfg.plugins))
unloadplugin(filename.split(".js")[0], pluginpath) unloadplugin(pluginname)
console.assert(Object.keys(cfg.plugins).length == check.length - 1, "plugin not removed, potential memory leak") console.assert(Object.keys(cfg.plugins).length == check.length - 1, "plugin not removed, potential memory leak")
if (hassubplugin) {
console.info("reload: also unloading sub")
unloadplugin(pluginname, fullpluginpath)
}
} }
loadplugin(filename.split(".js")[0], pluginpath) loadplugin(pluginname)
if (Object.keys(cfg.plugins).length != check.length) { if (Object.keys(cfg.plugins).length != check.length) {
// If left < right : // If left < right :
// - new plugin that's not registered in cfg.plugins, so added // - new plugin that's not registered in cfg.plugins, so added
@ -85,7 +94,7 @@ reloadplugin = (event, filename, pluginpath) => {
// console.log('file.js %s event', event) // console.log('file.js %s event', event)
} }
fs.watch('./lib/plugins', reloadplugin) fs.watch('./lib/plugins', { recursive: true }, reloadplugin)
cfg.bot = bot cfg.bot = bot
// TODO better name, or switch to array // TODO better name, or switch to array
@ -112,6 +121,8 @@ bot.once("spawn", () => {
cfg.plugins = plugins cfg.plugins = plugins
cfg.botAddressRegex = new RegExp(`^${bot.username} (${cfg.botAddressPrefix}.+)`) cfg.botAddressRegex = new RegExp(`^${bot.username} (${cfg.botAddressPrefix}.+)`)
// FIXME leaks every load, so adding here instead of command.js to load only once
bot.addChatPattern("web", /\[WEB\] (\[.+\])?\s*([\w.]+): (.+)/, { parse: true })
for (const plugin of Object.values(plugins)) { for (const plugin of Object.values(plugins)) {
try { try {

View File

@ -56,6 +56,29 @@ const events = {
}, 15 * 60 * 1000, bot, cfg); }, 15 * 60 * 1000, bot, cfg);
} }
} }
, message: systemMessage
, "chat:web": commandWeb
}
function systemMessage(...args) {
if (args[0]?.text) return
const metadata = (args[0]?.extra || args[0]?.with)?.map(v => v.text)
console.log(
"cmd msg:",
args[0]?.text || args[0]?.translate,
args[0]?.extra?.length || args[0]?.with?.length || Object.keys(args[0]?.json).length - 1,
metadata.length > 0 && metadata || args[0],
args.slice(1)
)
}
function commandWeb([[mode, username, message]]) {
console.log("web msg:", mode, username, message)
message && command(username, message)
}
function _clientSystemMessage(...args) {
console.log("cmd msg:", args[0]?.message, args[0]?.extra?.length, args[0]?.extra, args[0], args.slice(1))
} }
const events_registered = [] const events_registered = []

View File

@ -30,16 +30,16 @@
}, },
"homepage": "https://github.com/PrismarineJS/prismarine-template#readme", "homepage": "https://github.com/PrismarineJS/prismarine-template#readme",
"devDependencies": { "devDependencies": {
"@types/node": "^14.14.35", "@types/node": "^14.14.41",
"jest": "^26.6.3", "jest": "^26.6.3",
"require-self": "^0.2.3", "require-self": "^0.2.3",
"typescript": "^4.2.3" "typescript": "^4.2.4"
}, },
"dependencies": { "dependencies": {
"dotenv-packed": "^1.2.1", "dotenv-packed": "^1.2.2",
"minecraft-data": "^2.80.0", "minecraft-data": "^2.84.0",
"mineflayer": "^3.4.0", "mineflayer": "^3.6.0",
"mineflayer-armor-manager": "^1.4.0", "mineflayer-armor-manager": "^1.4.1",
"mineflayer-pathfinder": "^1.6.1", "mineflayer-pathfinder": "^1.6.1",
"mineflayer-pvp": "^1.0.2", "mineflayer-pvp": "^1.0.2",
"prismarine-block": "^1.8.0", "prismarine-block": "^1.8.0",
@ -49,7 +49,7 @@
"prismarine-nbt": "^1.5.0", "prismarine-nbt": "^1.5.0",
"prismarine-recipe": "^1.1.0", "prismarine-recipe": "^1.1.0",
"vec3": "^0.1.7", "vec3": "^0.1.7",
"xstate": "^4.17.0" "xstate": "^4.18.0"
}, },
"files": [ "files": [
"lib/**/*" "lib/**/*"