mirror of
https://github.com/danbulant/flying-squid
synced 2026-07-03 18:20:42 +00:00
Lots and lots and lots of changes... Plugins begin again!
This commit is contained in:
parent
808b5a0149
commit
cb88a5cbbb
15 changed files with 195 additions and 54 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -2,4 +2,6 @@ node_modules
|
||||||
dist/
|
dist/
|
||||||
modpePlugins/
|
modpePlugins/
|
||||||
config/settings.json
|
config/settings.json
|
||||||
logs/
|
logs/
|
||||||
|
src/plugins/*
|
||||||
|
!src/plugins/README.md
|
||||||
|
|
|
||||||
3
app.js
3
app.js
|
|
@ -21,7 +21,8 @@ var options = {
|
||||||
generation:settings.generation,
|
generation:settings.generation,
|
||||||
'modpe': settings.modpe,
|
'modpe': settings.modpe,
|
||||||
kickTimeout: settings.kickTimeout ? settings.kickTimeout : 10*1000,
|
kickTimeout: settings.kickTimeout ? settings.kickTimeout : 10*1000,
|
||||||
regionFolder: settings.regionFolder
|
regionFolder: settings.regionFolder,
|
||||||
|
plugins: settings.plugins
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports=mcServer.createMCServer(options);
|
module.exports=mcServer.createMCServer(options);
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,9 @@
|
||||||
"options":{
|
"options":{
|
||||||
"worldHeight":80
|
"worldHeight":80
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"plugins": {
|
||||||
|
|
||||||
},
|
},
|
||||||
"modpe": false
|
"modpe": false
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,5 +32,6 @@ class MCServer extends EventEmitter {
|
||||||
if(options.logging == true) this.createLog();
|
if(options.logging == true) this.createLog();
|
||||||
this._server.on('error', error => this.emit('error',error));
|
this._server.on('error', error => this.emit('error',error));
|
||||||
this._server.on('listening', () => this.emit('listening',this._server.socketServer.address().port));
|
this._server.on('listening', () => this.emit('listening',this._server.socketServer.address().port));
|
||||||
|
this.emit('asap');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,16 +1,21 @@
|
||||||
module.exports = (obj) => {
|
module.exports = (obj) => {
|
||||||
return (eventName, data, func, opt) => {
|
return async (eventName, data, func, opt) => {
|
||||||
var hiddenCancelled = false;
|
var hiddenCancelled = false;
|
||||||
var cancelled = 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
|
var cancel = (hidden) => { // Hidden shouldn't be used often but it's not hard to implement so meh
|
||||||
if (hidden) hiddenCancelled = true;
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -24,7 +24,7 @@ class Command {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
use(command) {
|
async use(command) {
|
||||||
var res = this.find(command);
|
var res = this.find(command);
|
||||||
|
|
||||||
if(res) {
|
if(res) {
|
||||||
|
|
@ -42,7 +42,7 @@ class Command {
|
||||||
res[1].shift();
|
res[1].shift();
|
||||||
}
|
}
|
||||||
|
|
||||||
res = res[0].params.action(res[1]);
|
res = await res[0].params.action(res[1]);
|
||||||
if(res) return '' + res;
|
if(res) return '' + res;
|
||||||
} else {
|
} else {
|
||||||
return 'Command not found';
|
return 'Command not found';
|
||||||
|
|
|
||||||
9
src/lib/plugins/behavior.js
Normal file
9
src/lib/plugins/behavior.js
Normal 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);
|
||||||
|
}
|
||||||
|
|
@ -75,7 +75,6 @@ module.exports.player=function(player) {
|
||||||
|
|
||||||
|
|
||||||
player.handleCommand = (str) => {
|
player.handleCommand = (str) => {
|
||||||
var res = player.commands.use(str);
|
player.commands.use(str);
|
||||||
if(res) player.chat('' + res);
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -6,18 +6,45 @@ module.exports.player=function(player,serv)
|
||||||
var pos=new Vec3(location.x,location.y,location.z);
|
var pos=new Vec3(location.x,location.y,location.z);
|
||||||
player.world.getBlock(pos)
|
player.world.getBlock(pos)
|
||||||
.then(block => {
|
.then(block => {
|
||||||
currentlyDugBlock=block;
|
player.behavior('digPacket', {
|
||||||
if(currentlyDugBlock.type==0) return;
|
position: pos,
|
||||||
if(status==0 && player.gameMode!=1)
|
status: status,
|
||||||
startDigging(pos);
|
block: block
|
||||||
else if(status==2)
|
}, ({position,status,block}) => {
|
||||||
completeDigging(pos);
|
currentlyDugBlock=block;
|
||||||
else if(status==1)
|
if(currentlyDugBlock.type==0) return;
|
||||||
cancelDigging(pos);
|
if(status==0 && player.gameMode!=1)
|
||||||
else if(status==0 && player.gameMode==1)
|
player.behavior('dig', { // Start dig survival
|
||||||
creativeDigging(pos);
|
position: position,
|
||||||
})
|
block: block
|
||||||
.catch((err)=> setTimeout(() => {throw err;},0));
|
}, ({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)
|
function diggingTime(location)
|
||||||
|
|
|
||||||
62
src/lib/plugins/external.js
Normal file
62
src/lib/plugins/external.js
Normal 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);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
@ -12,15 +12,16 @@ module.exports.server=function(serv,options)
|
||||||
client.on('error',error => serv.emit('clientError',client,error)));
|
client.on('error',error => serv.emit('clientError',client,error)));
|
||||||
|
|
||||||
serv._server.on('login', async (client) => {
|
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 {
|
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();
|
await player.login();
|
||||||
}
|
}
|
||||||
catch(err){
|
catch(err){
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,12 @@
|
||||||
var Vec3 = require("vec3").Vec3;
|
var Vec3 = require("vec3").Vec3;
|
||||||
|
|
||||||
module.exports.server=function(serv) {
|
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({
|
var players = (typeof whitelist != 'undefined' ? (typeof whitelist == 'array' ? whitelist : [whitelist]) : serv.getNearby({
|
||||||
world: world,
|
world: world,
|
||||||
position: position.scaled(32).floored(),
|
position: position.scaled(32).floored(),
|
||||||
radius: radius // 32 blocks, fixed position
|
radius: radius // 32 blocks, fixed position
|
||||||
}));
|
}));
|
||||||
if (!size) size = new Vec3(1.0, 1.0, 1.0);
|
|
||||||
|
|
||||||
serv._writeArray('world_particles', {
|
serv._writeArray('world_particles', {
|
||||||
particleId: particle,
|
particleId: particle,
|
||||||
|
|
|
||||||
|
|
@ -18,26 +18,35 @@ module.exports.player=function(player,serv)
|
||||||
var referencePosition=new Vec3(location.x,location.y,location.z);
|
var referencePosition=new Vec3(location.x,location.y,location.z);
|
||||||
var directionVector=directionToVector[direction];
|
var directionVector=directionToVector[direction];
|
||||||
var placedPosition=referencePosition.plus(directionVector);
|
var placedPosition=referencePosition.plus(directionVector);
|
||||||
player.world.getBlockType(referencePosition).then((id) => {
|
player.behavior('placeBlock', {
|
||||||
if([25].indexOf(id) != -1) return;
|
direction: directionVector,
|
||||||
var sound = 'dig.' + (materialToSound[blocks[heldItem.blockId].material] || 'stone');
|
heldItem: heldItem,
|
||||||
serv.playSound(sound, player.world, placedPosition.clone().add(new Vec3(0.5, 0.5, 0.5)), {
|
id: heldItem.blockId,
|
||||||
pitch: 0.8
|
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){
|
if(heldItem.blockId!=323){
|
||||||
player.changeBlock(placedPosition,heldItem.blockId,heldItem.itemDamage);
|
player.changeBlock(position,heldItem.blockId,heldItem.itemDamage);
|
||||||
}else if(direction==1){
|
}else if(direction==1){
|
||||||
player.setBlock(placedPosition, 63, 0);
|
player.setBlock(position, 63, 0);
|
||||||
player._client.write('open_sign_entity', {
|
player._client.write('open_sign_entity', {
|
||||||
location:placedPosition
|
location:position
|
||||||
});
|
});
|
||||||
}else{
|
}else{
|
||||||
player.setBlock(placedPosition, 68, 0);
|
player.setBlock(position, 68, 0);
|
||||||
player._client.write('open_sign_entity', {
|
player._client.write('open_sign_entity', {
|
||||||
location:placedPosition
|
location:position
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}).catch((err)=> setTimeout(() => {throw err;},0));
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,12 +21,14 @@ module.exports.server=function(serv) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
serv.playNoteBlock = (world, position, pitch) => {
|
serv.playNoteBlock = (pitch, world, position, {instrument='harp', particle=true}={}) => {
|
||||||
serv.emitParticle(23, world, position.clone().add(new Vec3(0.5, 1.5, 0.5)), {
|
if (particle) {
|
||||||
count: 1,
|
serv.emitParticle(23, world, position.clone().add(new Vec3(0.5, 1.5, 0.5)), {
|
||||||
size: new Vec3(0, 0, 0)
|
count: 1,
|
||||||
});
|
size: new Vec3(0, 0, 0)
|
||||||
serv.playSound('note.harp', world, position, { pitch: serv.getNote(pitch) });
|
});
|
||||||
|
}
|
||||||
|
serv.playSound('note.' + instrument, world, position, { pitch: serv.getNote(pitch) });
|
||||||
};
|
};
|
||||||
|
|
||||||
serv.getNote = note => 0.5 * Math.pow(Math.pow(2, 1/12), note);
|
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;
|
if (typeof data.note == 'undefined') data.note = -1;
|
||||||
data.note++;
|
data.note++;
|
||||||
data.note %= 25;
|
data.note %= 25;
|
||||||
serv.playNoteBlock(player.world, pos, data.note);
|
serv.playNoteBlock(data.note, player.world, pos);
|
||||||
}).catch((err)=> setTimeout(() => {throw err;},0));
|
}).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()] = {};
|
if (!player.world.blockEntityData[pos.toString()]) player.world.blockEntityData[pos.toString()] = {};
|
||||||
var data = player.world.blockEntityData[pos.toString()];
|
var data = player.world.blockEntityData[pos.toString()];
|
||||||
if (typeof data.note == 'undefined') data.note = 0;
|
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));
|
}).catch((err)=> setTimeout(() => {throw err;},0));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
21
src/plugins/README.md
Normal file
21
src/plugins/README.md
Normal 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.
|
||||||
Loading…
Reference in a new issue