diff --git a/src/server/components/portal/sendObjToZone.js b/src/server/components/portal/sendObjToZone.js index 52b39278..3638d2fd 100644 --- a/src/server/components/portal/sendObjToZone.js +++ b/src/server/components/portal/sendObjToZone.js @@ -46,6 +46,16 @@ const sendObjToZone = async ({ obj, invokingObj, zoneName, toPos, toRelativePos globalSyncer.processDestroyedObject(obj); await obj.auth.doSave(); + //Inform the main thread that we are rezoning. We do this because if the player + // dc's before rezone is complete the player might become stuck in the main thread + process.send({ + method: 'object', + serverId: obj.serverId, + obj: { + rezoning: true + } + }); + //We have to do this again. This is because onCollisionEnter in portal is not blocking (even though it is async) // So physics will carry on and allow the obj to move onto the next tile (changing the position while we save above) fixPosition(obj, toPos, toRelativePos, invokingObj); diff --git a/src/server/security/connections.js b/src/server/security/connections.js index 8aa53771..b2087c92 100644 --- a/src/server/security/connections.js +++ b/src/server/security/connections.js @@ -44,9 +44,13 @@ module.exports = { }] }); - await new Promise(res => { - atlas.removeObject(player, false, res); - }); + //Rezoning is set to true while rezoning so we don't try to remove objects + // from zones if they are currently rezoning + if (player.rezoning !== true) { + await new Promise(res => { + atlas.removeObject(player, false, res); + }); + } } if (player.name) { @@ -123,19 +127,25 @@ module.exports = { }, logOut: async function (exclude) { - let players = this.players; + const { players } = this; + let pLen = players.length; for (let i = 0; i < pLen; i++) { - let p = players[i]; + const p = players[i]; - if ((!p) || (p === exclude) || (!p.auth)) + if (!p || p === exclude || !p.auth) continue; - - if (p.auth.username === exclude.auth.username) { + else if (p.auth.username === exclude.auth.username) { if (p.name && p.zoneId) await atlas.forceSavePlayer(p.id, p.zoneId); - p.socket.emit('dc', {}); + if (p.socket?.connected) + p.socket.emit('dc', {}); + else { + players.splice(i, 1); + i--; + pLen--; + } } } }, diff --git a/src/server/world/atlas.js b/src/server/world/atlas.js index dcd1389f..045089a8 100644 --- a/src/server/world/atlas.js +++ b/src/server/world/atlas.js @@ -15,6 +15,9 @@ module.exports = { if (!serverObj) return; + //While rezoning, this is set to true. So we remove it + delete serverObj.rezoning; + events.emit('onBeforePlayerEnterWorld', obj); let { zoneName, zoneId } = obj;