reorg
This commit is contained in:
parent
4d807373da
commit
aa93491a6c
1 changed files with 55 additions and 202 deletions
|
@ -49,7 +49,12 @@ As of February 10 2013, the js-plugins directory has the following sub-directori
|
|||
## Core Module
|
||||
|
||||
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.
|
||||
|
||||
* 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.
|
||||
A plugin is just a regular javascript object whose state is managed by
|
||||
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
|
||||
ScriptCraft. This makes it easier to write plugins which need to
|
||||
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)
|
||||
|
||||
***/
|
||||
var verbose = verbose || false;
|
||||
/*
|
||||
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")
|
||||
return ;
|
||||
var File = java.io.File;
|
||||
|
||||
var _canonize = function(file){
|
||||
return "" + file.getCanonicalPath().replaceAll("\\\\","/");
|
||||
};
|
||||
|
||||
var _originalScript = __script;
|
||||
var parentFileObj = new java.io.File(__script).getParentFile();
|
||||
var parentFileObj = new File(__script).getParentFile();
|
||||
var jsPluginsRootDir = parentFileObj.getParentFile();
|
||||
var jsPluginsRootDirName = _canonize(jsPluginsRootDir);
|
||||
|
||||
|
@ -257,9 +262,15 @@ var server = org.bukkit.Bukkit.server;
|
|||
*/
|
||||
var _load = function(filename,warnOnFileNotFound)
|
||||
{
|
||||
var result = null;
|
||||
var FileReader = java.io.FileReader
|
||||
,BufferedReader = java.io.BufferedReader
|
||||
,result = null
|
||||
,file = filename
|
||||
,r = undefined;
|
||||
|
||||
var file = new java.io.File(filename);
|
||||
if (!(filename instanceof File))
|
||||
file = new File(filename);
|
||||
|
||||
var canonizedFilename = _canonize(file);
|
||||
//
|
||||
// wph 20130123 don't load the same file more than once.
|
||||
|
@ -267,27 +278,24 @@ var server = org.bukkit.Bukkit.server;
|
|||
if (_loaded[canonizedFilename])
|
||||
return _loaded[canonizedFilename];
|
||||
|
||||
if (verbose)
|
||||
print("loading " + canonizedFilename);
|
||||
|
||||
if (file.exists()) {
|
||||
var parent = file.getParentFile();
|
||||
var reader = new java.io.FileReader(file);
|
||||
var br = new java.io.BufferedReader(reader);
|
||||
var reader = new FileReader(file);
|
||||
var br = new BufferedReader(reader);
|
||||
__engine.put("__script",canonizedFilename);
|
||||
__engine.put("__folder",(parent?_canonize(parent):"")+"/");
|
||||
|
||||
var code = "";
|
||||
try{
|
||||
if (file.getCanonicalPath().endsWith(".coffee")) {
|
||||
var r = undefined;
|
||||
while ((r = br.readLine()) !== null) code += "\"" + r + "\" +\n";
|
||||
code += "\"\"";
|
||||
var code = "load(__folder + \"../core/_coffeescript.js\"); var ___code = "+code+"; eval(CoffeeScript.compile(___code, {bare: true}))";
|
||||
} 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;
|
||||
}catch (e){
|
||||
__plugin.logger.severe("Error evaluating " + canonizedFilename + ", " + e );
|
||||
|
@ -306,168 +314,12 @@ var server = org.bukkit.Bukkit.server;
|
|||
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)
|
||||
{
|
||||
if (typeof dir == "undefined"){
|
||||
dir = new java.io.File(_originalScript).getParentFile().getParentFile();
|
||||
}
|
||||
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];
|
||||
};
|
||||
var config = _load(new File(jsPluginsRootDir, "data/global-config.json" ));
|
||||
if (!config)
|
||||
config = {verbose: false};
|
||||
global.config = config;
|
||||
/*
|
||||
Tab Completion of the /js and /jsp commands
|
||||
*/
|
||||
|
@ -568,6 +420,7 @@ var server = org.bukkit.Bukkit.server;
|
|||
}
|
||||
return result;
|
||||
};
|
||||
var _commands;
|
||||
/*
|
||||
Tab completion for the /js command
|
||||
*/
|
||||
|
@ -775,41 +628,41 @@ See [issue #69][issue69] for more information.
|
|||
__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.save = _save;
|
||||
global.plugin = _plugin;
|
||||
global.ready = _ready;
|
||||
global.command = _command;
|
||||
global.logger = __plugin.logger;
|
||||
global._onTabComplete = __onTabCompleteJS;
|
||||
global.addUnloadHandler = _addUnloadHandler;
|
||||
|
||||
var fnRequire = load(jsPluginsRootDirName + '/core/_require.js',true);
|
||||
global.require = fnRequire(__plugin, __engine, verbose);
|
||||
//
|
||||
// assumes this was loaded from js-plugins/core/
|
||||
// load all of the plugins.
|
||||
//
|
||||
_reload(jsPluginsRootDir);
|
||||
var fnRequire = load(jsPluginsRootDirName + '/lib/require.js',true);
|
||||
global.require = fnRequire(__plugin.logger, __engine, config.verbose, jsPluginsRootDirName);
|
||||
|
||||
//
|
||||
// all modules have loaded
|
||||
//
|
||||
for (var i =0;i < _deferred.length;i++)
|
||||
_deferred[i]();
|
||||
|
||||
events.on("server.PluginDisableEvent",function(l,e){
|
||||
//
|
||||
// save all plugins which have persistent data
|
||||
//
|
||||
for (var moduleName in _plugins){
|
||||
var pluginData = _plugins[moduleName];
|
||||
if (pluginData.persistent)
|
||||
save(pluginData.module.store, jsPluginsRootDirName + "/" + moduleName + "-store.txt");
|
||||
}
|
||||
_runUnloadHandlers();
|
||||
|
||||
var plugins = require('plugin');
|
||||
_commands = plugins.commands;
|
||||
global.plugin = plugins.plugin;
|
||||
global.command = plugins.command;
|
||||
global.save = plugins.save;
|
||||
plugins.autoload(jsPluginsRootDir);
|
||||
|
||||
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();
|
||||
org.bukkit.event.HandlerList["unregisterAll(org.bukkit.plugin.Plugin)"](__plugin);
|
||||
});
|
||||
|
||||
}());
|
||||
|
||||
|
||||
|
|
Reference in a new issue