fCraft.Session.JoinWorldNow C# (CSharp) Method

JoinWorldNow() private method

private JoinWorldNow ( World newWorld, bool firstTime, bool doUseWorldSpawn ) : bool
newWorld World
firstTime bool
doUseWorldSpawn bool
return bool
        internal bool JoinWorldNow( World newWorld, bool firstTime, bool doUseWorldSpawn ) {
            if( newWorld == null ) throw new ArgumentNullException( "newWorld" );

            if( !Player.CanJoin( newWorld ) ) {
                Logger.Log( "Session.JoinWorldNow: Access limits prevented {0} from joining {1}.", LogType.Error,
                            Player.Name, newWorld.Name );
                return false;
            }

            if( !newWorld.FirePlayerTriedToJoinEvent( Player ) ) {
                Logger.Log( "Session.JoinWorldNow: FirePlayerTriedToJoinEvent prevented {0} from joining {1}", LogType.Warning,
                            Player.Name, newWorld.Name );
                return false;
            }

            World oldWorld = Player.World;

            // remove player from the old world
            if( oldWorld != null && oldWorld != newWorld ) {
                if( !oldWorld.ReleasePlayer( Player ) ) {
                    Logger.Log( "Session.JoinWorldNow: Player asked to be released from its world, " +
                                "but the world did not contain the player.", LogType.Error );
                }
            }

            ResetVisibleEntities();

            ClearBlockUpdateQueue();

            Map map;

            // try to join the new world
            if( oldWorld != newWorld ) {
                bool announce = !firstTime && (oldWorld.Name != newWorld.Name);
                map = newWorld.AcceptPlayer( Player, announce );
                if( map == null ) {
                    return false;
                }
            } else {
                map = oldWorld.EnsureMapLoaded();
            }
            Player.World = newWorld;

            // Set spawn point
            Position spawn;
            if( doUseWorldSpawn ) {
                spawn = map.Spawn;
            }else{
                spawn = postJoinPosition;
            }
            Player.Position = spawn;

            // Start sending over the level copy
            if( !firstTime ) {
                SendNow( PacketWriter.MakeHandshake( Player,
                                                     ConfigKey.ServerName.GetString(),
                                                     "Loading world " + newWorld.GetClassyName() ) );
            }

            writer.WriteLevelBegin();
            bytesSent++;

            // enable Nagle's algorithm (in case it was turned off by LowLatencyMode)
            // to avoid wasting bandwidth for map transfer
            client.NoDelay = false;

            // Fetch compressed map copy
            byte[] buffer = new byte[1024];
            int mapBytesSent = 0;
            byte[] blockData;
            using( MemoryStream stream = new MemoryStream() ) {
                map.GetCompressedCopy( stream, true );
                blockData = stream.ToArray();
            }
            Logger.Log( "Session.JoinWorldNow: Sending compressed level copy ({0} bytes) to {1}.", LogType.Debug,
                        blockData.Length, Player.Name );

            // Transfer the map copy
            while( mapBytesSent < blockData.Length ) {
                int chunkSize = blockData.Length - mapBytesSent;
                if( chunkSize > 1024 ) {
                    chunkSize = 1024;
                } else {
                    // CRC fix for ManicDigger
                    for( int i = 0; i < buffer.Length; i++ ) {
                        buffer[i] = 0;
                    }
                }
                Array.Copy( blockData, mapBytesSent, buffer, 0, chunkSize );
                byte progress = (byte)(100 * mapBytesSent / blockData.Length);

                // write in chunks of 1024 bytes or less
                writer.WriteLevelChunk( buffer, chunkSize, progress );
                bytesSent += 1028; 
                mapBytesSent += chunkSize;
            }

            // Done sending over level copy
            writer.WriteLevelEnd( map );
            bytesSent += 7;

            // Send spawn point
            writer.WriteAddEntity( 255, Player, map.Spawn );
            bytesSent += 74;
            writer.WriteTeleport( 255, spawn );
            bytesSent += 10;

            Player.Message( "Joined world {0}", newWorld.GetClassyName() );

            // Turn off Nagel's algorithm again for LowLatencyMode
            if( ConfigKey.LowLatencyMode.GetBool() ) {
                client.NoDelay = true;
            }

            Server.FireWorldChangedEvent( Player, oldWorld, newWorld );

            // Done.
            if( MonoCompat.IsMono ) {
                Server.RequestGC();
            }

            return true;
        }