示例#1
0
        static void RaisePlayerJoinedWorldEvent(Player player, World oldWorld, WorldChangeContext context)
        {
            var handler = JoinedWorld;

            if (handler != null)
            {
                handler(null, new PlayerJoinedWorldEventArgs(player, oldWorld, player.World, context));
            }
        }
示例#2
0
 internal PlayerJoinedWorldEventArgs([NotNull] Player player, [CanBeNull] World oldWorld, [NotNull] World newWorld, WorldChangeContext context)
 {
     if (player == null)
     {
         throw new ArgumentNullException("player");
     }
     Player   = player;
     OldWorld = oldWorld;
     NewWorld = newWorld;
     Context  = context;
 }
示例#3
0
 internal PlayerJoiningWorldEventArgs([NotNull] Player player, [CanBeNull] World oldWorld,
                                      [NotNull] World newWorld, WorldChangeContext context,
                                      string textLine1, string textLine2)
 {
     if (player == null)
     {
         throw new ArgumentNullException("player");
     }
     if (newWorld == null)
     {
         throw new ArgumentNullException("newWorld");
     }
     Player    = player;
     OldWorld  = oldWorld;
     NewWorld  = newWorld;
     Context   = context;
     TextLine1 = textLine1;
     TextLine2 = textLine2;
 }
示例#4
0
 internal PlayerJoinedWorldEventArgs( [NotNull] Player player, [CanBeNull] World oldWorld, [NotNull] World newWorld, WorldChangeContext context ) {
     if( player == null ) throw new ArgumentNullException( "player" );
     Player = player;
     OldWorld = oldWorld;
     NewWorld = newWorld;
     Context = context;
 }
示例#5
0
 internal PlayerJoiningWorldEventArgs( [NotNull] Player player, [CanBeNull] World oldWorld,
                                       [NotNull] World newWorld, WorldChangeContext context,
                                       string textLine1, string textLine2 ) {
     if( player == null ) throw new ArgumentNullException( "player" );
     if( newWorld == null ) throw new ArgumentNullException( "newWorld" );
     Player = player;
     OldWorld = oldWorld;
     NewWorld = newWorld;
     Context = context;
     TextLine1 = textLine1;
     TextLine2 = textLine2;
 }
示例#6
0
 static void RaisePlayerJoinedWorldEvent( Player player, World oldWorld, WorldChangeContext context ) {
     var handler = JoinedWorld;
     if( handler != null ) handler( null, new PlayerJoinedWorldEventArgs( player, oldWorld, player.World, context ) );
 }
示例#7
0
 static bool RaisePlayerJoiningWorldEvent( [NotNull] Player player, [NotNull] World newWorld, WorldChangeContext context,
                                           string textLine1, string textLine2 ) {
     if( player == null ) throw new ArgumentNullException( "player" );
     if( newWorld == null ) throw new ArgumentNullException( "newWorld" );
     var handler = JoiningWorld;
     if( handler == null ) return true;
     var e = new PlayerJoiningWorldEventArgs( player, player.World, newWorld, context, textLine1, textLine2 );
     handler( null, e );
     return !e.Cancel;
 }
示例#8
0
        static bool RaisePlayerJoiningWorldEvent([NotNull] Player player, [NotNull] World newWorld, WorldChangeContext context,
                                                 string textLine1, string textLine2)
        {
            if (player == null)
            {
                throw new ArgumentNullException("player");
            }
            if (newWorld == null)
            {
                throw new ArgumentNullException("newWorld");
            }
            var handler = JoiningWorld;

            if (handler == null)
            {
                return(true);
            }
            var e = new PlayerJoiningWorldEventArgs(player, player.World, newWorld, context, textLine1, textLine2);

            handler(null, e);
            return(!e.Cancel);
        }
示例#9
0
        internal bool JoinWorldNow( [NotNull] World newWorld, bool doUseWorldSpawn, WorldChangeContext context ) {
            if( newWorld == null ) throw new ArgumentNullException( "newWorld" );
            if( !Enum.IsDefined( typeof( WorldChangeContext ), context ) ) {
                throw new ArgumentOutOfRangeException( "context" );
            }
            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, context, 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( Packet.MakeHandshake( this, textLine1, textLine2 ) );
            }

            writer.Write( OpCode.MapBegin );
            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.Write( OpCode.MapChunk );
                writer.Write( (short)chunkSize );
                writer.Write( buffer, 0, 1024 );
                writer.Write( progress );
                BytesSent += 1028;
                mapBytesSent += chunkSize;
            }

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

            // Done sending over level copy
            writer.Write( OpCode.MapEnd );
            writer.Write( (short)map.Width );
            writer.Write( (short)map.Height );
            writer.Write( (short)map.Length );
            BytesSent += 7;

            // Sets player's spawn point to map spawn
            writer.Write( Packet.MakeAddEntity( -1, ListName, map.Spawn ).Bytes );
            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.Write( Packet.MakeTeleport( -1, Position ).Bytes );
            BytesSent += 10;

            if( oldWorld == newWorld ) {
                Message( "Rejoined world {0}", newWorld.ClassyName );
            } else {
                Message( "Joined world {0}", newWorld.ClassyName );
            }

            RaisePlayerJoinedWorldEvent( this, oldWorld, context );
            
            Server.RequestGC();
            return true;
        }
示例#10
0
 /// <summary> Causes a player to join the specified world, with the specified context, at the specified location. </summary>
 /// <param name="newWorld"> World for this player to join. </param>
 /// <param name="context"> context why this player is joining this world. </param>
 /// <param name="position"> Position in the world that the player is joining. </param>
 public void JoinWorld( [NotNull] World newWorld, WorldChangeContext context, Position position ) {
     if( newWorld == null ) throw new ArgumentNullException( "newWorld" );
     if( !Enum.IsDefined( typeof( WorldChangeContext ), context ) ) {
         throw new ArgumentOutOfRangeException( "context" );
     }
     lock( joinWorldLock ) {
         useWorldSpawn = false;
         postJoinPosition = position;
         forcedWorldToJoin = newWorld;
         worldChangeContext = context;
     }
 }
示例#11
0
 /// <summary> Causes a player to join the specified world, with the specified context, at Position.Zero. </summary>
 /// <param name="newWorld"> World for this player to join. </param>
 /// <param name="context"> context why the player is joining this world. </param>
 public void JoinWorld( [NotNull] World newWorld, WorldChangeContext context ) {
     if( newWorld == null ) throw new ArgumentNullException( "newWorld" );
     lock( joinWorldLock ) {
         useWorldSpawn = true;
         postJoinPosition = Position.Zero;
         forcedWorldToJoin = newWorld;
         worldChangeContext = context;
     }
 }