
리슨 서버의 경우 플레이어로서 게임에도 참여하므로, 어플리케이션의 게임 로직을 사용함
어플리케이션의 게임 로직은 서버 액터에 대해서만 게임에 관련된 작업을 수행해야 함
이를 구분하기 위해 현재 동작하는 어플리케이션에서의 역할을 로컬 역할, 커넥션으로 연결된 어플리케이션에서의 역할을 리모트 역할이라 함


신뢰할 수 있는 액터, 즉 Authority를 가진 액터만 게임 로직을 수행할 수 있음
AutonomousProxy는 예외적으로 입력에 관련된 로직을 수행할 수 있음
입력에 관련된 게임 로직의 실행은 Authority와 Autonomous Proxy에서만 허용됨
게임 모드는 HasAuthority() 함수를 호출할 필요가 없음 (서버에만 존재하니)
폰은 Autonomous와 Simulated가 혼재되어 있어 API를 사용하여 로직 구분 필요
애니메이션 재생이나 UI 관련 로직은 클라이언트에만 사용함
(서버는 변경된 속성을 전달하고, 변경된 속성에 따라 애니메이션과 UI를 바꾸도록 설계)
- 클라이언트 접속 로그
LogABNetwork: [SERVER][ROLE_Authority/ROLE_None] AABGameMode::PreLogin Begin LogABNetwork: [SERVER][ROLE_Authority/ROLE_None] AABGameMode::PreLogin End LogABNetwork: [SERVER][ROLE_Authority/ROLE_None] AABGameMode::Login Begin // 클라이언트의 컨트롤러가 생성될 땐 리모트 롤이 없음 LogABNetwork: [SERVER][ROLE_Authority/ROLE_None] AABPlayerController::PostInitializeComponents Begin BP_ABPlayerController_C_1 LogABNetwork: [SERVER][ROLE_Authority/ROLE_None] AABPlayerController::PostInitializeComponents End LogABNetwork: [SERVER][ROLE_Authority/ROLE_None] AABGameMode::Login End LogABNetwork: [SERVER][ROLE_Authority/ROLE_None] AABGameMode::PostLogin Begin // 빙의를 시작하며 리모트 롤이 변경 LogABNetwork: [SERVER][ROLE_Authority/ROLE_AutonomousProxy] AABPlayerController::OnPossess Begin BP_ABPlayerController_C_1 LogABNetwork: [SERVER][ROLE_Authority/ROLE_SimulatedProxy] AABCharacterPlayer::PossessedBy Begin ABCharacterPlayer_1 LogABNetwork: [SERVER][ROLE_Authority/ROLE_SimulatedProxy] AABCharacterPlayer::PossessedBy No Owner // 빙의 과정에서 Owner가 설정되며 Autonomous로 변경 LogABNetwork: [SERVER][ROLE_Authority/ROLE_AutonomousProxy] AABCharacterPlayer::PossessedBy Owner : BP_ABPlayerController_C_1 LogABNetwork: [SERVER][ROLE_Authority/ROLE_AutonomousProxy] AABCharacterPlayer::PossessedBy End ABCharacterPlayer_1 LogABNetwork: [SERVER][ROLE_Authority/ROLE_AutonomousProxy] AABPlayerController::OnPossess End LogABNetwork: [SERVER][ROLE_Authority/ROLE_None] AABGameMode::PostLogin Client Connections : IpConnection_1 LogABNetwork: [SERVER][ROLE_Authority/ROLE_None] AABGameMode::PostLogin End LogABNetwork: [CLIENT1][ROLE_None/ROLE_Authority] AABPlayerController::PostInitializeComponents Begin BP_ABPlayerController_C_0 LogABNetwork: [CLIENT1][ROLE_None/ROLE_Authority] AABPlayerController::PostInitializeComponents End // 서버에서 설정한 정보가 넘어오며 로컬 롤이 변경 LogABNetwork: [CLIENT1][ROLE_AutonomousProxy/ROLE_Authority] AABPlayerController::PostNetInit Begin BP_ABPlayerController_C_0 LogABNetwork: [CLIENT1][ROLE_AutonomousProxy/ROLE_Authority] AABPlayerController::PostNetInit Server Connection : IpConnection_0 LogABNetwork: [CLIENT1][ROLE_AutonomousProxy/ROLE_Authority] AABPlayerController::PostNetInit End LogABNetwork: [CLIENT1][ROLE_AutonomousProxy/ROLE_Authority] AABCharacterPlayer::OnRep_Owner Begin ABCharacterPlayer_0 LogABNetwork: [CLIENT1][ROLE_AutonomousProxy/ROLE_Authority] AABCharacterPlayer::OnRep_Owner End ABCharacterPlayer_0 LogABNetwork: [CLIENT1][ROLE_AutonomousProxy/ROLE_Authority] AABCharacterPlayer::PostNetInit Begin ABCharacterPlayer_0 LogABNetwork: [CLIENT1][ROLE_AutonomousProxy/ROLE_Authority] AABCharacterPlayer::PostNetInit End // 서버 플레이어의 캐릭터는 오너십을 가지고 있지 않아 SimulatedProxy LogABNetwork: [CLIENT1][ROLE_SimulatedProxy/ROLE_Authority] AABCharacterPlayer::PostNetInit Begin ABCharacterPlayer_1 LogABNetwork: [CLIENT1][ROLE_SimulatedProxy/ROLE_Authority] AABCharacterPlayer::PostNetInit End
// Pawn.cpp
bool APawn::IsLocallyControlled() const
{
return ( Controller && Controller->IsLocalController() );
}
// Controller.cpp
bool AController::IsLocalController() const
{
const ENetMode NetMode = GetNetMode();
if (NetMode == NM_Standalone)
{
// Not networked.
return true;
}
// 클라이언트의 경우엔 AutonomousProxy여야함
if (NetMode == NM_Client && GetLocalRole() == ROLE_AutonomousProxy)
{
// Networked client in control.
return true;
}
// 서버가 플레이어로 참여하면 로컬 롤은 당연히 Authority
// 리모트 롤은 남한테 권한을 줄 필요가 없으니 SimulatedProxy로 동작
if (GetRemoteRole() != ROLE_AutonomousProxy && GetLocalRole() == ROLE_Authority)
{
// Local authority in control.
return true;
}
return false;
}
네트워크로 접속하는 두 컴퓨터가 잘 연결되었는지 확인하는 과정

커넥션을 허용하면 게임을 시작할 수 있도록 클라이언트와 서버는 준비 과정을 거침

용도에 따라 패킷을 처리하는 다양한 NetDriver 클래스를 제공함
언리얼 엔진은 게임 데이터를 처리하는 게임넷드라이버로 IpNetDriver를 사용함
초기 접속에 관련된 데이터 패킷은 ControlChannel을 통해 분석됨
언리얼 엔진에서 번치를 처리하는데 사용하는 주요 채널
- Bunch 정보
// message type definitions DEFINE_CONTROL_CHANNEL_MESSAGE(Hello, 0, uint8, uint32, FString, uint16); // initial client connection message DEFINE_CONTROL_CHANNEL_MESSAGE(Welcome, 1, FString, FString, FString); // server tells client they're ok'ed to load the server's level DEFINE_CONTROL_CHANNEL_MESSAGE(Upgrade, 2, uint32, uint16); // server tells client their version is incompatible DEFINE_CONTROL_CHANNEL_MESSAGE(Challenge, 3, FString); // server sends client challenge string to verify integrity DEFINE_CONTROL_CHANNEL_MESSAGE(Netspeed, 4, int32); // client sends requested transfer rate DEFINE_CONTROL_CHANNEL_MESSAGE(Login, 5, FString, FString, FUniqueNetIdRepl, FString); // client requests to be admitted to the game DEFINE_CONTROL_CHANNEL_MESSAGE(Failure, 6, FString); // indicates connection failure DEFINE_CONTROL_CHANNEL_MESSAGE(Join, 9); // final join request (spawns PlayerController) DEFINE_CONTROL_CHANNEL_MESSAGE(JoinSplit, 10, FString, FUniqueNetIdRepl); // child player (splitscreen) join request DEFINE_CONTROL_CHANNEL_MESSAGE(Skip, 12, FGuid); // client request to skip an optional package DEFINE_CONTROL_CHANNEL_MESSAGE(Abort, 13, FGuid); // client informs server that it aborted a not-yet-verified package due to an UNLOAD request DEFINE_CONTROL_CHANNEL_MESSAGE(PCSwap, 15, int32); // client tells server it has completed a swap of its Connection->Actor DEFINE_CONTROL_CHANNEL_MESSAGE(ActorChannelFailure, 16, int32); // client tells server that it failed to open an Actor channel sent by the server (e.g. couldn't serialize Actor archetype) DEFINE_CONTROL_CHANNEL_MESSAGE(DebugText, 17, FString); // debug text sent to all clients or to server DEFINE_CONTROL_CHANNEL_MESSAGE(NetGUIDAssign, 18, FNetworkGUID, FString); // Explicit NetworkGUID assignment. This is rare and only happens if a netguid is only serialized client->server (this msg goes server->client to tell client what ID to use in that case) DEFINE_CONTROL_CHANNEL_MESSAGE(SecurityViolation, 19, FString); // server tells client that it has violated security and has been disconnected DEFINE_CONTROL_CHANNEL_MESSAGE(GameSpecific, 20, uint8, FString); // custom game-specific message routed to UGameInstance for processing DEFINE_CONTROL_CHANNEL_MESSAGE(EncryptionAck, 21); DEFINE_CONTROL_CHANNEL_MESSAGE(DestructionInfo, 22); DEFINE_CONTROL_CHANNEL_MESSAGE(CloseReason, 23, FString); // Reason for client NetConnection Close, for analytics/logging DEFINE_CONTROL_CHANNEL_MESSAGE(NetPing, 24, ENetPingControlMessage /* MessageType */, FString /* MessageStr */);
https://github.com/dnjfs/ArenaBattle_Network/commit/7caff5f6a2d0de3157ae53357f8ec9e23e406351