Mongoose MixedType 도큐먼트가 저장 혹은 업데이트가 안될 때..

Mongoose에서 Document.Save()를 이용할 때, Mixed Type인 데이터가 save가 안된다.

이 때, Document.markModified()를 이용하면 제대로 저장이 된다.

1.PNG

참고

http://mongoosejs.com/docs/api.html#document_Document-markModified

Advertisements

Windows 10 Bash 설치(Insider Preview 14393)

이번에 프로젝트가 끝나 포멧을 진행 했다.

그 동안 Tensorflow때문에 Windows bash와 Ubuntu를 번갈아 사용해왔는데

이번에도 Windows Bash 설치를 진행 했고, 그 과정을 남겨 본다.

먼저 Windows Update에서 개발자용 탭 – 개발자 모드를 선택한다.(개발자 참여?가 안되어 있으면 알아서 페이지가 뜬다)

그 다음 업데이트 탭에서 고급 옵션을 누르면 아래와 같이 Insider preview를 받을 수 있는 설정이 나온다. insider2.PNG

예전과는 다르게 분기를 선택할 수 있었고 RE_PRERELEASE를 선택하였더니 현재 최신 버전인 14393버전이 나왔다.

이렇게 설정을 해두고 몇시간 기다리면…  아래와 같이 업데이트가 진행 된다. 옛날에는 3~4시간 걸렷는데, 이번에는 하루가 지나서야 시작 됬다.insider.PNG

다 설치가 되면 재부팅 두어번 정도 해준 뒤 프로그램 추가 제거에서 Windows 기능 추가 제거를 눌러 아래와 같이 Linux용 Windows 하위 시스템(베타)를 선택한다.

insider3.PNG

설치가 끝나면, 윈도우 검색에서 Bash를 검색하여 실행을 하고 약관 동의같은걸 하면 Ubuntu가 설치가 된다.

끝.

파일 업데이트 시스템 만들기

개요

개발중인 프로젝트에서 클라이언트 업데이트 시스템이 필요해졌다.
업데이트 되는 파일만 새롭게 받게 한다면 편할 테지만 큰 파일의 용량은 600MB가 넘었고, 서버에 차지하는 용량과 트래픽도 부담이 되었다.

그리하여 이전 버전과 새로운 버전의 Binary data 차이점(Patch file)만을 추출 하여 이를 서버에 업로드 하고, 유저는 해당 Patch file 만을 받아 이전 버전의 파일 + 받은 Patch file 을 이용하여 새로운 버전의 파일을 생성 해내는 방식으로 업데이트 시스템을 만들기로 하였다.

처음부터 Binary를 비교하여 Chunk를 만들려고 했으나 자료 조사 중 RTPatch, bsdiff, MSDelta 를 찾아내었는데, 그중 bsdiff 를 사용하기로 했다.

http://www.daemonology.net/bsdiff/

( MSDelta는 Microsoft에서 제공하는 API 인데, Vista 부터 사용이 가능하다고 하여 패스)

과정

패치 파일을 생성하는 순서는 다음과 같다.

이전 버전의 클라이언트 폴더 이름 : A
새로운 버전의 클라이언트 폴더 이름 : B

  1. A 폴더 내부에 있는 파일과 B 폴더 내부에 있는 파일이 동일한 파일인지 확인.
  2. 동일하지 않다면, bsdiff를 이용하여 패치 파일 생성.
  3. 생성된 패치 파일을 bzip을 이용하여 최대 레벨로 압축.
  4. 압축된 패치 파일을 MD5 값과 함께 서버의 업로드.

A 폴더와 B 폴더의 모든 파일을 위 과정을 거쳐서 패치 파일들을 생성 한후 MD5 값과 함께 서버의 업로드를 하면 된다.

패치 파일을 적용하는 순서는 다음과 같다.

  1. 업데이트 프로그램에서 현재 파일들의 버전을 확인 후 알맞는 패치 파일을 서버로 요청하여 내려 받는다.
  2. 내려받은 패치 파일이 유효한지 MD5 값을 비교 한다.
  3. bzip을 이용하여 압축을 해제 한다.
  4. 이전 버전의 파일과 패치 파일을 bsdiff를 이용하여 합친다.
  5. 새롭게 생성된 파일의 MD5값을 서버로 부터 요청 받아 패치가 제대로 이루어 졌는지 확인 한다.

퍼포먼스

위 과정대로 코딩 후, 테스트(cpu I7-2700K)를 해보았다.

가장 용량이 큰 600MB 파일의 경우 diff 하는데 5분 ~ 10분 정도의 시간이 걸린다.
병렬 처리가 아니기 때문에 좀 걸린다.

하지만 patch를 할때는 5초 내외의 시간이 걸리므로, 유저 입장에서는 충분히 사용할만 하다고 생각 된다.

단점

단점으로는 diff를 할 때, 메모리를 좀 많이 사용한다. 때문에 32bit에서는 diff를 할 수가 없다(메모리 할당 초과 – 2GB 이상 할당이 어렵다)

마무리

한번 패치 파일을 생성하는데 총 15분 정도의 시간이 소요 되고 메모리를 많이 사용하지만 개발 환경의 램은 빵빵 하며, 자주 패치 파일을 생성하는 것이 아니기 때문에 넘어갈만 하다.
또한, 클라이언트에서 패치를 할 때는 전혀 문제가 없고, 서버의 용량이나 트래픽을 고려하는 것이 초기 목표이므로…

잘 사용하기로 했다.

UE4, OnlineSubsystemFacebook(iOS) 사용하기.

HumanDevil 프로젝트는 Facebook 계정을 연동하여 플레이 할 수 있다.

Android 같은 경우에는 다운받은 FacebookSDK.jar을 추가하여 직접 사용하였지만,

iOS나 Window같은 경우에는 OnlineSubsystem으로 Facebook이 제공이 된다.

 

필요한 Module이름은 OnlineSubsystemFacebook이며 아래와 같이 Project.Build.cs에 추가하면 된다.

if ( Target.Platform == UnrealTargetPlatform.IOS )
{
PrivateDependencyModuleNames.Add("OnlineSubsystemFacebook");
}

 

그 다음 필요한 것은 Config/DefaultEngine.ini 파일을 수정하는 것이다.

OnlineSubsystemFacebook 코드 내부에는 아래와 같은 코드가 있으며,

GConfig->GetBool( 
TEXT("OnlineSubsystemFacebook"), 
TEXT("bEnabled"), 
bEnableFacebook, 
GEngineIni);

bEnableFacebook 값이 false이면, OnlineSubsystemFacebook이 생성되지 않는다.

Config/DefaultEngine.ini 파일에 아래의 코드를 넣어준다.

[OnlineSubsystemFacebook]
bEnabled=true

그 다음으로 해야할 것은 .plist 파일을 수정하는 것인데, 이것은 빌드시에 매번 자동으로 생성이 되는것 이다.
우리가 필요한 정보를 넣기 위해선 에디터에서 추가하거나 직접 Config 파일에 추가하는 것인데,
에디터에서는 IOS 설정에서 Extra Plist Data에 필요한 데이터들을 추가하면 된다.
필요한 데이터는 Facebook Developer 사이트를 참고하면 된다.

<key>FacebookAppID</key>	
<string>정보</string>	
<key>FacebookDisplayName</key>	
<string>정보</string>	
<key>CFBundleURLTypes</key>	
<array>
	<dict>		
	<key>CFBundleURLSchemes</key>	
		<array>	
			<string>정보</string>
		</array>
	</dict>	
</array>

이제 Facebook을 사용할곳에서 OnlineSubsystemFacebook.h를 포함한 후에 코드를 작성 하면된다.

간단히 Login 하는 방법을 나열하자면,
1. IOnlineSubsystem::Get(TEXT(“Facebook”)); 이와 같은 방법으로 OnlineSubsystem을 가져온다.
2. 가져온 시스템에서 GetIdentityInterface()를 이용하여 IdentityInterface를 얻어온 후, Login()를 호출하면 된다.
3. Login이 되던, 실패하던 어떠한 이벤트를 전달 받으려면 델리게이트를 추가해줘야 한다.

AddOnLoginCompleteDelegate_Handle(
0,
FOnLoginCompleteDelegate::CreateUObject(
this, 
&Class::Function));

이와 같이 추가한 후, 전달받은 정보를 통하여 로직을 구성하면 된다.