Chunkのアップデートの仕組みについて、よくわからないところがあり、問い合わさせていただきました。
具体的には、SlideShareにアップロードされている以下のスライド資料に関する質問になります。
「徹底解説!UE4を使ったモバイルゲーム開発におけるコンテンツアップデートの極意!」
「Chunkの更新フローの方針」というページにおいて、以下のような記述があります。
「特定のChunkのみ修正したい場合はバージョンを変えずに、Chunkパッケージを作成・差し替え
・変更がないChunkはハッシュ値が変化しないので再ダウンロードは行われない」
この「ハッシュ値を参照したChunk更新」の仕方についてご教示いただきたく、質問させていただきました。
当方の検証により、以下のことを確認しております。
・Chunkをビルドすると、書き出された”CloudDir“ディレクトリ内に、windowsnoeditor.manifestというファイルが作成される。
・その中に、書き出された全てのChunkのハッシュ値が記載されており、Chunkが更新された場合は、その値も更新される。
Blueprint上で“Request Content”ノードを使用して、Chunkのダウンロードを実装していますが、この場合ですと、ハッシュ値が参照されず、ハッシュ値が更新されていようといまいと、Chunkをダウンロードしてしまいます。
windowsnoeditor.manifestのコピーをローカルに保持し、アセットロード時に毎回、サーバ上のものとローカルのものを比較して更新されているかどうかを判断することもできなくはありませんが、正規のやり方ではないように思われます。
ハッシュ値を参照したChunkのアップデートはどのように実装するのが正しいのでしょうか。
Chunk周りにつきましては、web上の情報が非常に限られており、なかなか手がかりを得ることができません。
情報が記載されているwebページ(英語でも可)や、実装のヒント等、ご教示いただけましたら幸いです。
どうぞよろしくお願い申し上げます。
FHttpChunkInstall::ParseTitleFileManifest()内のバージョンアップ検知部分を以下のように変更することでHash違いも検出できるようにすることが可能です。
if ((InstalledVersion != RemoteVersion && bInstallIsPatch == bRemoteIsPatch) || FilesHaveChanged(InstalledManifest, RemoteManifest, ChunkID))
{
...
}
bool FHTTPChunkInstall::FilesHaveChanged(IBuildManifestPtr LocalManifest, IBuildManifestPtr RemoteManifest, int32 InInstallingChunkID)
{
#if (!WITH_EDITORONLY_DATA || IS_PROGRAM)
if (LocalManifest->GetDownloadSize() != RemoteManifest->GetDownloadSize())
{
return true;
}
// same number of files check to see if the file StartBuis out dated
auto ChunkFolderName = FString::Printf(TEXT("%s%d"), TEXT("base"), InInstallingChunkID);
auto ChunkInstallDir = FPaths::Combine(*InstallDir, *ChunkFolderName);
FBuildPatchAppManifestPtr CurrentManifest = StaticCastSharedPtr< FBuildPatchAppManifest >(LocalManifest);
FBuildPatchAppManifestPtr InstallManifest = StaticCastSharedPtr< FBuildPatchAppManifest >(RemoteManifest);
TSet<FString> OutOfDateFiles;
CurrentManifest->GetOutdatedFiles(InstallManifest.ToSharedRef(), ChunkInstallDir, OutOfDateFiles);
return OutOfDateFiles.Num() > 0;
#else
return false;
#endif
}
または、以下の変更でも対応可能です。
bool isHashMatch = true;
TSet<FString> Tags;
auto DonwloadSize = (double)RemoteManifest->GetDeltaDownloadSize(Tags, InstalledManifest.ToSharedRef());
isHashMatch = DonwloadSize == 0;
if (!isHashMatch || (InstalledVersion != RemoteVersion && bInstallIsPatch == bRemoteIsPatch))
ご参考になれば幸いです。