mirror of
https://github.com/danbulant/flying-squid
synced 2026-06-14 12:01:12 +00:00
Merge pull request #154 from demipixel/inCompSciRightNow
wats ur fav type of icecream
This commit is contained in:
commit
b679dd6325
14 changed files with 190 additions and 205 deletions
|
|
@ -5,93 +5,67 @@
|
|||
Directory architecture :
|
||||
|
||||
* app.js: specific settings and actually start the server
|
||||
* index.js: contain the generic server implementation
|
||||
* lib/: contain the classes and functions used in the plugins
|
||||
* serverPlugins/: server plugins that do things general to the server,
|
||||
properties and method are added to the server object in them
|
||||
* playerPlugins/: player plugins that do things for each player, properties and method are added to the player object in them
|
||||
* dist/: Contains "compiled" code (go to current directory in console and type `gulp` to generate this)
|
||||
* src/: Source files for the project
|
||||
* src/index.js: contain the generic server implementation
|
||||
* src/lib: contain the classes and functions used in the plugins
|
||||
* plugins/: All of the default plugins made to simulate vanilla
|
||||
* worldGeneraions/: Contains default world generations, however plugins can use their own
|
||||
|
||||
Structure of a server plugin:
|
||||
## Structure of a plugin
|
||||
|
||||
```js
|
||||
module.exports=inject;
|
||||
|
||||
function inject(serv)
|
||||
{
|
||||
// add methods and properties to serv
|
||||
// Each of these are called an "inject" because you're injecting properties, events, methods, or data into the objects
|
||||
|
||||
module.exports.server = function(serv) { // Create your server events here
|
||||
serv.spawnPoint = ...;
|
||||
serv.on('...', ...);
|
||||
}
|
||||
```
|
||||
|
||||
Structure of a player plugin :
|
||||
|
||||
```js
|
||||
module.exports=inject;
|
||||
|
||||
function inject(serv,player)
|
||||
{
|
||||
// add methods and properties to player
|
||||
// you can use serv, but you shouldn't add things to it here
|
||||
module.exports.entity = function(entity, serv) { // Called whenever an entity is created, do NOT do serv.on here
|
||||
entity.health = 10; // Start with 10 health out of 20
|
||||
entity.on('...', ...);
|
||||
// serv.on('...', ...); NOOOO
|
||||
}
|
||||
|
||||
module.exports.player = function(player, serv) { // Player is a type of entity (entity inject is called first) with added properties and functions
|
||||
player.setXp(100); // Example of a property player entities have but not other entities
|
||||
player.on(',,,', ...);
|
||||
// serv.on('...', .– don't even think about it
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Logs and event
|
||||
|
||||
In order to keep logging independent from the rest of the server and to let people react in other ways than logging,
|
||||
server and player events should be emitting and the logging should only take place in response to these events
|
||||
in log.js of playerPlugins or serverPlugins.
|
||||
logging uses methods and events from `log.js`. These include `serv.log(message)` and `serv.emit('error', err)`.
|
||||
|
||||
## Creating external plugins
|
||||
|
||||
Create a new repo, which will be published to npm when ready to be used.
|
||||
Create a new repo, which will be published to npm when ready to be used. Create a file (probably `index.js`) in which you use a similar format as above (module.exports.xxxx).
|
||||
|
||||
Create a file in which you put an inject function like this :
|
||||
In these inject functions you can use everything documented in the [api.md](api.md).
|
||||
|
||||
```js
|
||||
module.exports=init;
|
||||
Let's say you called your module fs-flying-horses and you published it to npm.
|
||||
|
||||
function init(flying-squid) {
|
||||
return inject;
|
||||
}
|
||||
Now people can use install your plugin by simply typing:
|
||||
|
||||
function inject(serv)
|
||||
{
|
||||
// add methods and properties to serv
|
||||
}
|
||||
```
|
||||
```npm install fs-flying-horses```
|
||||
|
||||
In the init function, you can use anything flying-squid provide
|
||||
(see [index.js](https://github.com/mhsjlw/flying-squid/blob/master/index.js#L11)).
|
||||
### Testing your Plugin
|
||||
|
||||
In the inject function you can use everything documented in the [api.md](api.md) to add functionalities to the serv object.
|
||||
For your convenience, you can put your plugin inside /src/plugins. An example might look like:
|
||||
- src/plugins/
|
||||
- myPluginName/
|
||||
- index.js
|
||||
- package.json
|
||||
- node_modules
|
||||
- ...
|
||||
- myPluginName2.js (direct files are allowed but are impossible to publish, so it's best only to use them for testing)
|
||||
|
||||
Let's say you called your module flying-horses and you published it to npm.
|
||||
|
||||
Now people can use your plugin that way :
|
||||
|
||||
```js
|
||||
var flyingSquid = require('flying-squid');
|
||||
var flyingHorses = require('flying-horses')(flyingSquid);
|
||||
var serv = flyingSquid.createMCServer(/* your options there */);
|
||||
// install the plugin
|
||||
flyingHorses(serv);
|
||||
```
|
||||
|
||||
As explained in the first part of this file, flying-squid has 2 kinds of plugins: server plugins, and player plugins.
|
||||
We've explained until now how to create a server plugin and to use it with flying-squid.
|
||||
|
||||
Within the same module, you can also create a player plugin. Here is the code you need to add to do that:
|
||||
|
||||
```js
|
||||
serv.on("newPlayer",function(player){
|
||||
injectPlayer(serv,player);
|
||||
});
|
||||
|
||||
function injectPlayer(serv,player)
|
||||
{
|
||||
// add methods and properties to player
|
||||
// you can use serv, but you shouldn't add things to it here
|
||||
}
|
||||
```
|
||||
## Conclusion
|
||||
|
||||
In this document, we explained how to create a simple plugin with just one file, but you can cut your code
|
||||
in several files by having several inject function and putting them in different files, just like flying-squid does for its internal plugins.
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@ module.exports = {
|
|||
Command:require("./lib/command"),
|
||||
version:require("./lib/version"),
|
||||
generations:require("./lib/generations"),
|
||||
experience:require("./lib/experience")
|
||||
experience:require("./lib/experience"),
|
||||
UserError:require("./lib/UserError")
|
||||
};
|
||||
|
||||
function createMCServer(options) {
|
||||
|
|
@ -39,5 +40,7 @@ class MCServer extends EventEmitter {
|
|||
this._server.on('error', error => this.emit('error',error));
|
||||
this._server.on('listening', () => this.emit('listening',this._server.socketServer.address().port));
|
||||
this.emit('asap');
|
||||
|
||||
process.on('unhandledRejection', err => this.emit('error',err));
|
||||
}
|
||||
}
|
||||
5
src/lib/UserError.js
Normal file
5
src/lib/UserError.js
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
class UserError extends Error {
|
||||
|
||||
}
|
||||
|
||||
module.exports = UserError;
|
||||
|
|
@ -13,13 +13,22 @@ module.exports = (obj) => {
|
|||
defaultCancel = dC;
|
||||
};
|
||||
|
||||
var resp;
|
||||
|
||||
await obj.emitThen(eventName + '_cancel', data, cancel).catch((err)=> setTimeout(() => {throw err;},0));
|
||||
await obj.emitThen(eventName, data, cancelled, cancelCount).catch((err)=> setTimeout(() => {throw err;},0));
|
||||
|
||||
if (!hiddenCancelled && !cancelled) await func(data).catch((err)=> setTimeout(() => {throw err;},0));
|
||||
else if (cancelFunc && defaultCancel) await cancelFunc(data).catch((err)=> setTimeout(() => {throw err;},0));
|
||||
|
||||
if (!hiddenCancelled && !cancelled) {
|
||||
resp = func(data);
|
||||
if (resp instanceof Promise) resp = await resp.catch((err)=> setTimeout(() => {throw err;},0));
|
||||
if (typeof resp == 'undefined') resp = true;
|
||||
} else if (cancelFunc && defaultCancel) {
|
||||
resp = cancelFunc(data);
|
||||
if (resp instanceof Promise) resp = await resp.catch((err)=> setTimeout(() => {throw err;},0));
|
||||
if (typeof resp == 'undefined') resp = false;
|
||||
}
|
||||
await obj.emitThen(eventName + '_done', data, cancelled).catch((err)=> setTimeout(() => {throw err;},0));
|
||||
return data;
|
||||
|
||||
return resp;
|
||||
}
|
||||
};
|
||||
|
|
@ -3,6 +3,9 @@ class Command {
|
|||
this.params = params;
|
||||
this.parent = parent;
|
||||
this.hash = parent ? parent.hash : {};
|
||||
this.uniqueHash = parent ? parent.uniqueHash : {};
|
||||
this.parentBase = (this.parent && this.parent.base && this.parent.base + ' ') || '';
|
||||
this.base = this.parentBase + (this.params.base || '');
|
||||
|
||||
this.updateHistory();
|
||||
}
|
||||
|
|
@ -44,9 +47,9 @@ class Command {
|
|||
updateHistory() {
|
||||
var all = '(.+?)';
|
||||
|
||||
var list = [this.params.base];
|
||||
var list = [this.base];
|
||||
if(this.params.aliases && this.params.aliases.length) {
|
||||
this.params.aliases.forEach(al => list.unshift(al));
|
||||
this.params.aliases.forEach(al => list.unshift(this.parentBase + al));
|
||||
}
|
||||
|
||||
list.forEach((command) => {
|
||||
|
|
@ -56,6 +59,7 @@ class Command {
|
|||
|
||||
if(this.path) this.hash[this.path] = this;
|
||||
});
|
||||
this.uniqueHash[this.base] = this;
|
||||
}
|
||||
|
||||
add(params) {
|
||||
|
|
|
|||
|
|
@ -30,24 +30,18 @@ module.exports.player=function(player,serv)
|
|||
|
||||
player.commands.add({
|
||||
base: 'setblock',
|
||||
info: 'to put a block',
|
||||
usage: '/setblock <x> <y> <z> <id> <data>',
|
||||
info: 'set a block at a position',
|
||||
usage: '/setblock <x> <y> <z> <id> [data]',
|
||||
op: true,
|
||||
parse(str) {
|
||||
var results = str.match(/^(~|~?-?[0-9]*) (~|~?-?[0-9]*) (~|~?-?[0-9]*) ([0-9]{1,3}) ([0-9]{1,3})/);
|
||||
var results = str.match(/^(~|~?-?[0-9]+) (~|~?-?[0-9]+) (~|~?-?[0-9]+) ([0-9]{1,3})(?: ([0-9]{1,3}))?/);
|
||||
if(!results) return false;
|
||||
return results;
|
||||
},
|
||||
action(params) {
|
||||
var res = params.map((num, i) => { // parseInt parameters
|
||||
if (num.indexOf('~') == 0) {
|
||||
return (player.position[['', 'x', 'y', 'z'][i]] >> 5) + parseInt(num.slice(1) || 0);
|
||||
} else {
|
||||
return parseInt(num); // return parseInt>>5 if position, not id
|
||||
}
|
||||
});
|
||||
|
||||
player.setBlock(new Vec3(res[1], res[2], res[3]), res[4],res[5]);
|
||||
var res = params.slice(1, 4);
|
||||
res = res.map((val, i) => serv.posFromString(val, player.position[['x','y','z'][i]] / 32))
|
||||
player.setBlock(new Vec3(res[0], res[1], res[2]).floored(), params[4], params[5] || 0);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
@ -1,32 +1,55 @@
|
|||
var Vec3 = require("vec3").Vec3;
|
||||
var UserError = require('flying-squid').UserError;
|
||||
|
||||
module.exports.player=function(player, serv) {
|
||||
|
||||
player.commands.add({
|
||||
base: 'help',
|
||||
info: 'to show all commands',
|
||||
usage: '/help [command]',
|
||||
action(params) {
|
||||
var c = params[0];
|
||||
var hash = player.commands.hash;
|
||||
parse(str) {
|
||||
var params = str.split(' ');
|
||||
var page = parseInt(params[params.length-1]);
|
||||
var search = '';
|
||||
if (page) {
|
||||
params.pop();
|
||||
}
|
||||
search = params.join(' ');
|
||||
return { search: search, page: (page && page - 1) || 0 };
|
||||
},
|
||||
action({search, page}) {
|
||||
if (page < 0) return 'Page # must be >= 1';
|
||||
var hash = player.commands.uniqueHash;
|
||||
|
||||
if(c) {
|
||||
var f=player.commands.find(c);
|
||||
if(f==undefined || f.length==0) return 'Command '+c+' not found';
|
||||
return f[0].params.usage + ' ' + f[0].params.info;
|
||||
} else {
|
||||
var used = [];
|
||||
for(var key in hash) {
|
||||
if(used.indexOf(hash[key]) > -1) continue;
|
||||
used.push(hash[key]);
|
||||
var PAGE_LENGTH = 8;
|
||||
|
||||
if(hash[key].params.info && (player.op || !hash[key].params.op)) {
|
||||
var str = hash[key].params.usage + ' ' + hash[key].params.info;
|
||||
if(hash[key].params.aliases && hash[key].params.aliases.length) {
|
||||
str += ' (aliases: ' + hash[key].params.aliases.join(', ') + ')';
|
||||
}
|
||||
var found = Object.keys(hash).filter(h => (h + ' ').indexOf((search && search + ' ') || '') == 0);
|
||||
|
||||
player.chat(str);
|
||||
}
|
||||
if (found.length == 0) { // None found
|
||||
return 'Could not find any matches';
|
||||
} else if (found.length == 1) { // Single command found, giev info on command
|
||||
var cmd = hash[found[0]];
|
||||
var usage = (cmd.params && cmd.params.usage) || cmd.base;
|
||||
var info = (cmd.params && cmd.params.info) || 'No info';
|
||||
player.chat(usage + ': ' + info);
|
||||
} else { // Multiple commands found, give list with pages
|
||||
var totalPages = Math.ceil((found.length-1) / PAGE_LENGTH);
|
||||
if (page >= totalPages) return 'There are only' + totalPages + ' help pages';
|
||||
found = found.sort();
|
||||
if (found.indexOf('search') != -1) {
|
||||
var baseCmd = hash[search];
|
||||
player.chat(baseCmd.base + ' -' + ((baseCmd.params && baseCmd.params.info && ' ' + baseCmd.params.info) || '=-=-=-=-=-=-=-=-'));
|
||||
} else {
|
||||
player.chat('Help -=-=-=-=-=-=-=-=-');
|
||||
}
|
||||
for (var i = PAGE_LENGTH*page; i < Math.min(PAGE_LENGTH*(page + 1), found.length); i++) {
|
||||
if (i == search) continue;
|
||||
var cmd = hash[found[i]];
|
||||
var usage = (cmd.params && cmd.params.usage) || cmd.base;
|
||||
var info = (cmd.params && cmd.params.info) || 'No info';
|
||||
player.chat(usage + ': ' + info);
|
||||
}
|
||||
player.chat('--=[Page ' + (page + 1) + ' of ' + totalPages + ']=--')
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -83,8 +106,7 @@ module.exports.player=function(player, serv) {
|
|||
},
|
||||
action(sel) {
|
||||
var arr = serv.selectorString(sel, player.position.scaled(1/32), player.world);
|
||||
if (arr instanceof Error) return arr.toString();
|
||||
else if (arr == null) return 'Could not find player';
|
||||
if (arr == null) return 'Could not find player';
|
||||
else player.chat(JSON.stringify(arr.map(a => a.id)));
|
||||
}
|
||||
});
|
||||
|
|
@ -96,11 +118,16 @@ module.exports.player=function(player, serv) {
|
|||
if (res) player.chat('' + res);
|
||||
}
|
||||
catch(err) {
|
||||
setTimeout(() => {throw err;}, 0);
|
||||
if (err instanceof UserError) player.chat('Error: ' + err.toString());
|
||||
else setTimeout(() => {throw err;}, 0);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
module.exports.entity = function(entity, serv) {
|
||||
entity.selectorString = (str) => serv.selectorString(str, entity.position.scaled(1/32), entity.world);
|
||||
}
|
||||
|
||||
module.exports.server = function(serv) {
|
||||
|
||||
function shuffleArray(array) {
|
||||
|
|
@ -126,7 +153,7 @@ module.exports.server = function(serv) {
|
|||
|
||||
serv.selector = (type, opt) => {
|
||||
if (['all', 'random', 'near', 'entity'].indexOf(type) == -1)
|
||||
return new Error('serv.selector(): type must be either [all, random, near, or entity]');
|
||||
throw new UserError('serv.selector(): type must be either [all, random, near, or entity]');
|
||||
|
||||
var count = typeof opt.count != 'undefined' ?
|
||||
count :
|
||||
|
|
@ -209,12 +236,13 @@ module.exports.server = function(serv) {
|
|||
else return sample.slice(count); // Negative, returns from end
|
||||
}
|
||||
|
||||
serv.selectorString = (str, pos, world) => {
|
||||
serv.selectorString = (str, pos, world, allowUser=true) => {
|
||||
pos = pos.clone();
|
||||
var player = serv.getPlayer(str);
|
||||
if (!player && str[0] != '@') return null;
|
||||
else if (player) return allowUser ? [player] : null;
|
||||
var match = str.match(/^@([a,r,p,e])(?:\[([^\]]+)\])?$/);
|
||||
if (match == null) return new Error('Invalid selector format');
|
||||
if (match == null) throw new UserError('Invalid selector format');
|
||||
var typeConversion = {
|
||||
a: 'all',
|
||||
r: 'random',
|
||||
|
|
@ -227,10 +255,10 @@ module.exports.server = function(serv) {
|
|||
var err;
|
||||
opt.forEach(o => {
|
||||
var match = o.match(/^([^=]+)=([^=]+)$/);
|
||||
if (match == null) err = new Error('Invalid selector option format: "' + o + '"');
|
||||
if (match == null) err = new UserError('Invalid selector option format: "' + o + '"');
|
||||
else optPair.push({key: match[1], val: match[2]});
|
||||
});
|
||||
if (err) return err;
|
||||
if (err) throw err;
|
||||
|
||||
var optConversion = {
|
||||
type: 'type',
|
||||
|
|
@ -269,4 +297,11 @@ module.exports.server = function(serv) {
|
|||
|
||||
return serv.selector(type, data);
|
||||
}
|
||||
|
||||
serv.posFromString = (str, pos) => {
|
||||
if (parseInt(str)) return parseInt(str);
|
||||
if (str.match(/~-?\d+/)) return parseInt(str.slice(1)) + pos;
|
||||
else if (str == '~') return pos;
|
||||
else throw new UserError('Invalid position');
|
||||
};
|
||||
}
|
||||
|
|
@ -19,9 +19,8 @@ module.exports.server=function(serv,options) {
|
|||
}
|
||||
}
|
||||
if (!entity.velocity || !entity.size) return;
|
||||
var oldPosAndOnGround = await entity.calculatePhysics(delta);
|
||||
if (!oldPosAndOnGround.oldPos.equals(new Vec3(0,0,0)))
|
||||
if (entity.type == 'mob') entity.sendPosition(oldPosAndOnGround);
|
||||
var posAndOnGround = await entity.calculatePhysics(delta);
|
||||
if (entity.type == 'mob') entity.sendPosition(posAndOnGround.position, posAndOnGround.onGround);
|
||||
})
|
||||
).catch((err)=> setTimeout(() => {throw err;},0));
|
||||
});
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ module.exports.player=function(player,serv)
|
|||
sendLogin();
|
||||
await player.sendMap();
|
||||
player.sendSpawnPosition();
|
||||
player.sendPosition();
|
||||
player.sendSelfPosition();
|
||||
player.updateHealth(player.health);
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -27,14 +27,14 @@ module.exports.entity=function(entity){
|
|||
entity.velocity.z = getFriction(entity.velocity.z, entity.friction.z, delta);
|
||||
}
|
||||
|
||||
var oldPos = entity.position.clone();
|
||||
var newPos = entity.position.clone();
|
||||
|
||||
entity.position.x += getMoveAmount('x', xBlock, entity, delta, sizeSigned.x);
|
||||
entity.position.y += getMoveAmount('y', yBlock, entity, delta, sizeSigned.y);
|
||||
entity.position.z += getMoveAmount('z', zBlock, entity, delta, sizeSigned.z);
|
||||
newPos.x += getMoveAmount('x', xBlock, entity, delta, sizeSigned.x);
|
||||
newPos.y += getMoveAmount('y', yBlock, entity, delta, sizeSigned.y);
|
||||
newPos.z += getMoveAmount('z', zBlock, entity, delta, sizeSigned.z);
|
||||
|
||||
//serv.emitParticle(30, serv.overworld, entity.position.scaled(1/32), { size: new Vec3(0, 0, 0) });
|
||||
return { oldPos: oldPos, onGround: yBlock}
|
||||
return { position: newPos, onGround: yBlock}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ module.exports.player=function(player)
|
|||
gamemode:player.gameMode,
|
||||
levelType:'default'
|
||||
});
|
||||
player.sendPosition();
|
||||
player.sendSelfPosition();
|
||||
player.updateHealth(20);
|
||||
player.nearbyEntities=[];
|
||||
player.updateAndSpawn();
|
||||
|
|
|
|||
|
|
@ -2,11 +2,6 @@ var Vec3 = require("vec3").Vec3;
|
|||
|
||||
module.exports.player = (player, serv) => {
|
||||
|
||||
var getPos = (num, dir='x', p=player) => {
|
||||
if (num[0] == '~') return p.position[dir] + parseInt(num.slice(1, num.length) || 0)*32;
|
||||
else return parseInt(num)*32;
|
||||
}
|
||||
|
||||
player.commands.add({
|
||||
base: 'teleport',
|
||||
aliases: ['tp'],
|
||||
|
|
@ -14,34 +9,29 @@ module.exports.player = (player, serv) => {
|
|||
usage: '/teleport [target player] <destination player or x> [y] [z]',
|
||||
op: true,
|
||||
parse(str) {
|
||||
return str.match(/^(((\w* )?~?-?\d* ~?-?\d* ~?-?\d*)|(\w* \w*))$/) ? str.split(' ') : false;
|
||||
return str.match(/^(((.* )?~?-?\d* ~?-?\d* ~?-?\d*)|(.+ .+))$/) ? str.split(' ') : false;
|
||||
},
|
||||
action(args) {
|
||||
if(args.length === 2 && args[0] !== args[1]) {
|
||||
let player_from;
|
||||
let player_to;
|
||||
if(args.length === 2) {
|
||||
let entities_from = player.selectorString(args[0]);
|
||||
let entity_to = player.selectorString(args[1])[0];
|
||||
|
||||
if(!(player_from = serv.getPlayer(args[0])) || !(player_to = serv.getPlayer(args[1])))
|
||||
return false;
|
||||
|
||||
player_from.teleport(player_to.position.clone());
|
||||
entities_from.forEach(e => e.teleport(entity_to.position.scaled(1/32)));
|
||||
} else if(args.length === 3) {
|
||||
let x = getPos(args[0], 'x');
|
||||
let y = getPos(args[1], 'y');
|
||||
let z = getPos(args[2], 'z');
|
||||
let x = serv.posFromString(args[0], player.position.x / 32);
|
||||
let y = serv.posFromString(args[1], player.position.y / 32);
|
||||
let z = serv.posFromString(args[2], player.position.z / 32);
|
||||
|
||||
player.teleport(new Vec3(x, y, z));
|
||||
|
||||
} else if(args.length === 4) {
|
||||
let player_from;
|
||||
let entities_from = player.selectorString(args[0]);
|
||||
|
||||
if(!(player_from = serv.getPlayer(args[0])))
|
||||
return false;
|
||||
|
||||
let x = getPos(args[1], 'x', player_from);
|
||||
let y = getPos(args[2], 'y', player_from);
|
||||
let z = getPos(args[3], 'z', player_from);
|
||||
|
||||
player_from.teleport(new Vec3(x, y, z));
|
||||
entities_from.forEach(e => e.teleport(new Vec3(
|
||||
serv.posFromString(args[1], e.position.x / 32),
|
||||
serv.posFromString(args[2], e.position.y / 32),
|
||||
serv.posFromString(args[3], e.position.z / 32)
|
||||
)));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -39,55 +39,20 @@ module.exports.player=function(player)
|
|||
headYaw: convYaw
|
||||
});
|
||||
}, () => {
|
||||
player.sendPosition();
|
||||
player.sendSelfPosition();
|
||||
});
|
||||
}
|
||||
|
||||
player._client.on('position', ({x,y,z,onGround} = {}) =>
|
||||
player.sendRelativePositionChange((new Vec3(x, y, z)).toFixedPosition(), onGround));
|
||||
player._client.on('position', ({x,y,z,onGround} = {}) => {
|
||||
player.sendPosition((new Vec3(x, y, z)).toFixedPosition(), onGround);
|
||||
});
|
||||
|
||||
player._client.on('position_look', ({x,y,z,onGround,yaw,pitch} = {}) => {
|
||||
player.sendRelativePositionChange((new Vec3(x, y, z)).toFixedPosition(), onGround);
|
||||
player.sendPosition((new Vec3(x, y, z)).toFixedPosition(), onGround);
|
||||
sendLook(yaw,pitch,onGround);
|
||||
});
|
||||
|
||||
player.sendRelativePositionChange = (newPosition, onGround) => {
|
||||
return player.behavior('move', {
|
||||
onGround: onGround,
|
||||
position: newPosition
|
||||
}, async ({onGround, position}) => {
|
||||
if (player.position.distanceTo(new Vec3(0, 0, 0)) != 0) {
|
||||
var diff = position.minus(player.position);
|
||||
if(diff.abs().x>127 || diff.abs().y>127 || diff.abs().z>127)
|
||||
{
|
||||
player._writeOthersNearby('entity_teleport', {
|
||||
entityId:player.id,
|
||||
x: position.x,
|
||||
y: position.y,
|
||||
z: position.z,
|
||||
yaw: player.yaw,
|
||||
pitch: player.pitch,
|
||||
onGround: onGround
|
||||
});
|
||||
}
|
||||
else if (diff.distanceTo(new Vec3(0, 0, 0)) != 0) {
|
||||
player._writeOthersNearby('rel_entity_move', {
|
||||
entityId: player.id,
|
||||
dX: diff.x,
|
||||
dY: diff.y,
|
||||
dZ: diff.z,
|
||||
onGround: onGround
|
||||
});
|
||||
}
|
||||
}
|
||||
player.position = position;
|
||||
player.onGround = onGround;
|
||||
}, () => {
|
||||
player.sendPosition();
|
||||
});
|
||||
};
|
||||
|
||||
player.sendPosition = () => {
|
||||
player.sendSelfPosition = () => {
|
||||
player._client.write('position', {
|
||||
x: player.position.x/32,
|
||||
y: player.position.y/32,
|
||||
|
|
@ -99,43 +64,46 @@ module.exports.player=function(player)
|
|||
};
|
||||
|
||||
player.teleport = async (position) => {
|
||||
await player.sendRelativePositionChange(position, false);
|
||||
player.sendPosition();
|
||||
var notCancelled = await player.sendPosition(position.scaled(32).floored(), false, true);
|
||||
if (notCancelled) player.sendSelfPosition();
|
||||
}
|
||||
};
|
||||
|
||||
module.exports.entity=function(entity,serv){
|
||||
entity.sendPosition = ({oldPos,onGround}) => {
|
||||
entity.behavior('move', {
|
||||
old: oldPos,
|
||||
onGround: onGround
|
||||
}, ({old,onGround}) => {
|
||||
var diff = entity.position.minus(old);
|
||||
|
||||
entity.sendPosition = (position, onGround, teleport=false) => {
|
||||
if (typeof position == 'undefined') throw new Error('undef');
|
||||
if (entity.position.equals(position) && entity.onGround == onGround) return Promise.resolve();
|
||||
return entity.behavior('move', {
|
||||
position: position,
|
||||
onGround: onGround,
|
||||
teleport: teleport
|
||||
}, ({position,onGround}) => {
|
||||
var diff = position.minus(entity.position);
|
||||
if(diff.abs().x>127 || diff.abs().y>127 || diff.abs().z>127)
|
||||
entity._writeOthersNearby('entity_teleport', {
|
||||
entityId: entity.id,
|
||||
x: entity.position.x,
|
||||
y: entity.position.y,
|
||||
z: entity.position.z,
|
||||
x: position.x,
|
||||
y: position.y,
|
||||
z: position.z,
|
||||
yaw: entity.yaw,
|
||||
pitch: entity.pitch,
|
||||
onGround: onGround
|
||||
});
|
||||
else if (diff.distanceTo(new Vec3(0, 0, 0)) != 0) serv._writeNearby('rel_entity_move', {
|
||||
else if (diff.distanceTo(new Vec3(0, 0, 0)) != 0) entity._writeOthersNearby('rel_entity_move', {
|
||||
entityId: entity.id,
|
||||
dX: diff.x,
|
||||
dY: diff.y,
|
||||
dZ: diff.z,
|
||||
onGround: onGround
|
||||
}, entity);
|
||||
});
|
||||
|
||||
entity.position = position;
|
||||
entity.onGround = onGround;
|
||||
}, () => {
|
||||
entity.position = oldPos;
|
||||
if (entity.type == 'player') player.sendSelfPosition();
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
|
||||
entity.sendVelocity = (vel, maxVel) => {
|
||||
var velocity = vel.scaled(32).floored(); // Make fixed point
|
||||
var maxVelocity = maxVel.scaled(32).floored();
|
||||
|
|
@ -152,6 +120,10 @@ module.exports.entity=function(entity,serv){
|
|||
}
|
||||
};
|
||||
|
||||
entity.teleport = (pos) => { // Overwritten in players inject above
|
||||
entity.sendPosition(pos.scaled(32), false, true);
|
||||
}
|
||||
|
||||
function addVelocityWithMax(current, newVel, max) {
|
||||
var x, y, z;
|
||||
if (current.x > max.x || current.x < -max.x) x = current.x;
|
||||
|
|
|
|||
|
|
@ -159,7 +159,7 @@ module.exports.player=function(player,serv,settings) {
|
|||
|
||||
await player.sendMap();
|
||||
|
||||
player.sendPosition();
|
||||
player.sendSelfPosition();
|
||||
player.emit('change_world');
|
||||
|
||||
await player.waitPlayerLogin();
|
||||
|
|
|
|||
Loading…
Reference in a new issue