fCraft.Player.JoinWorldNow C# (CSharp) Method

JoinWorldNow() private method

private JoinWorldNow ( [ newWorld, bool doUseWorldSpawn, WorldChangeReason reason ) : bool
newWorld [
doUseWorldSpawn bool
reason WorldChangeReason
return bool
        internal bool JoinWorldNow( [NotNull] World newWorld, bool doUseWorldSpawn, WorldChangeReason reason )
        {
            if ( newWorld == null )
                throw new ArgumentNullException( "newWorld" );
            if ( !Enum.IsDefined( typeof( WorldChangeReason ), reason ) ) {
                throw new ArgumentOutOfRangeException( "reason" );
            }
            if ( Thread.CurrentThread != ioThread ) {
                throw new InvalidOperationException( "Player.JoinWorldNow may only be called from player's own thread. " +
                                                     "Use Player.JoinWorld instead." );
            }

            string textLine1 = ConfigKey.ServerName.GetString();
            string textLine2;

            if ( IsUsingWoM && ConfigKey.WoMEnableEnvExtensions.Enabled() ) {
                if ( IP.Equals( IPAddress.Loopback ) ) {
                    textLine2 = "cfg=localhost:" + Server.Port + "/" + newWorld.Name;
                } else {
                    textLine2 = "cfg=" + Server.ExternalIP + ":" + Server.Port + "/" + newWorld.Name;
                }
            } else {
                textLine2 = "Loading world " + newWorld.ClassyName;
            }

            if ( RaisePlayerJoiningWorldEvent( this, newWorld, reason, textLine1, textLine2 ) ) {
                Logger.Log( LogType.Warning,
                            "Player.JoinWorldNow: Player {0} was prevented from joining world {1} by an event callback.",
                            Name, newWorld.Name );
                return false;
            }

            World oldWorld = World;

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

            ResetVisibleEntities();

            ClearLowPriotityOutputQueue();

            Map map;

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

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

            // Start sending over the level copy
            if ( oldWorld != null ) {
                SendNow( PacketWriter.MakeHandshake( this, textLine1, textLine2 ) );
            }

            writer.WriteMapBegin();
            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 mapStream = new MemoryStream() ) {
                map.GetCompressedCopy( mapStream, true );
                blockData = mapStream.ToArray();
            }
            Logger.Log( LogType.Debug,
                        "Player.JoinWorldNow: Sending compressed map ({0} bytes) to {1}.",
                        blockData.Length, 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.WriteMapChunk( buffer, chunkSize, progress );
                BytesSent += 1028;
                mapBytesSent += chunkSize;
            }

            // Turn off Nagel's algorithm again for LowLatencyMode
            client.NoDelay = ConfigKey.LowLatencyMode.Enabled();

            // Done sending over level copy
            writer.WriteMapEnd( map );
            BytesSent += 7;

            // Sets player's spawn point to map spawn
            writer.WriteAddEntity( 255, this, map.Spawn );
            BytesSent += 74;

            // Teleport player to the target location
            // This allows preserving spawn rotation/look, and allows
            // teleporting player to a specific location (e.g. /TP or /Bring)
            writer.WriteTeleport( 255, Position );
            BytesSent += 10;

            if ( oldWorld == newWorld ) {
                if ( !newWorld.IsRealm ) {
                    Message( "Rejoined world {0}", newWorld.ClassyName );
                } else {
                    Message( "Rejoined realm {0}", newWorld.ClassyName );
                }
            } else {
                if ( !newWorld.IsRealm ) {
                    Message( "Joined world {0}", newWorld.ClassyName );
                } else {
                    Message( "Joined realm {0}", newWorld.ClassyName );
                }
                if ( newWorld != WorldManager.MainWorld ) {
                    newWorld.VisitCount++;
                }
                string greeting = newWorld.Greeting;
                if ( greeting != null ) {
                    greeting = Chat.ReplaceTextKeywords( this, greeting );
                    Message( "&R* {0}: {1}", newWorld.Name, greeting );
                }
            }
            RaisePlayerJoinedWorldEvent( this, oldWorld, reason );

            // Done.
            Server.RequestGC();

            return true;
        }

Usage Example

Ejemplo n.º 1
0
        static void JoinHandler( Player player, CommandReader cmd ) {
            string worldName = cmd.Next();
            if( worldName == null ) {
                CdJoin.PrintUsage( player );
                return;
            }

            if( worldName == "-" ) {
                if( player.LastUsedWorldName != null ) {
                    worldName = player.LastUsedWorldName;
                } else {
                    player.Message( "Cannot repeat world name: you haven't used any names yet." );
                    return;
                }
            }

            World[] worlds = WorldManager.FindWorlds( player, worldName );

            if( worlds.Length > 1 ) {
                player.MessageManyMatches( "world", worlds );

            } else if( worlds.Length == 1 ) {
                World world = worlds[0];
                player.LastUsedWorldName = world.Name;
                switch( world.AccessSecurity.CheckDetailed( player.Info ) ) {
                    case SecurityCheckResult.Allowed:
                    case SecurityCheckResult.WhiteListed:
                        if( world.IsFull ) {
                            player.Message( "Cannot join {0}&S: world is full.", world.ClassyName );
                            return;
                        }
                        player.StopSpectating();
                        if( !player.JoinWorldNow( world, true, WorldChangeContext.ManualJoin ) ) {
                            player.Message( "ERROR: Failed to join world. See log for details." );
                        }
                        break;
                    case SecurityCheckResult.BlackListed:
                        player.Message( "Cannot join world {0}&S: you are blacklisted.",
                                        world.ClassyName );
                        break;
                    case SecurityCheckResult.RankTooLow:
                        player.Message( "Cannot join world {0}&S: must be {1}+",
                                        world.ClassyName, world.AccessSecurity.MinRank.ClassyName );
                        break;
                    // TODO: Uncomment
                    //case SecurityCheckResult.RankTooHigh:
                    //    player.Message("Cannot join world {0}&S: must be {1}-",
                    //                    world.ClassyName, world.AccessSecurity.MaxRank.ClassyName);
                    //    break;
                }

            } else {
                player.MessageNoWorld( worldName );
            }
        }
All Usage Examples Of fCraft.Player::JoinWorldNow