static void RaisePlayerJoinedWorldEvent(Player player, World oldWorld, WorldChangeContext context) { var handler = JoinedWorld; if (handler != null) { handler(null, new PlayerJoinedWorldEventArgs(player, oldWorld, player.World, context)); } }
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; }
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; }
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; }
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; }
static void RaisePlayerJoinedWorldEvent( Player player, World oldWorld, WorldChangeContext context ) { var handler = JoinedWorld; if( handler != null ) handler( null, new PlayerJoinedWorldEventArgs( player, oldWorld, player.World, context ) ); }
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; }
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); }
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; }
/// <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; } }
/// <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; } }