카테고리 없음

완성 코드 분석 - 서버 / UI(2)

anna59 2026. 7. 23. 20:58

 

저번에 코드 분석을 너무 세세하게 작성하느라 시간이 많이 소요되어서, 이번에는 이해한 흐름은 간단하게 기록하고 넘어가려고 한다.

 

지난번에 이어서 FindServers() 함수의 흐름을 분석할 것이다.

 

전체 흐름

IOnlineSessionPtr SessionInterface 헤더에 정의

-> SessionInterface에 FindSessionCompleteDelegate를 등록. 서치가 완료되면 신호를 받게 구현함.

-> SessionSearch의 쿼리를 통해 검색 기준 설정

TSharedPtr<FOnlineSessionSearch> SessionSearch

->서치 쿼리 설정완료 

->SessionInterface의 FindSessions 호출, bFindStarted에 서치가 시작되었음을 저장함

(FindSession을 실패했을때에 대비하여 방어코드 추가)

 

 

이후 서버 찾기가 완료되고 나면 FindSessionsCompleteDelegate를 통해 신호가 전달된다.

GameInstance에서 해당 델리게이트는 다음과 같이 바인딩 되어있다.

 

FindSessionsCompleteDelegate 
	= FOnFindSessionsCompleteDelegate::CreateUObject(this, &ThisClass::OnFindSessionsComplete);

 

OnFindSessionsComplete()

흐름

1. SessionInterface가 유효하다면 델리게이트 바인딩을 해제한다.

2. 세션 찾기 실패 시 return (방어코드)

3. 발견된 방 개수 FoundCount에 저장

int32 FoundCount = SessionSearch->SearchResults.Num();

4. 스팀 닉네임 저장

FString MySteamName;

	if (ULocalPlayer* LocalPlayer = GetFirstGamePlayer())
	{
		MySteamName = LocalPlayer->GetNickname();
	}

 

5. 발견된 방을 순회하면서 방이 유효한지 판단

6. 유효한 방의 MapName을 받아옴

const bool bHasMapName =
		Result.Session.SessionSettings.Get(SETTING_MAPNAME, MapName);
Result.Session.SessionSettings.Get(SETTING_MAPNAME, MapName);

 

7. 내가 연 세션은 제외

if (!MySteamName.IsEmpty() &&
    Result.Session.OwningUserName == MySteamName)
{
    UE_LOG(LogTemp, Warning,
       TEXT("[%d] Skip My Session"),
       i);
    continue;
}

 

8. 맵 내에 빈자리가 있는지 체크

9. 세션 정보가 유효한지 체크 

10. bFoundValidSession 를 true로 설정, TargetSessionIndex = i(지금 확인한 인덱스); 

11. bFoundValideSession이 true -> JoinServer(TargetSessionIndex), false -> CreateServer()

 

 

JoinServer와 CreateServer 살펴보기

JoinServer(int32 SessionIndex)

1.  bUseLobbiesIfAvailable = bUsePresence;

SearchResult.Session.SessionSettings.bUseLobbiesIfAvailable =
	SessionResult.Session.SessionSettings.bUsePresence;

 

Steam JoinSession은 두 값이 같아야함.

 

2. Join Delegate 등록 해제 후 재등록 (이전 Join 기록때문에 꼬이지 않게 하기 위함)

3. SessionInterface의 JoinSession 함수 호출->리턴값으로 Join 성공 여부 받아서 저장

4. bJoinResult가 false일 경우 JoinSessionCompleteDelegate 등록 해제.

 

이렇게까지 하면 방을 찾고 접속하는 흐름이 완성된다.

 

 

CreateServer

1. 기존에 남아있는 서버가 있다면 파괴

// 해당 플레이어의 NetId 가져오기
FUniqueNetIdRepl PreferredNetId = LocalPlayer->GetPreferredUniqueNetId();

 

2. 만들 세션의 세팅 설정

3. CreateSessionCompleteDelegate 등록

4. 세션 만들기

const bool bCreateStarted = 
	SessionInterface->CreateSession(*PreferredNetId, NAME_GameSession, SessionSettings);

 

5. 세션이 만들어지지 않으면 bReturnTOMainMenuAfterDestroy = false; (무사히 세션이 파괴되지 않았다는 뜻)

CreateSessionCompleteDelegate도 등록 해제

 

여기까지 하면 방을 만들고, 존재하는 방에 참가하는 로직 분석 완료.