From a7a4bf79a1250ffbc80894ce29842c892341ea50 Mon Sep 17 00:00:00 2001 From: walterhiggins Date: Fri, 27 Dec 2013 22:50:13 +0000 Subject: [PATCH] Updated alias to support aliases without 'jsp' prefix, added 'console' global variable --- src/main/javascript/lib/console.js | 57 ++++++ src/main/javascript/lib/tabcomplete-jsp.js | 43 ++++ src/main/javascript/lib/tabcomplete.js | 171 ++++++++++++++++ .../plugins/minigames/SnowBallFight.js | 183 ------------------ 4 files changed, 271 insertions(+), 183 deletions(-) create mode 100644 src/main/javascript/lib/console.js create mode 100644 src/main/javascript/lib/tabcomplete-jsp.js create mode 100644 src/main/javascript/lib/tabcomplete.js delete mode 100644 src/main/javascript/plugins/minigames/SnowBallFight.js diff --git a/src/main/javascript/lib/console.js b/src/main/javascript/lib/console.js new file mode 100644 index 0000000..77c27bd --- /dev/null +++ b/src/main/javascript/lib/console.js @@ -0,0 +1,57 @@ +/************************************************************************* +## console global variable + +ScriptCraft provides a `console` global variable with the followng methods... + + * log() + * info() + * warn() + * error() + +The ScriptCraft console methods work like the Web API implementation. + +### Example + + console.log('Hello %s', 'world'); + +Basic variable substitution is supported (ScriptCraft's implementation +of console uses the Bukkit Plugin [Logger][lgr] under the hood and +uses [java.lang.String.format()][strfmt] for variable +substitution. All output will be sent to the server console (not +in-game). + +[lgr]: http://jd.bukkit.org/beta/apidocs/org/bukkit/plugin/PluginLogger.html +[strfmt]: http://docs.oracle.com/javase/6/docs/api/java/lang/String.html#format(java.lang.String, java.lang.Object...) + +***/ +var argsToArray = function(args){ + var result = []; + for (var i =0;i < args.length; i++) + result.push(args[i]); + return result; +} +var log = function(level, restOfArgs){ + var args = argsToArray(restOfArgs); + if (args.length > 1){ + var msg = java.lang.String.format(args[0],args.slice(1)); + logger['log(java.util.logging.Level,java.lang.String)'](level,msg); + }else{ + logger['log(java.util.logging.Level,java.lang.String)'](level, args[0]); + } +}; + +var Level = java.util.logging.Level; + +exports.log = function(){ + log(Level.INFO, arguments); +}; + +exports.info = function(){ + log(Level.INFO, arguments); +} +exports.warn = function(){ + log(Level.WARNING, arguments); +}; +exports.error = function(){ + log(Level.SEVERE, arguments); +}; diff --git a/src/main/javascript/lib/tabcomplete-jsp.js b/src/main/javascript/lib/tabcomplete-jsp.js new file mode 100644 index 0000000..1d3764f --- /dev/null +++ b/src/main/javascript/lib/tabcomplete-jsp.js @@ -0,0 +1,43 @@ +var _commands = require('plugin').commands; +/* + Tab completion for the /jsp commmand +*/ +var __onTabCompleteJSP = function() { + var result = global.__onTC_result; + var args = global.__onTC_args; + var cmdInput = args[0]; + var cmd = _commands[cmdInput]; + if (cmd){ + var opts = cmd.options; + var len = opts.length; + if (args.length == 1){ + for (var i = 0;i < len; i++) + result.add(opts[i]); + }else{ + // partial e.g. /jsp chat_color dar + for (var i = 0;i < len; i++){ + if (opts[i].indexOf(args[1]) == 0){ + result.add(opts[i]); + } + } + } + }else{ + if (args.length == 0){ + for (var i in _commands) + result.add(i); + }else{ + // partial e.g. /jsp al + // should tabcomplete to alias + // + for (var c in _commands){ + if (c.indexOf(cmdInput) == 0){ + result.add(c); + } + } + } + } + return result; +}; +module.exports = __onTabCompleteJSP; + + diff --git a/src/main/javascript/lib/tabcomplete.js b/src/main/javascript/lib/tabcomplete.js new file mode 100644 index 0000000..37e0bbc --- /dev/null +++ b/src/main/javascript/lib/tabcomplete.js @@ -0,0 +1,171 @@ +var tabCompleteJSP = require('tabcomplete-jsp'); +/* + Tab Completion of the /js and /jsp commands +*/ +var _isJavaObject = function(o){ + var result = false; + try { + o.hasOwnProperty("testForJava"); + }catch (e){ + // java will throw an error when an attempt is made to access the + // hasOwnProperty method. (it won't exist for Java objects) + result = true; + } + return result; +}; +var _javaLangObjectMethods = [ + 'equals' + ,'getClass' + ,'class' + ,'getClass' + ,'hashCode' + ,'notify' + ,'notifyAll' + ,'toString' + ,'wait' + ,'clone' + ,'finalize' +]; + +var _getProperties = function(o) +{ + var result = []; + if (_isJavaObject(o)) + { + propertyLoop: + for (var i in o) + { + // + // don't include standard Object methods + // + var isObjectMethod = false; + for (var j = 0;j < _javaLangObjectMethods.length; j++) + if (_javaLangObjectMethods[j] == i) + continue propertyLoop; + var typeofProperty = null; + try { + typeofProperty = typeof o[i]; + }catch( e ){ + if (e.message == 'java.lang.IllegalStateException: Entity not leashed'){ + // wph 20131020 fail silently for Entity leashing in craftbukkit + }else{ + throw e; + } + } + if (typeofProperty == 'function' ) + result.push(i+'()'); + else + result.push(i); + } + }else{ + if (o.constructor == Array) + return result; + + for (var i in o){ + if (i.match(/^[^_]/)){ + if (typeof o[i] == 'function') + result.push(i+'()'); + else + result.push(i); + } + } + } + return result.sort(); +}; + +var onTabCompleteJS = function() { + if (__onTC_cmd.name == 'jsp') + return tabCompleteJSP() + var _globalSymbols = _getProperties(global) + var result = global.__onTC_result; + var args = global.__onTC_args; + var lastArg = args.length?args[args.length-1]+'':null; + var propsOfLastArg = []; + var statement = args.join(' '); + + statement = statement.replace(/^\s+/,'').replace(/\s+$/,''); + + + if (statement.length == 0) + propsOfLastArg = _globalSymbols; + else{ + var statementSyms = statement.split(/[^\$a-zA-Z0-9_\.]/); + var lastSymbol = statementSyms[statementSyms.length-1]; + //print('DEBUG: lastSymbol=[' + lastSymbol + ']'); + // + // try to complete the object ala java IDEs. + // + var parts = lastSymbol.split(/\./); + var name = parts[0]; + var symbol = global[name]; + var lastGoodSymbol = symbol; + if (typeof symbol != 'undefined') + { + for (var i = 1; i < parts.length;i++){ + name = parts[i]; + symbol = symbol[name]; + if (typeof symbol == 'undefined') + break; + lastGoodSymbol = symbol; + } + //print('debug:name['+name+']lastSymbol['+lastSymbol+']symbol['+symbol+']'); + if (typeof symbol == 'undefined'){ + // + // look up partial matches against last good symbol + // + var objectProps = _getProperties(lastGoodSymbol); + if (name == ''){ + // if the last symbol looks like this.. + // ScriptCraft. + // + + for (var i =0;i < objectProps.length;i++){ + var candidate = lastSymbol + objectProps[i]; + var re = new RegExp(lastSymbol + '$','g'); + propsOfLastArg.push(lastArg.replace(re,candidate)); + } + + }else{ + // it looks like this.. + // ScriptCraft.co + // + //print('debug:case Y: ScriptCraft.co'); + + var li = statement.lastIndexOf(name); + for (var i = 0; i < objectProps.length;i++){ + if (objectProps[i].indexOf(name) == 0) + { + var candidate = lastSymbol.substring(0,lastSymbol.lastIndexOf(name)); + candidate = candidate + objectProps[i]; + var re = new RegExp(lastSymbol+ '$','g'); + //print('DEBUG: re=' + re + ',lastSymbol='+lastSymbol+',lastArg=' + lastArg + ',candidate=' + candidate); + propsOfLastArg.push(lastArg.replace(re,candidate)); + } + } + + } + }else{ + //print('debug:case Z:ScriptCraft'); + var objectProps = _getProperties(symbol); + for (var i = 0; i < objectProps.length; i++){ + var re = new RegExp(lastSymbol+ '$','g'); + propsOfLastArg.push(lastArg.replace(re,lastSymbol + '.' + objectProps[i])); + } + } + }else{ + //print('debug:case AB:ScriptCr'); + // loop thru globalSymbols looking for a good match + for (var i = 0;i < _globalSymbols.length; i++){ + if (_globalSymbols[i].indexOf(lastSymbol) == 0){ + var possibleCompletion = _globalSymbols[i]; + var re = new RegExp(lastSymbol+ '$','g'); + propsOfLastArg.push(lastArg.replace(re,possibleCompletion)); + } + } + + } + } + for (var i = 0;i < propsOfLastArg.length; i++) + result.add(propsOfLastArg[i]); +}; +module.exports = onTabCompleteJS; diff --git a/src/main/javascript/plugins/minigames/SnowBallFight.js b/src/main/javascript/plugins/minigames/SnowBallFight.js deleted file mode 100644 index 9a95c2e..0000000 --- a/src/main/javascript/plugins/minigames/SnowBallFight.js +++ /dev/null @@ -1,183 +0,0 @@ -/************************************************************************* -# SnowballFight mini-game - -## Description - -This is a rough and ready prototype of a simple multi-player -shoot-em-up. To start a game with all players playing against one another... - - /js new Game_SnowballFight(60).start(); - -... this obviously works best if all of the players are in close -proximity within the same game world. Alternatively you can have team -matches... - - - /js var redTeam = ['','',...etc] - /js var blueTeam = ['',',...etc] - /js var greenTeam = ['',',...etc] - /js new Game_SnowballFight(60, {red: redTeam,blue: blueTeam,green: greenTeam}).start(); - -Or you can just have specific players play against each other... - - /js new Game_SnowballFight(60, ['player1','player2','player3']).start(); - -(where 'player1' etc are the names of actual players) - -You specify the teams in the game as an object where each property's -name is a team name and each property's value is the list of players -on that team. You specify the duration of the game (in seconds) You -kick off the game with the start() method. I need to work on a -better in-game mechanism for players to choose teams and start the -game but this will do for now. - -When the game starts, each player is put in survival mode and given -snowballs. The aim of the game is to hit players on opposing teams. If -you hit a player on your own team, you lose a point. - -At the end of the game the scores for each team are broadcast and each -player returns to their previous mode of play (creative or -survival). Create a small arena with a couple of small buildings for -cover to make the game more fun. - -***/ - -var _startGame = function(gameState){ - // don't let game start if already in progress (wait for game to finish) - if (gameState.inProgress){ - return; - } - gameState.inProgress = true; - // reset timer - gameState.duration = gameState.originalDuration; - // put all players in survival mode and give them each 200 snowballs - // 64 snowballs for every 30 seconds should be more than enough - for (var i = 10;i < gameState.duration;i+=10) - gameState.ammo.push(gameState.ammo[0]); - - for (var teamName in gameState.teams) - { - gameState.teamScores[teamName] = 0; - var team = gameState.teams[teamName]; - for (var i = 0;i < team.length;i++) { - var player = server.getPlayer(team[i]); - gameState.savedModes[player.name] = player.gameMode; - player.gameMode = org.bukkit.GameMode.SURVIVAL; - player.inventory.addItem(gameState.ammo); - } - } -}; -/* - end the game -*/ -var _endGame = function(gameState){ - var scores = []; - - var leaderBoard = []; - for (var tn in gameState.teamScores){ - leaderBoard.push([tn,gameState.teamScores[tn]]); - } - leaderBoard.sort(function(a,b){ return b[1] - a[1];}); - - for (var i = 0;i < leaderBoard.length; i++){ - scores.push("Team " + leaderBoard[i][0] + " scored " + leaderBoard[i][1]); - } - - for (var teamName in gameState.teams) { - var team = gameState.teams[teamName]; - for (var i = 0;i < team.length;i++) { - // restore player's previous game mode and take back snowballs - var player = server.getPlayer(team[i]); - player.gameMode = gameState.savedModes[player.name]; - player.inventory.removeItem(gameState.ammo); - player.sendMessage("GAME OVER."); - player.sendMessage(scores); - } - } - var handlerList = org.bukkit.event.entity.EntityDamageByEntityEvent.getHandlerList(); - handlerList.unregister(gameState.listener); - gameState.inProgress = false; -}; -/* - get the team the player belongs to -*/ -var _getTeam = function(player,pteams) { - for (var teamName in pteams) { - var team = pteams[teamName]; - for (var i = 0;i < team.length; i++) - if (team[i] == player.name) - return teamName; - } - return null; -}; -/* - construct a new game -*/ -var createGame = function(duration, teams) { - - var _snowBalls = new org.bukkit.inventory.ItemStack(org.bukkit.Material.SNOW_BALL, 64); - - var _gameState = { - teams: teams, - duration: duration, - originalDuration: duration, - inProgress: false, - teamScores: {}, - listener: null, - savedModes: {}, - ammo: [_snowBalls] - }; - if (typeof duration == "undefined"){ - duration = 60; - } - if (typeof teams == "undefined"){ - /* - wph 20130511 use all players - */ - teams = []; - var players = server.onlinePlayers; - for (var i = 0;i < players.length; i++){ - teams.push(players[i].name); - } - } - // - // allow for teams param to be either {red:['player1','player2'],blue:['player3']} or - // ['player1','player2','player3'] if all players are against each other (no teams) - // - if (teams instanceof Array){ - _gameState.teams = {}; - for (var i = 0;i < teams.length; i++) - _gameState.teams[teams[i]] = [teams[i]]; - } - /* - this function is called every time a player is damaged by another entity/player - */ - var _onSnowballHit = function(l,event){ - var snowball = event.damager; - if (!snowball || !(snowball instanceof org.bukkit.entity.Snowball)) - return; - var throwersTeam = _getTeam(snowball.shooter,_gameState.teams); - var damageeTeam = _getTeam(event.entity,_gameState.teams); - if (!throwersTeam || !damageeTeam) - return; // thrower/damagee wasn't in game - if (throwersTeam != damageeTeam) - _gameState.teamScores[throwersTeam]++; - else - _gameState.teamScores[throwersTeam]--; - }; - - return { - start: function() { - _startGame(_gameState); - _gameState.listener = events.on('entity.EntityDamageByEntityEvent',_onSnowballHit); - new java.lang.Thread(function(){ - while (_gameState.duration--) - java.lang.Thread.sleep(1000); // sleep 1,000 millisecs (1 second) - _endGame(_gameState); - }).start(); - } - }; -}; -exports.Game_SnowballFight = createGame; - -