reorg
This commit is contained in:
parent
4d807373da
commit
aa93491a6c
1 changed files with 55 additions and 202 deletions
|
@ -50,6 +50,11 @@ As of February 10 2013, the js-plugins directory has the following sub-directori
|
||||||
|
|
||||||
This module defines commonly used functions by all plugins...
|
This module defines commonly used functions by all plugins...
|
||||||
|
|
||||||
|
* echo (message) - Displays a message on the screen.
|
||||||
|
For example: `/js echo('Hello World')` will print Hello World on the in-game chat window.
|
||||||
|
For programmers familiar with Javascript web programming, an `alert` function is also provided.
|
||||||
|
`alert` works exactly the same as `echo` e.g. `alert('Hello World')`
|
||||||
|
|
||||||
* load (filename,warnOnFileNotFound) - loads and evaluates a javascript file, returning the evaluated object.
|
* load (filename,warnOnFileNotFound) - loads and evaluates a javascript file, returning the evaluated object.
|
||||||
|
|
||||||
* save (object, filename) - saves an object to a file.
|
* save (object, filename) - saves an object to a file.
|
||||||
|
@ -140,7 +145,7 @@ whose state you want to have managed by ScriptCraft - that is - a
|
||||||
Module whose state will be loaded at start up and saved at shut down.
|
Module whose state will be loaded at start up and saved at shut down.
|
||||||
A plugin is just a regular javascript object whose state is managed by
|
A plugin is just a regular javascript object whose state is managed by
|
||||||
ScriptCraft. The only member of the plugin which whose persistence is
|
ScriptCraft. The only member of the plugin which whose persistence is
|
||||||
managed by Scriptcraft is `state` - this special member will be
|
managed by Scriptcraft is `store` - this special member will be
|
||||||
automatically saved at shutdown and loaded at startup by
|
automatically saved at shutdown and loaded at startup by
|
||||||
ScriptCraft. This makes it easier to write plugins which need to
|
ScriptCraft. This makes it easier to write plugins which need to
|
||||||
persist data.
|
persist data.
|
||||||
|
@ -225,7 +230,6 @@ There are a couple of special javascript variables available in ScriptCraft...
|
||||||
* self - the current player. (Note - this value should not be used in multi-threaded scripts - it's not thread-safe)
|
* self - the current player. (Note - this value should not be used in multi-threaded scripts - it's not thread-safe)
|
||||||
|
|
||||||
***/
|
***/
|
||||||
var verbose = verbose || false;
|
|
||||||
/*
|
/*
|
||||||
wph 20130124 - make self, plugin and server public - these are far more useful now that tab-complete works.
|
wph 20130124 - make self, plugin and server public - these are far more useful now that tab-complete works.
|
||||||
*/
|
*/
|
||||||
|
@ -239,13 +243,14 @@ var server = org.bukkit.Bukkit.server;
|
||||||
//
|
//
|
||||||
if (typeof load == "function")
|
if (typeof load == "function")
|
||||||
return ;
|
return ;
|
||||||
|
var File = java.io.File;
|
||||||
|
|
||||||
var _canonize = function(file){
|
var _canonize = function(file){
|
||||||
return "" + file.getCanonicalPath().replaceAll("\\\\","/");
|
return "" + file.getCanonicalPath().replaceAll("\\\\","/");
|
||||||
};
|
};
|
||||||
|
|
||||||
var _originalScript = __script;
|
var _originalScript = __script;
|
||||||
var parentFileObj = new java.io.File(__script).getParentFile();
|
var parentFileObj = new File(__script).getParentFile();
|
||||||
var jsPluginsRootDir = parentFileObj.getParentFile();
|
var jsPluginsRootDir = parentFileObj.getParentFile();
|
||||||
var jsPluginsRootDirName = _canonize(jsPluginsRootDir);
|
var jsPluginsRootDirName = _canonize(jsPluginsRootDir);
|
||||||
|
|
||||||
|
@ -257,9 +262,15 @@ var server = org.bukkit.Bukkit.server;
|
||||||
*/
|
*/
|
||||||
var _load = function(filename,warnOnFileNotFound)
|
var _load = function(filename,warnOnFileNotFound)
|
||||||
{
|
{
|
||||||
var result = null;
|
var FileReader = java.io.FileReader
|
||||||
|
,BufferedReader = java.io.BufferedReader
|
||||||
|
,result = null
|
||||||
|
,file = filename
|
||||||
|
,r = undefined;
|
||||||
|
|
||||||
|
if (!(filename instanceof File))
|
||||||
|
file = new File(filename);
|
||||||
|
|
||||||
var file = new java.io.File(filename);
|
|
||||||
var canonizedFilename = _canonize(file);
|
var canonizedFilename = _canonize(file);
|
||||||
//
|
//
|
||||||
// wph 20130123 don't load the same file more than once.
|
// wph 20130123 don't load the same file more than once.
|
||||||
|
@ -267,27 +278,24 @@ var server = org.bukkit.Bukkit.server;
|
||||||
if (_loaded[canonizedFilename])
|
if (_loaded[canonizedFilename])
|
||||||
return _loaded[canonizedFilename];
|
return _loaded[canonizedFilename];
|
||||||
|
|
||||||
if (verbose)
|
|
||||||
print("loading " + canonizedFilename);
|
|
||||||
|
|
||||||
if (file.exists()) {
|
if (file.exists()) {
|
||||||
var parent = file.getParentFile();
|
var parent = file.getParentFile();
|
||||||
var reader = new java.io.FileReader(file);
|
var reader = new FileReader(file);
|
||||||
var br = new java.io.BufferedReader(reader);
|
var br = new BufferedReader(reader);
|
||||||
__engine.put("__script",canonizedFilename);
|
__engine.put("__script",canonizedFilename);
|
||||||
__engine.put("__folder",(parent?_canonize(parent):"")+"/");
|
__engine.put("__folder",(parent?_canonize(parent):"")+"/");
|
||||||
|
|
||||||
var code = "";
|
var code = "";
|
||||||
try{
|
try{
|
||||||
if (file.getCanonicalPath().endsWith(".coffee")) {
|
if (file.getCanonicalPath().endsWith(".coffee")) {
|
||||||
var r = undefined;
|
|
||||||
while ((r = br.readLine()) !== null) code += "\"" + r + "\" +\n";
|
while ((r = br.readLine()) !== null) code += "\"" + r + "\" +\n";
|
||||||
code += "\"\"";
|
code += "\"\"";
|
||||||
var code = "load(__folder + \"../core/_coffeescript.js\"); var ___code = "+code+"; eval(CoffeeScript.compile(___code, {bare: true}))";
|
var code = "load(__folder + \"../core/_coffeescript.js\"); var ___code = "+code+"; eval(CoffeeScript.compile(___code, {bare: true}))";
|
||||||
} else {
|
} else {
|
||||||
while ((r = br.readLine()) !== null) code += r + "\n";
|
while ((r = br.readLine()) !== null)
|
||||||
|
code += r + "\n";
|
||||||
}
|
}
|
||||||
result = __engine.eval(code);
|
result = __engine.eval("(" + code + ")");
|
||||||
_loaded[canonizedFilename] = result || true;
|
_loaded[canonizedFilename] = result || true;
|
||||||
}catch (e){
|
}catch (e){
|
||||||
__plugin.logger.severe("Error evaluating " + canonizedFilename + ", " + e );
|
__plugin.logger.severe("Error evaluating " + canonizedFilename + ", " + e );
|
||||||
|
@ -306,168 +314,12 @@ var server = org.bukkit.Bukkit.server;
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
/*
|
/*
|
||||||
recursively walk the given directory and return a list of all .js files
|
now that load is defined, use it to load a global config object
|
||||||
*/
|
*/
|
||||||
var _listSourceFiles = function(store,dir)
|
var config = _load(new File(jsPluginsRootDir, "data/global-config.json" ));
|
||||||
{
|
if (!config)
|
||||||
if (typeof dir == "undefined"){
|
config = {verbose: false};
|
||||||
dir = new java.io.File(_originalScript).getParentFile().getParentFile();
|
global.config = config;
|
||||||
}
|
|
||||||
var files = dir.listFiles();
|
|
||||||
for (var i = 0;i < files.length; i++){
|
|
||||||
var file = files[i];
|
|
||||||
if (file.isDirectory()){
|
|
||||||
_listSourceFiles(store,file);
|
|
||||||
}else{
|
|
||||||
if ((file.getCanonicalPath().endsWith(".js") || file.getCanonicalPath().endsWith(".coffee")) &&
|
|
||||||
!(file.getName().startsWith("_")) &&
|
|
||||||
file.exists())
|
|
||||||
{
|
|
||||||
store.push(file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
/*
|
|
||||||
sort so that .js files with same name as parent directory appear before
|
|
||||||
other files in the same directory
|
|
||||||
*/
|
|
||||||
var sortByModule = function(a,b){
|
|
||||||
a = _canonize(a);
|
|
||||||
b = _canonize(b);
|
|
||||||
var aparts = (""+a).split(/\//);
|
|
||||||
var bparts = (""+b).split(/\//);
|
|
||||||
//var adir = aparts[aparts.length-2];
|
|
||||||
var adir = aparts.slice(0,aparts.length-1).join("/");
|
|
||||||
var afile = aparts[aparts.length-1];
|
|
||||||
//var bdir = bparts[bparts.length-2];
|
|
||||||
var bdir = bparts.slice(0,bparts.length-1).join("/");
|
|
||||||
var bfile = bparts[bparts.length-1];
|
|
||||||
|
|
||||||
if(adir<bdir) return -1;
|
|
||||||
if(adir>bdir) return 1;
|
|
||||||
|
|
||||||
afile = afile.match(/[a-zA-Z0-9\-_]+/)[0];
|
|
||||||
|
|
||||||
if (adir.match(new RegExp(afile + "$")))
|
|
||||||
return -1;
|
|
||||||
else
|
|
||||||
return 1;
|
|
||||||
};
|
|
||||||
/*
|
|
||||||
Reload all of the .js files in the given directory
|
|
||||||
*/
|
|
||||||
var _reload = function(pluginDir)
|
|
||||||
{
|
|
||||||
_loaded = [];
|
|
||||||
var sourceFiles = [];
|
|
||||||
_listSourceFiles(sourceFiles,pluginDir);
|
|
||||||
|
|
||||||
sourceFiles.sort(sortByModule);
|
|
||||||
|
|
||||||
//
|
|
||||||
// script files whose name begins with _ (underscore)
|
|
||||||
// will not be loaded automatically at startup.
|
|
||||||
// These files are assumed to be dependencies/private to plugins
|
|
||||||
//
|
|
||||||
// E.g. If you have a plugin called myMiniGame.js in the myMiniGame directory
|
|
||||||
// and which in addition to myMiniGame.js also includes _myMiniGame_currency.js _myMiniGame_events.js etc.
|
|
||||||
// then it's assumed that _myMiniGame_currency.js and _myMiniGame_events.js will be loaded
|
|
||||||
// as dependencies by myMiniGame.js and do not need to be loaded via js reload
|
|
||||||
//
|
|
||||||
var len = sourceFiles.length;
|
|
||||||
for (var i = 0;i < len; i++){
|
|
||||||
load(_canonize(sourceFiles[i]),true);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
Save a javascript object to a file (saves using JSON notation)
|
|
||||||
*/
|
|
||||||
var _save = function(object, filename){
|
|
||||||
var objectToStr = null;
|
|
||||||
try{
|
|
||||||
objectToStr = JSON.stringify(object);
|
|
||||||
}catch(e){
|
|
||||||
print("ERROR: " + e.getMessage() + " while saving " + filename);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var f = new java.io.File(filename);
|
|
||||||
var out = new java.io.PrintWriter(new java.io.FileWriter(f));
|
|
||||||
out.println("__data = " + objectToStr);
|
|
||||||
out.close();
|
|
||||||
};
|
|
||||||
/*
|
|
||||||
plugin management
|
|
||||||
*/
|
|
||||||
var _plugins = {};
|
|
||||||
var _plugin = function(/* String */ moduleName, /* Object */ moduleObject, isPersistent)
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// don't load plugin more than once
|
|
||||||
//
|
|
||||||
if (typeof _plugins[moduleName] != "undefined")
|
|
||||||
return _plugins[moduleName].module;
|
|
||||||
|
|
||||||
var pluginData = {persistent: isPersistent, module: moduleObject};
|
|
||||||
moduleObject.store = moduleObject.store || {};
|
|
||||||
_plugins[moduleName] = pluginData;
|
|
||||||
|
|
||||||
if (isPersistent)
|
|
||||||
moduleObject.store = load(jsPluginsRootDirName + "/" + moduleName + "-store.txt") || {};
|
|
||||||
|
|
||||||
global[moduleName] = moduleObject;
|
|
||||||
return moduleObject;
|
|
||||||
};
|
|
||||||
/*
|
|
||||||
allow for deferred execution (once all modules have loaded)
|
|
||||||
*/
|
|
||||||
var _deferred = [];
|
|
||||||
var _ready = function( func ){
|
|
||||||
_deferred.push(func);
|
|
||||||
};
|
|
||||||
var _cmdInterceptors = [];
|
|
||||||
/*
|
|
||||||
command management - allow for non-ops to execute approved javascript code.
|
|
||||||
*/
|
|
||||||
var _commands = {};
|
|
||||||
var _command = function(name,func,options,intercepts)
|
|
||||||
{
|
|
||||||
if (typeof name == "undefined"){
|
|
||||||
// it's an invocation from the Java Plugin!
|
|
||||||
if (__cmdArgs.length === 0)
|
|
||||||
throw new Error("Usage: jsp command-name command-parameters");
|
|
||||||
var name = __cmdArgs[0];
|
|
||||||
var cmd = _commands[name];
|
|
||||||
if (typeof cmd === "undefined"){
|
|
||||||
// it's not a global command - pass it on to interceptors
|
|
||||||
var intercepted = false;
|
|
||||||
for (var i = 0;i < _cmdInterceptors.length;i++){
|
|
||||||
if (_cmdInterceptors[i](__cmdArgs))
|
|
||||||
intercepted = true;
|
|
||||||
}
|
|
||||||
if (!intercepted)
|
|
||||||
self.sendMessage("Command '" + name + "' is not recognised");
|
|
||||||
}else{
|
|
||||||
func = cmd.callback;
|
|
||||||
var params = [];
|
|
||||||
for (var i =1; i < __cmdArgs.length;i++){
|
|
||||||
params.push("" + __cmdArgs[i]);
|
|
||||||
}
|
|
||||||
return func(params);
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
if (typeof options == "undefined")
|
|
||||||
options = [];
|
|
||||||
_commands[name] = {callback: func, options: options};
|
|
||||||
if (intercepts)
|
|
||||||
_cmdInterceptors.push(func);
|
|
||||||
return func;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
var _rmCommand = function(name){
|
|
||||||
delete _commands[name];
|
|
||||||
};
|
|
||||||
/*
|
/*
|
||||||
Tab Completion of the /js and /jsp commands
|
Tab Completion of the /js and /jsp commands
|
||||||
*/
|
*/
|
||||||
|
@ -568,6 +420,7 @@ var server = org.bukkit.Bukkit.server;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
var _commands;
|
||||||
/*
|
/*
|
||||||
Tab completion for the /js command
|
Tab completion for the /js command
|
||||||
*/
|
*/
|
||||||
|
@ -775,41 +628,41 @@ See [issue #69][issue69] for more information.
|
||||||
__plugin.pluginLoader.enablePlugin(__plugin);
|
__plugin.pluginLoader.enablePlugin(__plugin);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var _echo = function (msg) {
|
||||||
|
__plugin.logger.info( msg );
|
||||||
|
if (typeof self == "undefined"){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self.sendMessage(msg);
|
||||||
|
};
|
||||||
|
|
||||||
|
global.echo = _echo;
|
||||||
|
global.alert = _echo;
|
||||||
global.load = _load;
|
global.load = _load;
|
||||||
global.save = _save;
|
global.logger = __plugin.logger;
|
||||||
global.plugin = _plugin;
|
|
||||||
global.ready = _ready;
|
|
||||||
global.command = _command;
|
|
||||||
global._onTabComplete = __onTabCompleteJS;
|
global._onTabComplete = __onTabCompleteJS;
|
||||||
global.addUnloadHandler = _addUnloadHandler;
|
global.addUnloadHandler = _addUnloadHandler;
|
||||||
|
|
||||||
var fnRequire = load(jsPluginsRootDirName + '/core/_require.js',true);
|
var fnRequire = load(jsPluginsRootDirName + '/lib/require.js',true);
|
||||||
global.require = fnRequire(__plugin, __engine, verbose);
|
global.require = fnRequire(__plugin.logger, __engine, config.verbose, jsPluginsRootDirName);
|
||||||
//
|
|
||||||
// assumes this was loaded from js-plugins/core/
|
|
||||||
// load all of the plugins.
|
|
||||||
//
|
|
||||||
_reload(jsPluginsRootDir);
|
|
||||||
|
|
||||||
//
|
|
||||||
// all modules have loaded
|
|
||||||
//
|
|
||||||
for (var i =0;i < _deferred.length;i++)
|
|
||||||
_deferred[i]();
|
|
||||||
|
|
||||||
events.on("server.PluginDisableEvent",function(l,e){
|
var plugins = require('plugin');
|
||||||
//
|
_commands = plugins.commands;
|
||||||
// save all plugins which have persistent data
|
global.plugin = plugins.plugin;
|
||||||
//
|
global.command = plugins.command;
|
||||||
for (var moduleName in _plugins){
|
global.save = plugins.save;
|
||||||
var pluginData = _plugins[moduleName];
|
plugins.autoload(jsPluginsRootDir);
|
||||||
if (pluginData.persistent)
|
|
||||||
save(pluginData.module.store, jsPluginsRootDirName + "/" + moduleName + "-store.txt");
|
var events = require('events');
|
||||||
}
|
events.on('server.PluginDisableEvent',function(l,e){
|
||||||
|
// save config
|
||||||
|
plugins.save(global.config, new File(jsPluginsRootDir, "data/global-config.json" ));
|
||||||
|
|
||||||
_runUnloadHandlers();
|
_runUnloadHandlers();
|
||||||
org.bukkit.event.HandlerList["unregisterAll(org.bukkit.plugin.Plugin)"](__plugin);
|
org.bukkit.event.HandlerList["unregisterAll(org.bukkit.plugin.Plugin)"](__plugin);
|
||||||
});
|
});
|
||||||
|
|
||||||
}());
|
}());
|
||||||
|
|
||||||
|
|
||||||
|
|
Reference in a new issue