From 6771c3186b721371e20aaa02e7af695420bdb063 Mon Sep 17 00:00:00 2001 From: DemiPixel Date: Mon, 7 Sep 2015 15:06:23 -0700 Subject: [PATCH] Added many more cancelable events and more documentation! --- doc/api.md | 101 ++++++++++++++++++++++++++++++-- doc/contribute.md | 25 ++++++++ lib/playerPlugins/animations.js | 3 + lib/playerPlugins/chat.js | 16 ++++- lib/playerPlugins/digging.js | 33 +++++++++++ lib/playerPlugins/placeBlock.js | 2 +- lib/playerPlugins/pvp.js | 10 +++- 7 files changed, 182 insertions(+), 8 deletions(-) diff --git a/doc/api.md b/doc/api.md index 28e021c..7128894 100644 --- a/doc/api.md +++ b/doc/api.md @@ -39,8 +39,17 @@ - ["spawned"](#spawned) - ["disconnected"](#disconnected) - ["error" (error)](#error-error-1) - - ["chat" (message)](#chat-message) - ["kicked" (kicker,reason)](#kicked-kickerreason) + - [Cancelable Events](#cancelable-events) + - ["chatMessage"](#chatmessage) + - ["chat"](#chat) + - ["command"](#command) + - ["startDig"](#startdig) + - ["stopDig"](#stopdig) + - ["finishDig"](#finishdig) + - ["placeBlock"](#placeblock) + - ["attackPlayer"](#attackplayer) + - ["animation_arm"](#animation_arm) - [Methods](#methods-1) - [player.login()](#playerlogin) - [player.ban(reason)](#playerbanreason) @@ -202,14 +211,96 @@ Fires when the player disconnected Fires when there is an error. -#### "chat" (message) - -Fires when the player says `message`. - #### "kicked" (kicker,reason) `kicker` kick the player with `reason` +### Cancelable Events + +This type of event is emitted by the the player with the option to cancel a default. It is primarily used by external plugins. +This type of event is emitted twice. For example, if a player digs a block, both digBlock\_cancel and digBlock are emitted. +digBlock\_cancel has the ability to cancel the default action. digBlock allows plugins to check if the default has been cancelled before it runs. An example with finishDig: + +```js +player.on("finishDig_cancel", function(event, cancel) { + if (event.block.id == 1) { // If player mined stone (id == 1) + cancel(); // Do not break the block in the world, do not send block change to others + } +}); +``` + +```js +player.on("finishDig", function(event, cancelled) { + if (!cancelled) { // Make sure another plugin has not cancelled the default response + if (event.block.id == 1) player.chat("You broke stone!"); + } +}); +``` + +For these, the cancel event is always originalName_cancel with arguments (event, cancel) + +The "check cancel" event is always originalName with arguments (event, cancelled) + +#### "chatMessage" + +Fires when a user sends any message to the server (even a command) + +- message: String sent by player + +#### "chat" + +Fires when a user sends a message that does not start with a `/` (i.e. not a command). + +- message: String sent by the player + +#### "command" + +Fires when a user starts a message with a `/`. + +- message: String sent by player but without the `/` + +#### "startDig" + +Fires when a player begins to break a blog (even in creative) + +- position: Position block is being mined in the world +- block: Block at that position in world + +#### "stopDig" + +Fires when a player choses to stop breaking a block + +- position: Position block is being mined in the world +- block: Block at that position in world + +#### "finishDig" + +Fires when a player has finished mining a block. If the player is in creative, this will be called immediately after `startDig`. + +- time: Time it took to mine block (0 if player is in creative) +- position: Position block is being mined in the world +- block: Block at that position in world + +#### "placeBlock" + +Fires when a user places a block + +- reference: Position that the player right-clicked on to place the block +- position: Position the user wishes to place the block +- id: Id of the block they are placing + +`position` and `id` will soon be replaced by `block` which will contain a Block object. + +#### "attackPlayer" + +Fires when one player attacks another + +- attacked: Player who was attacked + +#### "animation_arm" + +Fires when a player wants to "punch" (including anything they're holding). + ### Methods #### player.login() diff --git a/doc/contribute.md b/doc/contribute.md index aad5066..724d3b8 100644 --- a/doc/contribute.md +++ b/doc/contribute.md @@ -43,6 +43,31 @@ in log.js of playerPlugins or serverPlugins. ## Creating external plugins +When you're making an external plugin, create a repo and publish to NPM your code so others can use it. + +However, if you simply want to fool around, create a folder, use `npm init`, and drag it into the "plugins" folder. + +Your file's base should look like this: + +```js +module.exports = inject; + +function inject(serv, player, self, opt) { + +} +``` + +- serv is the Server object. Use this to broadcast messages, set blocks, etc +- player is a Player object. You can make changes to the player or check for events from them. +- self is your plugin. You may need your plugin id, so you'll use `self.id`. +- opt is any options the server has while running. + +Since the plugin is its own node module, you can install any other modules inside of it! + +Checks the API.md for information about what events you can check for on the server or player! + +## Creating external plugins OLD + Create a new repo, which will be published to npm when ready to be used. Create a file in which you put an inject function like this : diff --git a/lib/playerPlugins/animations.js b/lib/playerPlugins/animations.js index a556fc9..f1dced0 100644 --- a/lib/playerPlugins/animations.js +++ b/lib/playerPlugins/animations.js @@ -3,6 +3,9 @@ module.exports=inject; function inject(serv, player) { player._client.on("arm_animation", function(packet) { + var doDefault = cancelEmit(player, "animation_arm", {}); + if (!doDefault) return; + player._writeOthers("animation", { entityId: player.entity.id, animation: 0 diff --git a/lib/playerPlugins/chat.js b/lib/playerPlugins/chat.js index df89d7d..0cf0f1c 100644 --- a/lib/playerPlugins/chat.js +++ b/lib/playerPlugins/chat.js @@ -3,13 +3,27 @@ module.exports=inject; function inject(serv, player) { player._client.on('chat', function (packet) { + var doDefault = cancelEmit(player, "chatMessage", { + message: packet.message + }); + if (!doDefault) return; + if(packet.message[0]=="/") { + var doDefault = cancelEmit(player, "command", { + message: packet.message.slice(1) + }); + if (!doDefault) return; + var command = packet.message.slice(1); player.handleCommand(command); } else { + var doDefault = cancelEmit(player, "chat", { + message: packet.message + }); + if (!doDefault) return; + serv.broadcast('<' + player.username + '>' + ' ' + packet.message); - player.emit("chat",packet.message); } }); diff --git a/lib/playerPlugins/digging.js b/lib/playerPlugins/digging.js index ff8c63e..ce989c5 100644 --- a/lib/playerPlugins/digging.js +++ b/lib/playerPlugins/digging.js @@ -1,4 +1,5 @@ var Vec3 = require("vec3"); +var cancelEmit = require("../cancelEvent"); module.exports=inject; @@ -6,6 +7,13 @@ function inject(serv,player) { player._client.on("block_dig",function(packet){ var pos=new Vec3(packet.location); + + var doDefault = cancelEmit(player, "startDig", { + position: pos, + block: serv.world.getBlock(pos) + }); + if (!doDefault) return; + currentlyDugBlock=serv.world.getBlock(pos); if(currentlyDugBlock.type==0) return; if(packet.status==0 && player.gameMode!=1) @@ -46,6 +54,13 @@ function inject(serv,player) newDestroyState=newDestroyState>9 ? 9 : newDestroyState; if(newDestroyState!=lastDestroyState) { + var doDefault = cancelEmit(player, "breakAnimation", { + lastState: lastDestroyState, + position: location, + block: currentlyDugBlock + }); + if (!doDefault) return; + lastDestroyState=newDestroyState; player._writeOthers("block_break_animation",{ "entityId":currentAnimationId, @@ -59,6 +74,13 @@ function inject(serv,player) function cancelDigging(location) { clearInterval(animationInterval); + + var doDefault = cancelEmit(player, "stopDig", { + position: pos, + block: serv.world.getBlock(pos) + }); + if (!doDefault) return; + player._writeOthers("block_break_animation",{ "entityId":currentAnimationId, "location":location, @@ -71,6 +93,12 @@ function inject(serv,player) clearInterval(animationInterval); var diggingTime=new Date()-startDiggingTime; if(expectedDiggingTime-diggingTime<100) + var doDefault = cancelEmit(player, "finishDig", { + time: diggingTime, + position: pos, + block: serv.world.getBlock(pos) + }); + if (!doDefault) return; player.changeBlock(location,0); else { @@ -84,6 +112,11 @@ function inject(serv,player) function creativeDigging(location) { + var doDefault = cancelEmit(player, "finishDig", { + time: 0, + position: pos, + block: serv.world.getBlock(pos) + }); player.changeBlock(location,0); } diff --git a/lib/playerPlugins/placeBlock.js b/lib/playerPlugins/placeBlock.js index 60c8a56..a2b452a 100644 --- a/lib/playerPlugins/placeBlock.js +++ b/lib/playerPlugins/placeBlock.js @@ -11,7 +11,7 @@ function inject(serv,player) var directionVector=directionToVector[packet.direction]; var placedPosition=referencePosition.plus(directionVector); - var doDefault = cancelEmit(player, "blockPlace", { + var doDefault = cancelEmit(player, "placeBlock", { // TODO, make block object and send it (instead of ID) reference: referencePosition, position: placedPosition, id: packet.heldItem.blockId diff --git a/lib/playerPlugins/pvp.js b/lib/playerPlugins/pvp.js index d179865..d72423d 100644 --- a/lib/playerPlugins/pvp.js +++ b/lib/playerPlugins/pvp.js @@ -1,3 +1,5 @@ +var cancelEmit = require("../cancelEvent"); + module.exports=inject; function inject(serv, player) @@ -15,6 +17,12 @@ function inject(serv, player) function attackEntity(entityId) { var attackedPlayer = serv.entities[entityId].player; + + var doDefault = cancelEmit(player, "attackPlayer", { + attacked: attackedPlayer + }); + if (!doDefault) return; + if(attackedPlayer.gameMode!=0) return; attackedPlayer.updateHealth(attackedPlayer.entity.health - 1); @@ -32,7 +40,7 @@ function inject(serv, player) player._client.on("use_entity", function(packet) { if(packet.mouse == 1) { - attackEntity(packet.target); + if (packet.target.player) attackEntity(packet.target); } });