// Construction
 public CClientChatChannel( EChannelID channel_id, string channel_name, EClientChannelNumber channel_number, bool announce_join_leave )
 {
     ChannelID = channel_id;
     ChannelName = channel_name;
     ChannelNumber = channel_number;
     AnnounceJoinLeave = announce_join_leave;
 }
 private void Add_Channel_To_Player( EPersistenceID player_id, EChannelID channel_id )
 {
     CChatPlayer player = Get_Player_By_Persistence_ID( player_id );
     if ( player != null )
     {
         player.Add_Channel( channel_id );
     }
 }
 // Construction
 public CJoinChatChannelRequestServerMessage( EPersistenceID player_id, EChannelID channel_id, EChannelGameProperties remove_mask )
     : base()
 {
     PlayerID = player_id;
     ChannelID = channel_id;
     RemoveMask = remove_mask;
 }
 // Construction
 public CPlayerChatMessage( EChannelID channel_id, string player_name, string chat_message )
     : base()
 {
     ChannelID = channel_id;
     PlayerName = player_name;
     ChatMessage = chat_message;
 }
 // Construction
 public CLeaveChatChannelMessage( EChannelID channel_id )
     : base()
 {
     ChannelID = channel_id;
 }
 // Construction
 public CChatClientNotificationMessage( EChannelID channel_id, string target_name, EPersistenceID target_id, EChatNotification chat_event, string source_name )
     : base()
 {
     ChannelID = channel_id;
     TargetName = target_name;
     TargetID = target_id;
     SourceName = source_name;
     ChatEvent = chat_event;
 }
 private void Send_Notification_To_Channel( EChannelID channel_id, EPersistenceID player_id, EChatNotification chat_event, EPersistenceID skip_id )
 {
     Send_Notification_To_Channel( channel_id, EPersistenceID.Invalid, player_id, chat_event, skip_id );
 }
        private void Send_Message_To_Channel( EChannelID channel_id, CNetworkMessage message, EPersistenceID skip_id )
        {
            CServerChatChannel channel = Get_Channel_By_Channel_ID( channel_id );
            if ( channel == null )
            {
                return;
            }

            channel.Members.Where( n => n != skip_id ).Apply( pid => Send_Message_To_Player( message, pid ) );
        }
        private void Request_Destroy_Channel( EChannelID channel_id )
        {
            CServerChatChannel channel = Get_Channel_By_Channel_ID( channel_id );
            if ( channel == null )
            {
                return;
            }

            channel.IsBeingDestroyed = true;

            List< EPersistenceID > members = channel.Members.ToList();
            members.Apply( player_id => Remove_From_Channel( player_id, channel_id, ELeftChannelReason.Channel_Shutdown, EPersistenceID.Invalid ) );

            m_Channels.Remove( channel_id );
            m_ChannelInternalNames.Remove( channel.InternalName.ToUpper() );
        }
        private void Remove_Channel( EChannelID channel_id )
        {
            CClientChatChannel channel = Get_Channel_By_Channel_ID( channel_id );
            if ( channel == null )
            {
                return;
            }

            if ( channel.ChannelNumber != EClientChannelNumber.Invalid )
            {
                m_ChannelsByNumber.Remove( channel.ChannelNumber );
            }

            m_ChannelsByName.Remove( channel.ChannelName.ToUpper() );
            m_Channels.Remove( channel_id );
        }
 private CClientChatChannel Get_Channel_By_Channel_ID( EChannelID channel_id )
 {
     CClientChatChannel channel = null;
     m_Channels.TryGetValue( channel_id, out channel );
     return channel;
 }
        private void Add_Client_Channel( EChannelID channel_id, string channel_name, bool announce_join_leave )
        {
            EClientChannelNumber channel_number = Allocate_Channel_Number();
            CClientChatChannel channel = new CClientChatChannel( channel_id, channel_name, channel_number, announce_join_leave );
            Add_Channel( channel );

            CClientResource.Output_Text( EClientTextID.Client_Chat_Channel_Joined, Build_Channel_Name_Display_String( channel_name, channel_number ) );
        }
 // Methods
 // Public interface
 public void Add_Channel( EChannelID channel_id )
 {
     m_Channels.Add( channel_id );
 }
 public void Remove_Channel( EChannelID channel_id )
 {
     m_Channels.Remove( channel_id );
 }
 // Construction
 public CRemoveFromChatChannelServerMessage( EPersistenceID player_id, EChannelID channel_id )
     : base()
 {
     PlayerID = player_id;
     ChannelID = channel_id;
 }
 private void Remove_Channel_From_Player( EPersistenceID player_id, EChannelID channel_id )
 {
     CChatPlayer player = Get_Player_By_Persistence_ID( player_id );
     if ( player != null )
     {
         player.Remove_Channel( channel_id );
     }
 }
        private bool Remove_From_Channel( EPersistenceID player_id, EChannelID channel_id, ELeftChannelReason reason, EPersistenceID source_player_id )
        {
            CServerChatChannel channel = Get_Channel_By_Channel_ID( channel_id );
            if ( channel == null )
            {
                Send_Message_To_Player( new CLeaveChatChannelFailureMessage( ELeaveChatChannelFailureReason.Unknown_Channel ), player_id );
                return false;
            }

            if ( reason == ELeftChannelReason.Self_Request && channel.IsMembershipClientLocked )
            {
                Send_Message_To_Player( new CLeaveChatChannelFailureMessage( ELeaveChatChannelFailureReason.Not_Allowed ), player_id );
                return false;
            }

            if ( !channel.Leave_Channel( player_id ) )
            {
                Send_Message_To_Player( new CLeaveChatChannelFailureMessage( ELeaveChatChannelFailureReason.Not_A_Member ), player_id );
                return false;
            }

            if ( reason != ELeftChannelReason.Channel_Shutdown )
            {
                Send_Notification_To_Channel( channel_id, source_player_id, player_id, Compute_Notification_From_Leave_Reason( reason ), player_id );
            }

            if ( channel.Update_Moderator() && reason != ELeftChannelReason.Channel_Shutdown )
            {
                Send_Notification_To_Channel( channel.ID, channel.Moderator, EChatNotification.New_Moderator, EPersistenceID.Invalid );
            }

            Remove_Channel_From_Player( player_id, channel_id );
            Send_Message_To_Player( new CLeftChatChannelMessage( channel_id, reason, Get_Player_Name_By_Persistence_ID( source_player_id ) ), player_id );

            if ( channel.MemberCount == 0 && channel.ShouldDestroyWhenEmpty && !channel.IsBeingDestroyed )
            {
                Request_Destroy_Channel( channel.ID );
            }

            return true;
        }
 public static void Player_Join_Lobby_Channel( EPersistenceID player_id, ELobbyID lobby_id, EChannelID channel_id )
 {
     Change_System_Channel( player_id,
                                   channel_id,
                                   EChannelGameProperties.OrdinarySingletonMask,
                                   delegate( CResponseMessage response ) {
                                         On_Lobby_Chat_Channel_Join_Response( player_id, lobby_id, response as CJoinChatChannelResponseServerMessage );
                                   } );
 }
        private EChannelJoinError Request_Join_Channel( EPersistenceID player_id, EChannelID channel_id, EChannelGameProperties remove_mask )
        {
            Remove_Player_From_Channels( player_id, remove_mask );

            CServerChatChannel channel = Get_Channel_By_Channel_ID( channel_id );
            if ( channel == null )
            {
                return EChannelJoinError.ChannelDoesNotExist;
            }

            EChannelJoinError error = channel.Join_Channel( player_id );
            if ( error == EChannelJoinError.None )
            {
                channel.Update_Moderator();
                Add_Channel_To_Player( player_id, channel_id );

                CJoinChatChannelResultMessage result_msg = new CJoinChatChannelResultMessage();
                result_msg.ChannelID = channel_id;
                result_msg.ChannelName = channel.ExternalName;
                result_msg.AnnounceJoinLeave = channel.ShouldAnnounceJoinLeave;

                channel.Members.Apply( n => result_msg.Add_Member( n ) );
                channel.Gagged.Apply( n => result_msg.Add_Gagged( n ) );

                Send_Notification_To_Channel( channel_id, player_id, EChatNotification.Player_Joined_Channel, player_id );

                if ( channel.Update_Moderator() )
                {
                    Send_Notification_To_Channel( channel.ID, channel.Moderator, EChatNotification.New_Moderator, EPersistenceID.Invalid );
                }

                result_msg.Moderator = channel.Moderator;
                Send_Message_To_Player( result_msg, player_id );
            }

            return error;
        }
        // Helper
        private static void Change_System_Channel( EPersistenceID player_id, EChannelID new_channel_id, EChannelGameProperties remove_mask, DRequestResponseHandler response_handler )
        {
            CJoinChatChannelRequestServerMessage change_request = new CJoinChatChannelRequestServerMessage( player_id, new_channel_id, remove_mask );
            change_request.Handler = response_handler;

            CServerMessageRouter.Send_Message_To_Chat_Server( change_request );
        }
 public static void Join_Match_Channel( EMatchInstanceID match_id, EPersistenceID player_id, EChannelID match_channel_id )
 {
     Change_System_Channel( player_id,
                                   match_channel_id,
                                   EChannelGameProperties.OrdinarySingletonMask,
                                   delegate( CResponseMessage response ) {
                                         On_Match_Chat_Channel_Join_Response( match_id, player_id, response as CJoinChatChannelResponseServerMessage );
                                   } );
 }
 // Methods
 // Public interface
 public void Initialize_Chat_Channel( EChannelID channel_id )
 {
     ChatChannel = channel_id;
 }
        private void Send_Notification_To_Channel( EChannelID channel_id, EPersistenceID source_player_id, EPersistenceID target_player_id, EChatNotification chat_event, EPersistenceID skip_id )
        {
            string source_player_name = Get_Player_Name_By_Persistence_ID( source_player_id );
            string target_player_name = Get_Player_Name_By_Persistence_ID( target_player_id );

            CChatClientNotificationMessage notification_message = new CChatClientNotificationMessage( channel_id, target_player_name, target_player_id, chat_event, source_player_name );
            Send_Message_To_Channel( channel_id, notification_message, skip_id );
        }
        private EChannelBroadcastError Broadcast_To_Channel( EPersistenceID player_id, EChannelID channel_id, string chat_message )
        {
            CChatPlayer player = Get_Player_By_Persistence_ID( player_id );
            if ( player == null )
            {
                return EChannelBroadcastError.None;
            }

            CServerChatChannel channel = Get_Channel_By_Channel_ID( channel_id );
            if ( channel == null )
            {
                return EChannelBroadcastError.UnknownChannel;
            }

            EChannelBroadcastError error = channel.Check_Broadcast_Status( player_id );
            if ( error != EChannelBroadcastError.None )
            {
                return error;
            }

            CPlayerChatMessage chat_msg = new CPlayerChatMessage( channel_id, player.Name, chat_message );
            channel.Members.Where( member_id => !Is_Ignoring_Player( member_id, player_id ) ).Apply( pid => Send_Message_To_Player( chat_msg, pid ) );

            return EChannelBroadcastError.None;
        }
 // Construction
 public CChatModOperationMessage( EChannelID channel_id, EChatModOperation operation, string player_name )
     : base()
 {
     ChannelID = channel_id;
     Operation = operation;
     PlayerName = player_name;
 }
        private CServerChatChannel Get_Channel_By_Channel_ID( EChannelID channel_id )
        {
            CServerChatChannel channel = null;
            if ( !m_Channels.TryGetValue( channel_id, out channel ) )
            {
                return null;
            }

            return channel;
        }
 // Construction
 public CLeftChatChannelMessage( EChannelID channel_id, ELeftChannelReason reason, string source_name )
     : base()
 {
     ChannelID = channel_id;
     Reason = reason;
     SourceName = source_name;
 }
        private string Get_Channel_Name_By_Channel_ID( EChannelID channel_id )
        {
            CServerChatChannel channel = Get_Channel_By_Channel_ID( channel_id );
            if ( channel != null )
            {
                return channel.InternalName;
            }

            return "Uknown Channel";
        }
 // Construction
 public CBroadcastToChatChannelMessage( EChannelID channel_id, string chat_message )
     : base()
 {
     ChannelID = channel_id;
     ChatMessage = chat_message;
 }
 // Construction
 public CDestroyChatChannelServerMessage( EChannelID channel_id )
     : base()
 {
     ChannelID = channel_id;
 }