문자열(string, wsring)은 어떻게 보낼까?
char snedData[1000] = "가";
char snedData[1000] = u8"가";
WCHAR snedData[1000] = L"가";
TCHAR snedData[1000] = _T("가");
// 모두 메모리공간을 읽어보면 다르게 나오는데 무슨차일까?
// 서버와 클라를 어떻게 맞춰야할까?
- UNICODE & ENCODING 
- 문자(Character)
 - 문자 집합(Character Set) Vs 인코딩(Encoding)
 - CP949 Vs UTF-8 Vs UTF-16
 - MBCS(Multi Byte Character Set) Vs WBCS(Wide Byte Character Set)
 
 
문자(Character)
처음은 ASCII Code(문자집합)로 문자를 표현 (Ex> A == 0x41(65))
 서로 다른 문자집합을 사용할 경우 문제가 발생함.
 공통된 문자집합을 써보자 -> UNICODE 탄생
그런데 영어만 주로 쓰는 환경에서 UNICODE는 보통 2바이트를 쓰는데 이게 과연 효율적인가??
 그래서 나온게 ENCODING! -> 만약 영어만 쓴다면 UTF-8로 ENCODING을 해줄께!
 제일 앞 비트를 0으로 두면 UTF-8이라 가정한다(Ex> 0xxxxxxx)
 만약 한글이라면 3바이트를 쓰고(1110xxxx 10xxxxxx 10xxxxxx) 이렇게 들어가 있으면 UTF-8 한글
그런데 한글은 꽤 널리 쓰이는데 3바이트나 쓰자고?? -> UTF-16의 탄생
 UTF-16은 거의 Unicode를 그대로 쓴다
그럼 CP949는 뭔가? -> 문자 집합 2개를 동시에 사용함(KS-X-1003, KS-X-1001) MS(마소)에서 주로사용된다.
- MBCS(Multi Byte Character Set) : (char) 개별 문자를 다수의 바이트로 표현
 - WBCS(Wide Byte Character Set) : (wchar) 유니코드 기반의 character set(UTF-16)
 
char snedData[1000] = "가";         // CP949 (한글2바이트, 로마자1바이트)
char snedData[1000] = u8"가";       // UTF8 (Unicode)
WCHAR snedData[1000] = L"가";       // UTF16 (Unicode)
TCHAR snedData[1000] = _T("가");
#include "pch.h"
#include "ThreadManager.h"
#include "Service.h"
#include "Session.h"
#include "GameSession.h"
#include "GameSessionManager.h"
#include "BufferWriter.h"
#include "ServerPacketHandler.h"
#include <tchar.h>
int main()
{
	ServerServiceRef service = MakeShared<ServerService>(
		NetAddress(L"127.0.0.1", 7777),
		MakeShared<IocpCore>(),
		MakeShared<GameSession>, // TODO : SessionManager 등
		100);
	ASSERT_CRASH(service->Start());
	for (int32 i = 0; i < 5; i++)
	{
		GThreadManager->Launch([=]()
			{
				while (true)
				{
					service->GetIocpCore()->Dispatch();
				}				
			});
	}	
	WCHAR sendData3[1000] = L"가"; // UTF16 = Unicode (한글/로마 2바이트)
	while (true)
	{
		vector<BuffData> buffs{ BuffData {100, 1.5f}, BuffData{200, 2.3f}, BuffData {300, 0.7f } };
		SendBufferRef sendBuffer = ServerPacketHandler::Make_S_TEST(1001, 100, 10, buffs, L"안녕하세요");
		GSessionManager.Broadcast(sendBuffer);
		this_thread::sleep_for(250ms);
	}
	GThreadManager->Join();
}
class ServerPacketHandler
{
public:
	static void HandlePacket(BYTE* buffer, int32 len);
	static SendBufferRef Make_S_TEST(uint64 id, uint32 hp, uint16 attack, vector<BuffData> buffs, wstring name);
    // wstring name을 보냄을 주목
};
SendBufferRef ServerPacketHandler::Make_S_TEST(uint64 id, uint32 hp, uint16 attack, vector<BuffData> buffs, wstring name)
{
	SendBufferRef sendBuffer = GSendBufferManager->Open(4096);
	BufferWriter bw(sendBuffer->Buffer(), sendBuffer->AllocSize());
	PacketHeader* header = bw.Reserve<PacketHeader>();
	// id(uint64), 체력(uint32), 공격력(uint16)
	bw << id << hp << attack;
	// 가변 데이터
	bw << (uint16)buffs.size();
	for (BuffData& buff : buffs)
	{
		bw << buff.buffId << buff.remainTime;
	}
	bw << (uint16)name.size();
	bw.Write((void*)name.data(), name.size() * sizeof(WCHAR));
	header->size = bw.WriteSize();
	header->id = S_TEST; // 1 : Test Msg
	sendBuffer->Close(bw.WriteSize());
	return sendBuffer;
}
void ClientPacketHandler::Handle_S_TEST(BYTE* buffer, int32 len)
{
	BufferReader br(buffer, len);
	PacketHeader header;
	br >> header;
	uint64 id;
	uint32 hp;
	uint16 attack;
	br >> id >> hp >> attack;
	cout << "ID: " << id << " HP : " << hp << " ATT : " << attack << endl;
	vector<BuffData> buffs;
	uint16 buffCount;
	br >> buffCount;
	buffs.resize(buffCount);
	for (int32 i = 0; i < buffCount; i++)
	{
		br >> buffs[i].buffId >> buffs[i].remainTime;
	}
	cout << "BufCount : " << buffCount << endl;
	for (int32 i = 0; i < buffCount; i++)
	{
		cout << "BufInfo : " << buffs[i].buffId << " " << buffs[i].remainTime << endl;
	}
	wstring name;
	uint16 nameLen;
	br >> nameLen;
	name.resize(nameLen);
	br.Read((void*)name.data(), nameLen * sizeof(WCHAR));
	wcout.imbue(std::locale("kor"));
	wcout << name << endl;
}