Lots and lots and lots of changes... Plugins begin again!

This commit is contained in:
DemiPixel 2015-11-21 14:30:16 -08:00
parent 808b5a0149
commit cb88a5cbbb
15 changed files with 195 additions and 54 deletions

4
.gitignore vendored
View file

@ -2,4 +2,6 @@ node_modules
dist/
modpePlugins/
config/settings.json
logs/
logs/
src/plugins/*
!src/plugins/README.md

3
app.js
View file

@ -21,7 +21,8 @@ var options = {
generation:settings.generation,
'modpe': settings.modpe,
kickTimeout: settings.kickTimeout ? settings.kickTimeout : 10*1000,
regionFolder: settings.regionFolder
regionFolder: settings.regionFolder,
plugins: settings.plugins
};
module.exports=mcServer.createMCServer(options);

View file

@ -10,6 +10,9 @@
"options":{
"worldHeight":80
}
},
"plugins": {
},
"modpe": false
}

View file

@ -32,5 +32,6 @@ class MCServer extends EventEmitter {
if(options.logging == true) this.createLog();
this._server.on('error', error => this.emit('error',error));
this._server.on('listening', () => this.emit('listening',this._server.socketServer.address().port));
this.emit('asap');
}
}

View file

@ -1,16 +1,21 @@
module.exports = (obj) => {
return (eventName, data, func, opt) => {
return async (eventName, data, func, opt) => {
var hiddenCancelled = false;
var cancelled = false;
var cancelCount = 0;
var cancel = (hidden) => { // Hidden shouldn't be used often but it's not hard to implement so meh
if (hidden) hiddenCancelled = true;
else cancelled = true;
else {
cancelled = true;
cancelCount++;
}
}
obj.emit(eventName + '_cancel', data, cancel);
obj.emit(eventName, data, cancelled);
await obj.emit(eventName + '_cancel', data, cancel);
await obj.emit(eventName, data, cancelled, cancelCount);
if (!hiddenCancelled && !cancelled) func(data);
if (!hiddenCancelled && !cancelled) await func(data);
obj.emit(eventName + '_done', data, cancelled);
await obj.emit(eventName + '_done', data, cancelled);
}
}

View file

@ -24,7 +24,7 @@ class Command {
return res;
}
use(command) {
async use(command) {
var res = this.find(command);
if(res) {
@ -42,7 +42,7 @@ class Command {
res[1].shift();
}
res = res[0].params.action(res[1]);
res = await res[0].params.action(res[1]);
if(res) return '' + res;
} else {
return 'Command not found';

View file

@ -0,0 +1,9 @@
var Behavior = require('../behavior');
module.exports.server = function(serv) {
serv.behavior = new Behavior(serv);
}
module.exports.entity = function(entity, serv) {
entity.behavior = new Behavior(entity);
}

View file

@ -75,7 +75,6 @@ module.exports.player=function(player) {
player.handleCommand = (str) => {
var res = player.commands.use(str);
if(res) player.chat('' + res);
player.commands.use(str);
};
};

View file

@ -6,18 +6,45 @@ module.exports.player=function(player,serv)
var pos=new Vec3(location.x,location.y,location.z);
player.world.getBlock(pos)
.then(block => {
currentlyDugBlock=block;
if(currentlyDugBlock.type==0) return;
if(status==0 && player.gameMode!=1)
startDigging(pos);
else if(status==2)
completeDigging(pos);
else if(status==1)
cancelDigging(pos);
else if(status==0 && player.gameMode==1)
creativeDigging(pos);
})
.catch((err)=> setTimeout(() => {throw err;},0));
player.behavior('digPacket', {
position: pos,
status: status,
block: block
}, ({position,status,block}) => {
currentlyDugBlock=block;
if(currentlyDugBlock.type==0) return;
if(status==0 && player.gameMode!=1)
player.behavior('dig', { // Start dig survival
position: position,
block: block
}, ({position}) => {
return startDigging(position);
});
else if(status==2)
player.behavior('finishDig', { // Finish dig survival
position: position,
block: block
}, ({position}) => {
return completeDigging(position);
});
else if(status==1)
player.behavior('cancelDig', { // Cancel dig survival
position: position,
block: block
}, ({position}) => {
return cancelDigging(position);
});
else if(status==0 && player.gameMode==1)
player.behavior('dig', { // Start/finish dig creative
position: position,
block: block
}, ({position}) => {
return creativeDigging(position);
});
}
)}
)
.catch((err)=> setTimeout(() => {throw err;},0))
});
function diggingTime(location)

View file

@ -0,0 +1,62 @@
module.exports.server = function(serv, settings) {
serv.plugins = {};
serv.pluginCount = 0;
serv.externalPluginsLoaded = false;
serv.addPlugin = (name, plugin, set) => {
if (!name || !plugin) throw new Error('You need a name and object for your plugin!');
serv.plugins[name] = {
id: serv.pluginCount,
name: name,
player: plugin.player,
entity: plugin.entity,
server: plugin.server,
settings: set,
enabled: true
};
serv.pluginCount++;
if (serv.externalPluginsLoaded && plugin.server) serv.plugins[name].server.call(p, serv, settings);
}
for (var p in settings.plugins) {
try {
serv.addPlugin(p, require(p), settings.plugins[p]);
} catch (err) {
try {
serv.addPlugin(p, require('../../plugins/' + p), settings.plugins[p]);
} catch (err) {
throw new Error('Cannot find plugin "' + p + '"');
}
}
}
for (var p in serv.plugins) {
if (serv.plugins[p].server) serv.plugins[p].server.call(serv.plugins[p], serv, settings);
}
serv.externalPluginsLoaded = true;
};
module.exports.player = function(player, serv) {
Object.keys(serv.plugins).forEach(p => {
var plugin = serv.plugins[p];
if (plugin.player) plugin.player.call(plugin, player, serv);
});
};
module.exports.entity = function(entity, serv) {
entity.pluginData = {};
Object.keys(serv.plugins).forEach(p => {
entity.pluginData[p] = {};
});
entity.getData = (pluginName) => {
if (typeof pluginName == 'object') pluginName = pluginName.name;
return entity.pluginData[pluginName] || null;
}
Object.keys(serv.plugins).forEach(p => {
var plugin = serv.plugins[p];
if (plugin.entity) plugin.entity.call(plugin, entity, serv);
});
}

View file

@ -12,15 +12,16 @@ module.exports.server=function(serv,options)
client.on('error',error => serv.emit('clientError',client,error)));
serv._server.on('login', async (client) => {
var player = serv.initEntity('player', null, serv.overworld, new Vec3(0,0,0));
player._client=client;
player.commands = new Command({});
Object.keys(plugins)
.filter(pluginName => plugins[pluginName].player!=undefined)
.forEach(pluginName => plugins[pluginName].player(player, serv, options));
serv.emit("newPlayer",player);
try {
var player = serv.initEntity('player', null, serv.overworld, new Vec3(0,0,0));
player._client=client;
player.commands = new Command({});
Object.keys(plugins)
.filter(pluginName => plugins[pluginName].player!=undefined)
.forEach(pluginName => plugins[pluginName].player(player, serv, options));
serv.emit("newPlayer",player);
player.emit('asap');
await player.login();
}
catch(err){

View file

@ -1,13 +1,12 @@
var Vec3 = require("vec3").Vec3;
module.exports.server=function(serv) {
serv.emitParticle = (particle, world, position, {whitelist,blacklist=[],radius=32*32,longDistance=true,size,count=1}={}) => {
serv.emitParticle = (particle, world, position, {whitelist,blacklist=[],radius=32*32,longDistance=true,size=new Vec3(1, 1, 1),count=1}={}) => {
var players = (typeof whitelist != 'undefined' ? (typeof whitelist == 'array' ? whitelist : [whitelist]) : serv.getNearby({
world: world,
position: position.scaled(32).floored(),
radius: radius // 32 blocks, fixed position
}));
if (!size) size = new Vec3(1.0, 1.0, 1.0);
serv._writeArray('world_particles', {
particleId: particle,

View file

@ -18,26 +18,35 @@ module.exports.player=function(player,serv)
var referencePosition=new Vec3(location.x,location.y,location.z);
var directionVector=directionToVector[direction];
var placedPosition=referencePosition.plus(directionVector);
player.world.getBlockType(referencePosition).then((id) => {
if([25].indexOf(id) != -1) return;
var sound = 'dig.' + (materialToSound[blocks[heldItem.blockId].material] || 'stone');
serv.playSound(sound, player.world, placedPosition.clone().add(new Vec3(0.5, 0.5, 0.5)), {
pitch: 0.8
});
player.behavior('placeBlock', {
direction: directionVector,
heldItem: heldItem,
id: heldItem.blockId,
damage: heldItem.itemDamage,
position: placedPosition,
reference: referencePosition,
playSound: true,
sound: 'dig.' + (materialToSound[blocks[heldItem.blockId].material] || 'stone')
}, ({direction, heldItem, position, reference, playSound, sound}) => {
if (playSound) {
serv.playSound(sound, player.world, placedPosition.clone().add(new Vec3(0.5, 0.5, 0.5)), {
pitch: 0.8
});
}
if(heldItem.blockId!=323){
player.changeBlock(placedPosition,heldItem.blockId,heldItem.itemDamage);
player.changeBlock(position,heldItem.blockId,heldItem.itemDamage);
}else if(direction==1){
player.setBlock(placedPosition, 63, 0);
player.setBlock(position, 63, 0);
player._client.write('open_sign_entity', {
location:placedPosition
location:position
});
}else{
player.setBlock(placedPosition, 68, 0);
player.setBlock(position, 68, 0);
player._client.write('open_sign_entity', {
location:placedPosition
location:position
});
}
}).catch((err)=> setTimeout(() => {throw err;},0));
});
});
};

View file

@ -21,12 +21,14 @@ module.exports.server=function(serv) {
});
};
serv.playNoteBlock = (world, position, pitch) => {
serv.emitParticle(23, world, position.clone().add(new Vec3(0.5, 1.5, 0.5)), {
count: 1,
size: new Vec3(0, 0, 0)
});
serv.playSound('note.harp', world, position, { pitch: serv.getNote(pitch) });
serv.playNoteBlock = (pitch, world, position, {instrument='harp', particle=true}={}) => {
if (particle) {
serv.emitParticle(23, world, position.clone().add(new Vec3(0.5, 1.5, 0.5)), {
count: 1,
size: new Vec3(0, 0, 0)
});
}
serv.playSound('note.' + instrument, world, position, { pitch: serv.getNote(pitch) });
};
serv.getNote = note => 0.5 * Math.pow(Math.pow(2, 1/12), note);
@ -48,7 +50,7 @@ module.exports.player=function(player,serv) {
if (typeof data.note == 'undefined') data.note = -1;
data.note++;
data.note %= 25;
serv.playNoteBlock(player.world, pos, data.note);
serv.playNoteBlock(data.note, player.world, pos);
}).catch((err)=> setTimeout(() => {throw err;},0));
});
@ -60,7 +62,7 @@ module.exports.player=function(player,serv) {
if (!player.world.blockEntityData[pos.toString()]) player.world.blockEntityData[pos.toString()] = {};
var data = player.world.blockEntityData[pos.toString()];
if (typeof data.note == 'undefined') data.note = 0;
serv.playNoteBlock(player.world, pos, data.note);
serv.playNoteBlock(data.not,player.world, pos, data.note);
}).catch((err)=> setTimeout(() => {throw err;},0));
});

21
src/plugins/README.md Normal file
View file

@ -0,0 +1,21 @@
## Usage
Drag plugins in this folder.
## Creating Plugin
1) Create folder.
2) Create your index.js inside the folder.
3) `cd` to the folder and type `npm init` and follow instructions.
4) index.js should return in module.exports. player, server, or entity. All are optional.
5.1) If you don't have config/settings.json, create it and copy everything from config/default-settings.json inside.
5.2) Add into plugins `"plugin_name": {}`. Add any options you'd like.
## Publish plugin
Use `npm publish` and follow instructions.