패킷 자동화(1)

RuuNee
|2023. 7. 14. 09:04
반응형

무엇을 자동화 할 것인가?

1. 프로토 버프 파일을 만들기 위해 batch 파일을 실행하는 부분.

2. 생성된 파일을 프로젝트로 가져오는 부분.

3. 프로토 버프에서 만든 프로토콜 구조체마다 아이디를 부여하고 
    그에 맞춰 1:1 대응을 시켜서 함수를 직접 만들어 주던 부분.

4. 패킷의 아이디에 맞춰 switch-case로 실행시키던 부분.

이번에는 우선 1번과 2번까지만 작업하고 3번과 4번을 위한 밑작업까지만 진행할 것이다.

 


우선 기존에 있던 프로토 파일들을 사용 용도별로 구별해서 새로 만들어 주자.

(프로토 파일도 서로간의 참조가 가능)

 

그런 다음 배치 파일 코드도 아래와 같이 수정해주자.

이렇게 해줌으로서 배치파일을 실행하면 프로토 코드들이 알아서 우리가 지정한 경로에 복사되게 된다.

 

마지막으로 빌드 이벤트를 설정해서 빌드 할 때마다 배치파일이 실행되도록 해주자.

 

 

위와 같이 하면 빌드를 할 때마다 배치파일이 실행되게 된다. 

하지만 코드상으로 아무런 변화가 없을 경우에는 빌드 이벤트가 실행되지 않는다.

그리고 만약 우리가 패킷을 수정해야 해서 프로토 파일을 수정하고 빌드하더라도 우리의 프로젝트는 이를 인지하지 못하고 빌드에 포함하지 않는다.

그래서 이를 해결하기 위해서는 vcxproj 파일을 아래와 같이 수정해주면 된다.

 

 


ServerPacketHandler.h

#pragma once

#include "Protocol.pb.h"

using PacketHandlerFunc = std::function<bool(PacketSessionRef&, BYTE*, int32)>;
extern PacketHandlerFunc GPacketHandler[UINT16_MAX];

//TODO : 자동화
enum : uint16
{
	PKT_S_TEST = 1,
	PKT_S_LOGIN = 2,
};

//TODO : 선언하는 부분까지 자동화
//Custom Handlers
bool Handle_INVALID(PacketSessionRef& session, BYTE* buffer, int32 len);
bool Handle_S_TEST(PacketSessionRef& session, Protocol::S_TEST& pkt);

class ServerPacketHandler
{
public:

	//TODO : 자동화
	static void Init()
	{
		for (int32 i = 0; i < UINT16_MAX; i++)
			GPacketHandler[i] = Handle_INVALID;
	
		GPacketHandler[PKT_S_TEST] = [](PacketSessionRef& session, BYTE* buffer, int32 len) {return HandlePacket<Protocol::S_TEST>(Handle_S_TEST, session, buffer, len); };
	}

	static bool HandlePacket(PacketSessionRef& session, BYTE* buffer, int32 len)
	{
		PacketHeader* header = reinterpret_cast<PacketHeader*>(buffer);
		return GPacketHandler[header->id](session, buffer, len);
	}

	//TODO : 자동화
	static SendBufferRef MakeSendBuffer(Protocol::S_TEST& pkt) { return _MakeSendBuffer(pkt, PKT_S_TEST); }

private:
	template<typename PacketType, typename ProcessFunc>
	static bool HandlePacket(ProcessFunc func, PacketSessionRef& session, BYTE* buffer, int32 len)
	{
		PacketType pkt;

		if(pkt.ParseFromArray(buffer+sizeof(PacketHeader), len-sizeof(PacketHeader))== false)
			return false;

		return func(session,pkt);
	}

 

메모리를 조금 낭비하더라도 속도가 빠른 배열을 통해 패킷을 핸들링 하였다.

 

 

ServerPacketHandler.cpp

#include "pch.h"
#include "ServerPacketHandler.h"

PacketHandlerFunc GPacketHandler[UINT16_MAX];

//자동화 하지 않고 컨텐츠 작업자가 직접 제작해야 함.
bool Handle_INVALID(PacketSessionRef& session, BYTE* buffer, int32 len)
{
	PacketHeader* header = reinterpret_cast<PacketHeader*>(buffer);
	//TODO : Log
	return false;
}

bool Handle_S_TEST(PacketSessionRef& session, Protocol::S_TEST& pkt)
{
	//TODO

	return false;
}
반응형

'패킷 직렬화' 카테고리의 다른 글

패킷 자동화(2)  (0) 2023.09.25
패킷 직렬화(3)  (0) 2023.06.09
패킷직렬화(2)  (0) 2023.05.27
패킷 직렬화 (1)  (0) 2023.05.19
Unicode  (0) 2023.05.12