Пример #1
0
 //----------------------------------------------------------------------------------------------------
 /// <summary>
 /// 클라이언트 추가
 /// </summary>
 /// <param name="client">클라이언트 객체</param>
 //----------------------------------------------------------------------------------------------------
 public bool AddClient( cClient client )
 {
     if( client != null )
     {
         if( Children.ContainsKey( client.ClientID ) ) return true;
         if( AddChild( client.ClientID, client ) )
         {
             client.Channel = ChannelID;
             return true;
         }
     }
     return false;
 }
Пример #2
0
 //----------------------------------------------------------------------------------------------------
 /// <summary>
 /// 클라이언트 삭제
 /// </summary>
 /// <param name="client">클라이언트 객체</param>
 //----------------------------------------------------------------------------------------------------
 public void RemoveClient( cClient client )
 {
     if( client != null )
     {
         RemoveChild( client.ClientID );
         client.Channel = (byte)cChannel.NULL_ID;
     }
 }
Пример #3
0
        //----------------------------------------------------------------------------------------------------
        /// <summary>
        /// 수신된 데이터를 파싱한다.
        /// 주의 : 이 함수는 상속 받아서 클라이언트마다 각자 프로토콜을 정의해서 사용한다.
        /// </summary>
        /// <param name="client">수신 클라이언트</param>
        /// <param name="data">수신 데이터</param>
        /// <param name="size">수신 데이터 크기</param>
        //----------------------------------------------------------------------------------------------------
        protected virtual void OnRecv( cClient client, byte[] data, int size )
        {
            cBitStream bits = new cBitStream();
            bits.Write( data, 0, size );

            Print( bits.ToString() );

            eOrder	order	= ReadOrder( bits );
            eResult	result	= ReadResult( bits );

            Print( order + " : '"+client.Name+"'" );

            // 파싱
            switch( order )
            {
            case eOrder.OBJECT_UPDATE:
                RecvObjectUpdate( client, result, bits );
                break;
            default:
                Error( client.Name + ":" + order );
                break;
            }
        }
Пример #4
0
        //----------------------------------------------------------------------------------------------------
        /// <summary>
        /// 동기화 오브젝트를 파싱.
        /// </summary>
        /// <param name="client">수신 클라이언트</param>
        /// <param name="result">결과값</param>
        /// <param name="bits">수신 데이터</param>
        //----------------------------------------------------------------------------------------------------
        public void RecvObjectUpdate( cClient client, eResult result, cBitStream bits )
        {
            bool host;
            bits.Read( out host );
            bool cobject;
            bits.Read( out cobject );
            uint object_id;
            bits.Read( out object_id, uint.MaxValue );

            if( cobject )
            {
                cObject value;
                if( m_sync_cobject.TryGetValue( object_id, out value ) )
                {
                    Type ctype = value.GetType();

                    foreach( FieldInfo field in ctype.GetFields(BindingFlags.NonPublic|BindingFlags.Public) )
                    {
                        if( host )
                        {
                            HOSTAttribute attrib=GetHostAttribute( field );
                            if( attrib != null )
                            {
                                object data = field.GetValue(value);
                                bits.Read( field.GetType(), out data, data, attrib.MaxSize, attrib.MaxPoint );
                            }
                        }
                        else
                        {
                            GUESTAttribute attrib=GetGuestAttribute( field );
                            if( attrib != null )
                            {
                                object data = field.GetValue(value);
                                bits.Read( field.GetType(), out data, data, attrib.MaxSize, attrib.MaxPoint );
                            }
                        }
                    }
                }
            }
            else
            {
                cUnityObject value;
                if( cUnityObject.GetInstance( object_id, out value ) )
                {
                    Type ctype = value.GetType();

                    foreach( FieldInfo field in ctype.GetFields(BindingFlags.NonPublic|BindingFlags.Public) )
                    {
                        if( host )
                        {
                            HOSTAttribute attrib=GetHostAttribute( field );
                            if( attrib != null )
                            {
                                object data = field.GetValue(value);
                                bits.Read( field.GetType(), out data, data, attrib.MaxSize, attrib.MaxPoint );
                            }
                        }
                        else
                        {
                            GUESTAttribute attrib=GetGuestAttribute( field );
                            if( attrib != null )
                            {
                                object data = field.GetValue(value);
                                bits.Read( field.GetType(), out data, data, attrib.MaxSize, attrib.MaxPoint );
                            }
                        }
                    }
                }
            }
        }
Пример #5
0
        //----------------------------------------------------------------------------------------------------
        /// <summary>
        /// 어플리케이션 종료.
        /// 주의: 프로그램 종료될때 메인 프로세스에서 호출해줘야 한다.
        /// </summary>
        //----------------------------------------------------------------------------------------------------
        public virtual void OnApplicationQuit()
        {
            if( s_client != null )
            {
                s_client.Disconnect();
                s_client = null;
            }

            if( s_thread_connect!=null )
            {
                s_thread_connect.Abort();
                s_thread_connect = null;
            }
        }
Пример #6
0
 //----------------------------------------------------------------------------------------------------
 /// <summary>
 /// 클라이언트 접속 종료
 /// </summary>
 /// <param name="client"></param>
 //----------------------------------------------------------------------------------------------------
 public void DisconnectClient( cClient client )
 {
     if( client != null )
     {
         OutChannel( client.Channel, client );
         RemoveClient( client.ClientID );
     }
 }
Пример #7
0
 //----------------------------------------------------------------------------------------------------
 /// <summary>
 ///	파티 퇴장.
 /// </summary>
 /// <param name="party_id">파티 아이디.</param>
 /// <param name="client">클라이언트 객체.</param>
 //----------------------------------------------------------------------------------------------------
 public void OutParty( uint party_id, cClient client )
 {
     lock(m_parties)
     {
         cParty party;
         if( m_parties.TryGetValue( party_id, out party ) )
         {
             party.RemoveChild( client.ClientID );
             client.Party = cParty.NULL_ID;
             if( party.Children.Count == 0 )
             {
                 m_parties.Remove( party_id );
             }
             else
             {
                 // 파티장 교체 : 첫번째 유저
                 if( client.Master )
                 {
                     foreach( KeyValuePair<uint,cObject> entry in party.Children )
                     {
                         cClient new_master=(cClient)entry.Value;
                         new_master.Master = true;
                         break;
                     }
                 }
             }
         }
     }
 }
Пример #8
0
 //----------------------------------------------------------------------------------------------------
 /// <summary>
 ///	클라이언트 추가.
 /// </summary>
 /// <param name="id">클라이언트 아이디.</param>
 /// <param name="value">클라이언트 인스턴스.</param>
 //----------------------------------------------------------------------------------------------------
 public void AddClient( uint id, cClient value )
 {
     lock(s_clients)
     {
         s_clients.Add( id, value );
     }
 }
Пример #9
0
        //----------------------------------------------------------------------------------------------------
        /// <summary>
        ///	스테이지 입장.(추가+입장)
        /// </summary>
        /// <param name="stage_id">스테이지 아이디.</param>
        /// <param name="client">클라이언트 객체.</param>
        /// <param name="max_user">스테이지 최대 입장객수.</param>
        /// <returns>파티 아이디</returns>
        //----------------------------------------------------------------------------------------------------
        public uint InStage( uint stage_id, byte max_user, cClient client )
        {
            lock(m_stages)
            {
                // 스테이지가 없으면 생성
                cStage stage=null;
                if( m_stages.TryGetValue( stage_id, out stage )==false )
                {
                    stage = new cStage( stage_id );
                    m_stages.Add( stage_id, stage );
                }

                // 파티중 빈 자리에 먼저 입장한다.
                cParty party=null;
                foreach( KeyValuePair<uint,cObject> entry in stage.Children )
                {
                    party = (cParty)entry.Value;
                    // 파티 입장
                    if( InParty( party.PartyID, client ) )
                    {
                        client.Stage = stage_id;
                        return party.PartyID;
                    }
                }

                // 빈자리가 없으면 새로 파티를 만든다.

                // 파티 생성
                party = AddParty(max_user);
                if( party != null )
                {
                    // 파티 등록
                    if( stage.AddChild( party.PartyID, party ) )
                    {
                        // 파티 입장
                        if( InParty( party.PartyID, client ) )
                        {
                            client.Stage = stage_id;
                            return party.PartyID;
                        }
                    }
                }
            }
            return cParty.NULL_ID;
        }
Пример #10
0
        //----------------------------------------------------------------------------------------------------
        /// <summary>
        ///	채널 퇴장.
        /// </summary>
        /// <param name="channel_id">채널 아이디.</param>
        /// <param name="client">클라이언트 객체.</param>
        //----------------------------------------------------------------------------------------------------
        public void OutChannel( byte channel_id, cClient client )
        {
            // 스테이지 퇴장
            OutStage( client.Stage, client );

            // 채널 퇴장
            lock(m_channels)
            {
                cChannel channel;
                if( m_channels.TryGetValue( channel_id, out channel ) )
                {
                    channel.RemoveClient( client );

                    //-----------------------------------------------
                    // Response
                    cBitStream		bits = new cBitStream();
                    WriteOrder(		bits, cNetwork.eOrder.CHANNEL_OUT );
                    WriteResult(	bits, eResult.SUCCESS );
                    WriteClientId(	bits, client.ClientID );
                    client.Send( bits );
                    SendChannel( channel_id, bits );
                }
            }
        }
Пример #11
0
 //----------------------------------------------------------------------------------------------------
 /// <summary>
 ///	파티 입장.
 /// </summary>
 /// <param name="party_id">파티 아이디.</param>
 /// <param name="client">클라이언트 객체.</param>
 /// <returns>결과</returns>
 //----------------------------------------------------------------------------------------------------
 public bool InParty( uint party_id, cClient client )
 {
     lock(m_parties)
     {
         cParty party;
         if( m_parties.TryGetValue( party_id, out party ) )
         {
             if( party.LockIn==false )
             {
                 if( party.AddChild( client.ClientID, client ) )
                 {
                     int count = party.Children.Count;
                     client.Master = (count==1);
                     client.Party = party_id;
                     if( count >= party.MaxUser )
                     {
                         party.LockIn = true;
                     }
                     return true;
                 }
             }
         }
     }
     return false;
 }
Пример #12
0
 //----------------------------------------------------------------------------------------------------
 /// <summary>
 ///	채널 입장.
 /// </summary>
 /// <param name="channel_id">채널 아이디.</param>
 /// <param name="client">클라이언트 객체.</param>
 /// <returns>결과</returns>
 //----------------------------------------------------------------------------------------------------
 public bool InChannel( byte channel_id, cClient client )
 {
     lock(m_channels)
     {
         cChannel channel;
         if( m_channels.TryGetValue( channel_id, out channel ) )
         {
             return channel.AddClient( client );
         }
     }
     return false;
 }
Пример #13
0
 //----------------------------------------------------------------------------------------------------
 /// <summary>
 ///	클라이언트를 얻어온다.
 /// </summary>
 /// <param name="client_id">클라이언트 아이디.</param>
 /// <param name="value">클라이언트 객체.</param>
 /// <returns>성공 유무.</returns>
 //----------------------------------------------------------------------------------------------------
 public bool GetClient( uint client_id, out cClient value )
 {
     lock(m_clients)
     {
         return m_clients.TryGetValue( client_id, out value );
     }
 }
Пример #14
0
        //----------------------------------------------------------------------------------------------------
        /// <summary>
        /// 데이터 수신 처리
        /// </summary>
        /// <param name="client">cClient 인스턴스</param>
        /// <param name="data">수신 데이터</param>
        /// <param name="size">수신 데이터 크기</param>
        //----------------------------------------------------------------------------------------------------
        void OnRecv( cClient client, byte[] data, int size )
        {
            if( client.UseCryptogram ) data = cCryptogram.Decrypt( data, size, client.DataIV, client.DataKey );

            cBitStream bits = new cBitStream();
            bits.Write( data, 0, size );
            bits.Position = 0;

            cNetwork.eOrder order	= cNetwork.ReadOrder( bits );
            cNetwork.eResult result = cNetwork.ReadResult( bits );

            if( result != cNetwork.eResult.SUCCESS )
            {
                Error( order + " : " + result + " : \n" + bits.ToString() );
            }
            else
            {
                Print( order + " : " + result + " : \n" + bits.ToString() );
            }

            switch( order )
            {
            case cNetwork.eOrder.SERVER_LOGIN:				RecvServerLogin( result, bits );			break;
            case cNetwork.eOrder.SERVER_IN:					RecvServerIn( result, bits );				break;
            case cNetwork.eOrder.SERVER_OUT:				RecvServerOut( result, bits );				break;
            case cNetwork.eOrder.CLIENT_INFO_DEFAULT:		RecvClientInfoDefault( result, bits );		break;
            case cNetwork.eOrder.CHANNEL_LIST:				RecvChannelList( result, bits );			break;
            case cNetwork.eOrder.CHANNEL_IN:				RecvChannelIn( result, bits );				break;
            case cNetwork.eOrder.CHANNEL_OUT:				RecvChannelOut( result, bits );				break;
            case cNetwork.eOrder.CHANNEL_CHAT:				RecvChannelChat( result, bits );			break;
            case cNetwork.eOrder.PARTY_CHAT:				RecvPartyChat( result, bits );				break;
            case cNetwork.eOrder.STAGE_LIST:				RecvStageList( result, bits );				break;
            case cNetwork.eOrder.STAGE_IN_REQUEST:			RecvStageInRequest( result, bits );			break;
            case cNetwork.eOrder.STAGE_IN_ACCEPT:			RecvStageInAccept( result, bits );			break;
            case cNetwork.eOrder.STAGE_USER_IN:				RecvStageUserIn( result, bits );			break;
            case cNetwork.eOrder.STAGE_USER_OUT:			RecvStageUserOut( result, bits );			break;
            case cNetwork.eOrder.STAGE_USER_MOVE:			RecvStageUserMove( result, bits );			break;
            case cNetwork.eOrder.STAGE_USER_ATTACK_MONSTER:	RecvStageUserAttackMonster( result, bits );	break;
            case cNetwork.eOrder.STAGE_USER_SKILL_SELF:		RecvStageUserSkillSelf( result, bits );		break;
            case cNetwork.eOrder.STAGE_USER_SKILL_MONSTER:	RecvStageUserSkillMonster( result, bits );	break;
            case cNetwork.eOrder.STAGE_USER_SKILL_POS:		RecvStageUserSkillPos( result, bits );		break;
            case cNetwork.eOrder.STAGE_USER_DAMAGE:			RecvStageUserDemage( result, bits );		break;
            case cNetwork.eOrder.STAGE_USER_ITEM_USE_SELF:	RecvStageUserItemUseSelf( result, bits );	break;
            case cNetwork.eOrder.STAGE_USER_TRIGGER_ON:		RecvStageUserTriggerOn( result, bits );		break;
            case cNetwork.eOrder.STAGE_MON_IN:				RecvStageMonIn( result, bits );				break;
            case cNetwork.eOrder.STAGE_MON_MOVE:			RecvStageMonMove( result, bits );			break;
            case cNetwork.eOrder.STAGE_MON_ATTACK_USER:		RecvStageMonAttackUser( result, bits );		break;
            case cNetwork.eOrder.STAGE_MON_SKILL_SELF:		RecvStageMonSkillSelf( result, bits );		break;
            case cNetwork.eOrder.STAGE_MON_SKILL_ACTOR:		RecvStageMonSkillUser( result, bits );		break;
            case cNetwork.eOrder.STAGE_MON_SKILL_POS:		RecvStageMonSkillPos( result, bits );		break;
            case cNetwork.eOrder.STAGE_MON_DAMAGE:			RecvStageMonDemage( result, bits );			break;
            case cNetwork.eOrder.STAGE_DATA:				RecvStageData( result, bits );				break;
            default:
                client.Disconnect();
                break;
            }
        }
Пример #15
0
        //----------------------------------------------------------------------------------------------------
        /// <summary>
        ///	스테이지 퇴장.
        /// </summary>
        /// <param name="stage_id">스테이지 아이디.</param>
        /// <param name="client">클라이언트 객체.</param>
        //----------------------------------------------------------------------------------------------------
        public void OutStage( uint stage_id, cClient client )
        {
            lock(m_stages)
            {
                // 스테이지 퇴장
                cStage stage=null;
                if( m_stages.TryGetValue( stage_id, out stage ) )
                {
                    client.Stage = cStage.NULL_ID;
                }

                // 파티 퇴장
                uint party_id = client.Party;
                if( party_id != cParty.NULL_ID )
                {
                    lock(m_parties)
                    {
                        // 파티 퇴장
                        OutParty( party_id, client );

                        // 등록된 파티 제거
                        if( IsParty( party_id )==false )
                        {
                            if( stage != null )
                            {
                                stage.RemoveChild( party_id );
                            }
                        }

                        //-----------------------------------------------
                        // Response
                        cBitStream bits = new cBitStream();
                        WriteOrder(	bits, cNetwork.eOrder.STAGE_USER_OUT );
                        WriteResult( bits, eResult.SUCCESS );
                        WriteClientId( bits, client.ClientID );
                        WriteClientId( bits, GetPartyMaster( party_id ) );
                        client.Send( bits );
                        SendParty( party_id, bits );
                    }
                }
            }
        }
Пример #16
0
 //----------------------------------------------------------------------------------------------------
 /// <summary>
 /// 생성자
 /// </summary>
 //----------------------------------------------------------------------------------------------------
 public cNetConnector( string version, string address, ushort port, ushort recv_buf_size, bool use_cryptogram )
     : base("NC")
 {
     s_version				= version;
     s_server_address		= address;
     s_server_port			= port;
     s_recv_buf_size			= recv_buf_size;
     s_use_cryptogram		= use_cryptogram;
     s_policy_port			= 843;
     s_mutex					= new Mutex(true);
     s_client				= new cClient( cClient.NULL_ID, recv_buf_size, use_cryptogram, DoRecv );
     s_clients				= new Dictionary<uint,cClient>();
     s_channels				= new Dictionary<byte,cChannel>();
     s_stage_party_count		= new Dictionary<uint,ushort>();
     s_thread_connect		= new Thread(ThreadConnect);
     s_thread_connect.Start(this);
 }
Пример #17
0
        //----------------------------------------------------------------------------------------------------
        /// <summary>
        /// 리슨 프로세스
        /// </summary>
        //----------------------------------------------------------------------------------------------------
        protected virtual void DoListen()
        {
            try
            {
                m_listener = new TcpListener( System.Net.IPAddress.Any, m_port );
                m_listener.Start();

                while(true)
                {
                    Print( "WAIT_CLIENT" );
                    cClient client = new cClient( cClient.UniqueID, m_listener.AcceptTcpClient(), RecvBufSize, UseCryptogram, OnRecv );
                    client.Parent = this;
                    Print( "CONNECT : " + client.Address );
                }
            }
            catch( Exception ex )
            {
                Error( ex.Message );
                Log( "error:"+ex );
            }
        }
Пример #18
0
 //----------------------------------------------------------------------------------------------------
 /// <summary>
 ///	클라이언트를 얻어온다.
 /// </summary>
 /// <param name="id">클라이언트 아이디.</param>
 /// <param name="value">클라이언트 객체.</param>
 /// <returns>성공 유무.</returns>
 //----------------------------------------------------------------------------------------------------
 public bool GetClient( uint id, out cClient value )
 {
     lock(s_clients)
     {
         return s_clients.TryGetValue( id, out value );
     }
 }
Пример #19
0
 //----------------------------------------------------------------------------------------------------
 /// <summary>
 /// 클라이언트로 부터 받은 패킷처리
 /// 주의 : 이 함수를 상속받아서 수신 데이터 처리를 요함
 /// </summary>
 /// <param name="client"></param>
 /// <param name="data"></param>
 /// <param name="size"></param>
 protected virtual void OnRecv( cClient client, byte[] data, int size )
 {
 }
Пример #20
0
        //----------------------------------------------------------------------------------------------------
        /// <summary>
        /// 데이터 수신 처리
        /// </summary>
        /// <param name="client">cClient 인스턴스</param>
        /// <param name="data">수신 데이터</param>
        /// <param name="size">수신 데이터 크기</param>
        //----------------------------------------------------------------------------------------------------
        protected void DoRecv( cClient client, byte[] data, int size )
        {
            // 메인쓰래드 작업이 종료될때까지 기다린다.
            s_mutex.WaitOne();

            // 받은 데이터를 처리한다.
            OnRecv( client, data, size );

            // 다른쓰래드로 프로세스를 넘긴다.
            s_mutex.ReleaseMutex();
        }
Пример #21
0
 //----------------------------------------------------------------------------------------------------
 /// <summary>
 ///	클라이언트 추가.
 /// </summary>
 /// <param name="client_id">클라이언트 아이디.</param>
 /// <param name="value">클라이언트 인스턴스.</param>
 //----------------------------------------------------------------------------------------------------
 public void AddClient( uint client_id, cClient value )
 {
     lock(m_clients)
     {
         m_clients.Add( client_id, value );
     }
 }