Game 클래스

이 클래스는 게임의 메인 루프와 초기화를 담당합니다.

Game::Game()
{
    // 생성자: 게임 초기화 수행. 여기서는 별도의 작업 없음.
}

Game::~Game()
{
    // 게임 종료 시 자원 정리
    GET_SINGLE(SceneManager)->Clear();
    GET_SINGLE(ResourceManager)->Clear();

    _CrtDumpMemoryLeaks(); // 메모리 누수 확인
}

주요 메서드

  • Init: 게임 자원을 초기화합니다.
    • DirectX에서 사용하는 DC(Device Context) 및 더블 버퍼링 설정.
    • 싱글톤 매니저 초기화:
      • TimeManager, InputManager, SceneManager, ResourceManager, SoundManager, NetworkManager.
    • SceneManager를 통해 초기 씬을 DevScene으로 설정.
    • NetworkManager 초기화는 서버와의 연결 설정.
void Game::Update()
{
    // 각 매니저 업데이트 호출
    GET_SINGLE(TimeManager)->Update();
    GET_SINGLE(InputManager)->Update();
    GET_SINGLE(SceneManager)->Update();
    GET_SINGLE(NetworkManager)->Update(); // 서버 통신 처리
}
  • Update: 각 매니저의 프레임 단위 업데이트.
    • NetworkManager는 서버와의 통신을 처리.

NetworkManager 클래스

이 클래스는 클라이언트-서버 간 통신을 관리합니다.

Init 메서드

void NetworkManager::Init()
{
    SocketUtils::Init(); // 소켓 라이브러리 초기화

    _service = make_shared<ClientService>(
        NetAddress(L"127.0.0.1", 7777), // 서버 주소 및 포트
        make_shared<IocpCore>(),       // IOCP 객체
        [=]() { return CreateSession(); }, // 세션 생성 콜백
        1 // 워커 스레드 수
    );

    assert(_service->Start()); // 서비스 시작
}
  1. IOCP 기반 비동기 통신:

    • IocpCore 객체는 IOCP의 핵심으로, 비동기 작업의 완료를 관리.
    • 클라이언트는 NetAddress와 연결된 서버와 통신.
  2. 멀티스레딩:

    • IOCP는 다중 워커 스레드를 지원.
    • 코드의 주석 처리된 부분에서는 5개의 워커 스레드를 생성하려는 시도를 보여줌.

Update 메서드

void NetworkManager::Update()
{
    _service->GetIocpCore()->Dispatch(0);
}
  • Dispatch: IOCP에서 완료된 작업을 처리.
  • 여기서는 블록하지 않음(0).

CreateSession

ServerSessionRef NetworkManager::CreateSession()
{
    return _session = make_shared<ServerSession>();
}
  • 새로운 ServerSession 객체를 생성하여 클라이언트-서버 세션 관리.

SendPacket

void NetworkManager::SendPacket(SendBufferRef sendBuffer)
{
    if (_session)
        _session->Send(sendBuffer); // 패킷 전송
}
  • 서버로 패킷을 보냄. 연결된 세션이 없으면 아무 작업도 수행하지 않음.

ClientPacketHandler

클라이언트에서 수신한 패킷을 처리하고, 서버로 전송할 패킷을 생성.

주요 메서드

  • HandlePacket:
    • 패킷의 헤더를 읽고, ID에 따라 적절한 핸들러 호출.
void ClientPacketHandler::HandlePacket(ServerSessionRef session, BYTE* buffer, int32 len)
{
    BufferReader br(buffer, len);

    PacketHeader header;
    br >> header;

    switch (header.id)
    {
    case S_EnterGame:
        Handle_S_EnterGame(session, buffer, len);
        break;
    case S_MyPlayer:
        Handle_S_MyPlayer(session, buffer, len);
        break;
    // ...
    }
}
  • Handle_S_EnterGame:
    • 서버에서 보낸 게임 입장 응답 처리.
void ClientPacketHandler::Handle_S_EnterGame(ServerSessionRef session, BYTE* buffer, int32 len)
{
    PacketHeader* header = (PacketHeader*)buffer;
    uint16 size = header->size;

    Protocol::S_EnterGame pkt;
    pkt.ParseFromArray(&header[1], size - sizeof(PacketHeader));

    bool success = pkt.success();
    uint64 accountId = pkt.accountid();

    // 성공 여부 및 계정 ID를 기반으로 게임 초기화
}
  • Make_C_Move:
    • 이동 패킷 생성 및 전송.
SendBufferRef ClientPacketHandler::Make_C_Move()
{
    Protocol::C_Move pkt;

    MyPlayer* myPlayer = GET_SINGLE(SceneManager)->GetMyPlayer();

    *pkt.mutable_info() = myPlayer->info;

    return MakeSendBuffer(pkt, C_Move);
}

ServerSession

클라이언트의 서버와의 통신 세션을 관리.

주요 메서드

  • OnConnected:

    • 서버에 성공적으로 연결되었을 때 호출.
  • OnRecvPacket:

    • 클라이언트가 서버에서 받은 데이터를 처리.
virtual void OnRecvPacket(BYTE* buffer, int32 len) override
{
    ClientPacketHandler::HandlePacket(static_pointer_cast<ServerSession>(shared_from_this()), buffer, len);
}
  • OnSend:

    • 데이터 전송 완료 시 호출.
  • OnDisconnected:

    • 서버와의 연결이 끊겼을 때 호출.

사용 기술

  1. IOCP (I/O Completion Port):

    • 비동기 I/O를 관리하는 고성능 네트워크 모델.
    • 다중 워커 스레드를 지원하며, IocpCore가 이를 구현.
  2. 멀티스레딩:

    • 주석 처리된 부분에서는 다중 워커 스레드 사용 가능성을 보여줌.
  3. 패킷 처리:

    • ClientPacketHandler가 클라이언트에서 수신한 패킷을 처리.
    • 패킷 헤더 기반으로 적절한 핸들러 호출.
  4. 더블 버퍼링:

    • Game 클래스에서 화면 깜빡임 방지를 위해 사용.
  5. 싱글톤 패턴:

    • 여러 매니저(SceneManager, ResourceManager 등)는 싱글톤으로 구현.

profile
李家네_공부방

0개의 댓글