From 2a3b8a157bd101171faceb1f72af4525c427e6bd Mon Sep 17 00:00:00 2001 From: Romain Beaumont Date: Sun, 25 Oct 2015 23:26:04 +0100 Subject: [PATCH] add player.spawnAPlayer, player.despawnPlayers, player.updateAndSpawnNearbyPlayers, automatically spawn and despawn players when getting closer or far --- doc/api.md | 28 +++++++++++--- src/lib/playerPlugins/blocks.js | 2 +- src/lib/playerPlugins/communication.js | 2 +- src/lib/playerPlugins/login.js | 36 ++++++++++++++++-- src/lib/playerPlugins/logout.js | 10 ++++- src/lib/playerPlugins/respawn.js | 4 +- src/lib/playerPlugins/world.js | 52 +++++++------------------- 7 files changed, 81 insertions(+), 53 deletions(-) diff --git a/doc/api.md b/doc/api.md index 54ed686..73df217 100644 --- a/doc/api.md +++ b/doc/api.md @@ -29,7 +29,6 @@ - [serv.createLog()](#servcreatelog) - [serv.log(message)](#servlogmessage) - [serv.broadcast(message[,color])](#servbroadcastmessagecolor) - - [serv.setBlock(position,blockType)](#servsetblockpositionblocktype) - [serv.getPlayer(username)](#servgetplayerusername) - [serv.getNearby(loc)](#servgetnearbyloc) - [server.banUsername(username,reason,callback)](#serverbanusernameusernamereasoncallback) @@ -49,6 +48,7 @@ - [player.username](#playerusername) - [player.view](#playerview) - [player.world](#playerworld) + - [player.nearbyPlayers](#playernearbyplayers) - [Events](#events-1) - ["connected"](#connected) - ["spawned"](#spawned) @@ -66,11 +66,14 @@ - [player.changeBlock(position,blockType)](#playerchangeblockpositionblocktype) - [player.sendBlock(position,blockType)](#playersendblockpositionblocktype) - [player.sendInitialPosition()](#playersendinitialposition) - - [player.spawn()](#playerspawn) - [player.setGameMode(gameMode)](#playersetgamemodegamemode) - [player.handleCommand(command)](#playerhandlecommandcommand) + - [player.setBlock(position,blockType)](#playersetblockpositionblocktype) - [player.updateHealth(health)](#playerupdatehealthhealth) - [player.changeWorld(world, opt)](#playerchangeworldworld-opt) + - [player.spawnAPlayer(spawnedPlayer)](#playerspawnaplayerspawnedplayer) + - [player.despawnPlayers(despawnedPlayers)](#playerdespawnplayersdespawnedplayers) + - [player.updateAndSpawnNearbyPlayers()](#playerupdateandspawnnearbyplayers) - [Low level properties](#low-level-properties) - [player._client](#player_client) - [Low level methods](#low-level-methods-1) @@ -264,6 +267,10 @@ The view size of the player, for example 8 for 16x16 The world which the player is in. +#### player.nearbyPlayers + +Nearby players. + ### Events #### "connected" @@ -333,10 +340,6 @@ this will not make any changes on the server's world and only sends it to the us send its initial position to the player -#### player.spawn() - -tell everybody else that the player spawned - #### player.setGameMode(gameMode) set player gameMode to `gameMode` @@ -364,6 +367,19 @@ The world object which the player is in (use serv.overworld, serv.netherworld, s - yaw: Yaw in which they spawn, default is 0 - pitch: Pitch in which they spawn, default is 0 + +#### player.spawnAPlayer(spawnedPlayer) + +Spawn `spawnedPlayer` for `player`. + +#### player.despawnPlayers(despawnedPlayers) + +Despawn `despawnedPlayers` for `player`. + +#### player.updateAndSpawnNearbyPlayers() + +Spawn and despawn the correct players depending on distance for `player`. + ### Low level properties #### player._client diff --git a/src/lib/playerPlugins/blocks.js b/src/lib/playerPlugins/blocks.js index 6e8de7b..50a5022 100644 --- a/src/lib/playerPlugins/blocks.js +++ b/src/lib/playerPlugins/blocks.js @@ -19,7 +19,7 @@ function inject(serv,player) function setBlock(position,blockType) { - player.getNearby().forEach(function(player){ + serv.players.filter(p => p.world==player.world).forEach(function(player){ player.sendBlock(position, blockType); }); return player.world.setBlockType(position,blockType); diff --git a/src/lib/playerPlugins/communication.js b/src/lib/playerPlugins/communication.js index 9ac5910..5946dbb 100644 --- a/src/lib/playerPlugins/communication.js +++ b/src/lib/playerPlugins/communication.js @@ -9,7 +9,7 @@ function inject(serv,player) }; player._writeOthersNearby = function(packetName, packetFields) { - serv._writeArray(packetName, packetFields, player.getNearby()); + serv._writeArray(packetName, packetFields, player.nearbyPlayers); }; player.getOthers = function() { diff --git a/src/lib/playerPlugins/login.js b/src/lib/playerPlugins/login.js index 59f5281..51b896f 100644 --- a/src/lib/playerPlugins/login.js +++ b/src/lib/playerPlugins/login.js @@ -20,6 +20,33 @@ function inject(serv,player) serv.players.push(player); serv.uuidToPlayer[player._client.uuid] = player; player.loadedChunks={}; + player.nearbyPlayers=[]; + } + + function updateAndSpawnNearbyPlayers() + { + player.lastPositionPlayersUpdated=player.entity.position; + var updatedPlayers=player.getNearby(); + var playersToAdd=updatedPlayers.filter(p => player.nearbyPlayers.indexOf(p)==-1); + var playersToRemove=player.nearbyPlayers.filter(p => updatedPlayers.indexOf(p)==-1); + player.despawnPlayers(playersToRemove); + playersToAdd.forEach(player.spawnAPlayer); + + playersToRemove.forEach(p => p.despawnPlayers([player])); + playersToRemove.forEach(p => p.nearbyPlayers=p.getNearby()); + playersToAdd.forEach(p => p.spawnAPlayer(player)); + playersToAdd.forEach(p => p.nearbyPlayers=p.getNearby()); + + player.nearbyPlayers=updatedPlayers; + + } + + function sendPlayersWhenMove() + { + player.on("positionChanged",function(){ + if(player.entity.position.distanceTo(player.lastPositionPlayersUpdated)>2*32) + player.updateAndSpawnNearbyPlayers(); + }); } function sendLogin() @@ -41,7 +68,7 @@ function inject(serv,player) { player.on("positionChanged",function(){ if(!player.sendingChunks && player.entity.position.distanceTo(player.lastPositionChunkUpdated)>16*32) - player.sendMap(); + player.sendRestMap(); }); } @@ -108,22 +135,23 @@ function inject(serv,player) sendLogin(); await player.sendMap(); player.sendSpawnPosition(); + player.sendPosition(); player.updateHealth(player.entity.health); updateTime(); setGameMode(player.gameMode); fillTabList(); - player.spawnForOthers(); - player.sendNearbyPlayers(); + player.updateAndSpawnNearbyPlayers(); - player.spawn(); announceJoin(); player.emit("spawned"); + sendPlayersWhenMove(); setTimeout(function(){player.sendRestMap();sendChunkWhenMove();},100); } player.setGameMode=setGameMode; player.login=login; + player.updateAndSpawnNearbyPlayers=updateAndSpawnNearbyPlayers; } \ No newline at end of file diff --git a/src/lib/playerPlugins/logout.js b/src/lib/playerPlugins/logout.js index 7558eac..f3f3fdd 100644 --- a/src/lib/playerPlugins/logout.js +++ b/src/lib/playerPlugins/logout.js @@ -2,6 +2,12 @@ module.exports=inject; function inject(serv,player) { + function despawnPlayers(despawnedPlayers) { + player._client.write('entity_destroy', { + 'entityIds': despawnedPlayers.map(p => p.entity.id) + }); + } + player._client.on('end', function () { if(player.entity) { serv.broadcast(player.username + ' quit the game.', "yellow"); @@ -11,7 +17,7 @@ function inject(serv,player) UUID: player._client.uuid }] }); - player._writeOthersNearby('entity_destroy', {'entityIds': [player.entity.id]}); + player.nearbyPlayers.forEach(otherPlayer => otherPlayer.despawnPlayers([player])); delete serv.entities[player.entity.id]; player.emit('disconnected'); var index = serv.players.indexOf(player); @@ -26,4 +32,6 @@ function inject(serv,player) player._client.on('error', function (error) { player.emit('error',error); }); + + player.despawnPlayers=despawnPlayers; } \ No newline at end of file diff --git a/src/lib/playerPlugins/respawn.js b/src/lib/playerPlugins/respawn.js index b92c353..019183b 100644 --- a/src/lib/playerPlugins/respawn.js +++ b/src/lib/playerPlugins/respawn.js @@ -10,9 +10,9 @@ function inject(serv, player) gamemode:player.gameMode, levelType:'default' }); - player.sendInitialPosition(); + player.sendPosition(); player.updateHealth(20); - player.spawn(); + player.updateAndSpawnNearbyPlayers(); } }); } \ No newline at end of file diff --git a/src/lib/playerPlugins/world.js b/src/lib/playerPlugins/world.js index fc5e038..03e178f 100644 --- a/src/lib/playerPlugins/world.js +++ b/src/lib/playerPlugins/world.js @@ -4,37 +4,18 @@ var spiralloop = require('spiralloop'); module.exports = inject; function inject(serv, player) { - function spawn() { - player.sendPosition(); - } - function spawnForOthers() { - player._writeOthersNearby('named_entity_spawn',{ - entityId: player.entity.id, - playerUUID: player._client.uuid, - x: player.entity.position.x, - y: player.entity.position.y, - z: player.entity.position.z, - yaw: player.entity.yaw, - pitch: player.entity.pitch, + function spawnAPlayer(spawnedPlayer) { + player._client.write('named_entity_spawn', { + entityId: spawnedPlayer.entity.id, + playerUUID: spawnedPlayer._client.uuid, + x: spawnedPlayer.entity.position.x, + y: spawnedPlayer.entity.position.y, + z: spawnedPlayer.entity.position.z, + yaw: spawnedPlayer.entity.yaw, + pitch: spawnedPlayer.entity.pitch, currentItem: 0, - metadata: player.entity.metadata - }); - } - - function sendNearbyPlayers() { - player.getNearby().forEach(function (otherPlayer) { - player._client.write('named_entity_spawn', { - entityId: otherPlayer.entity.id, - playerUUID: otherPlayer._client.uuid, - x: otherPlayer.entity.position.x, - y: otherPlayer.entity.position.y, - z: otherPlayer.entity.position.z, - yaw: otherPlayer.entity.yaw, - pitch: otherPlayer.entity.pitch, - currentItem: 0, - metadata: otherPlayer.entity.metadata - }); + metadata: spawnedPlayer.entity.metadata }); } @@ -59,9 +40,8 @@ function inject(serv, player) { return t; } - function sendNearbyChunks(view, world) + function sendNearbyChunks(view) { - world = world || player.world; player.lastPositionChunkUpdated=player.entity.position; var playerChunkX=Math.floor(player.entity.position.x/16/32); var playerChunkZ=Math.floor(player.entity.position.z/16/32); @@ -80,7 +60,7 @@ function inject(serv, player) { .reduce((acc,{chunkX,chunkZ})=> acc //.then(() => sleep(100)) - .then(() => world.getColumn(chunkX,chunkZ)) + .then(() => player.world.getColumn(chunkX,chunkZ)) .then((column) => player.sendChunk(chunkX,chunkZ,column)) ,Promise.resolve()); } @@ -112,7 +92,6 @@ function inject(serv, player) { } async function changeWorld(world, opt) { - player._writeOthersNearby('entity_destroy', {'entityIds': [player.entity.id]}); opt = opt || {}; player.world = world; @@ -126,9 +105,8 @@ function inject(serv, player) { }); player.entity.position=player.spawnPoint.toFixedPosition(); player.sendSpawnPosition(); + player.updateAndSpawnNearbyPlayers(); - player.spawnForOthers(); - player.sendNearbyPlayers(); await player.sendMap(); setTimeout(player.sendRestMap,100); player.sendPosition(); @@ -136,15 +114,13 @@ function inject(serv, player) { player.emit('change_world'); } - player.spawn = spawn; - player.spawnForOthers = spawnForOthers; - player.sendNearbyPlayers = sendNearbyPlayers; player.sendNearbyChunks = sendNearbyChunks; player.changeWorld = changeWorld; player.sendChunk = sendChunk; player.sendMap = sendMap; player.sendRestMap = sendRestMap; player.sendSpawnPosition = sendSpawnPosition; + player.spawnAPlayer = spawnAPlayer; player.on('chat', function(message) { if (message == 'world') {