Skip to content

Commit

Permalink
Add TFC support for Smite
Browse files Browse the repository at this point in the history
  • Loading branch information
yretenai committed Jun 8, 2022
1 parent c444911 commit fc617e5
Show file tree
Hide file tree
Showing 10 changed files with 468 additions and 1 deletion.
2 changes: 1 addition & 1 deletion UmodelTool/umodel.project
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,4 @@ sources(MAIN) = {
!message NO EXE_NAME
!endif

target(executable, $EXE_NAME, MAIN + COMP_LIBS + UE4_LIBS + IMG_LIBS + NV_LIBS + MOBILE_LIBS, MAIN)
target(executable, $EXE_NAME, MAIN + COMP_LIBS + UE4_LIBS + IMG_LIBS + NV_LIBS + MOBILE_LIBS + MD5_LIBS, MAIN)
15 changes: 15 additions & 0 deletions Unreal/FileSystem/GameFileSystem.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "Core.h"
#include "UnCore.h"
#include "GameFileSystem.h"
#include "GameFileSystemSmite.h"

#include "UnArchiveObb.h"
#include "UnArchivePak.h"
Expand Down Expand Up @@ -816,6 +817,20 @@ void appSetRootDirectory(const char *dir, bool recurse)
}
#endif // GEARS4

#if SMITE
if(GForceGame == GAME_Smite) {
const CGameFileInfo* manifest = CGameFileInfo::Find("MergedFileIndexCache.bin");
if (manifest)
{
LoadSmiteManifest(manifest);
}
else
{
appNotify("Smite: missing MergedFileIndexCache.bin file.");
}
}
#endif

appPrintf("Found %d game files (%d skipped) in %d folders at path \"%s\"\n", GameFiles.Num(), GNumForeignFiles, GameFolders.Num() ? GameFolders.Num()-1 : 0, dir);

#if UNREAL4
Expand Down
67 changes: 67 additions & 0 deletions Unreal/FileSystem/GameFileSystemSmite.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#include "Core.h"
#include "UnCore.h"
#include "GameFileSystem.h"
#include "GameFileSystemSmite.h"

#if SMITE
static FSmiteManifest* GSmiteManifest = NULL;

void LoadSmiteManifest(const CGameFileInfo* info) {
guard(LoadSmiteManifest);

appPrintf("Loading Smite manifest %s...\n", *info->GetRelativeName());

FArchive* loader = info->CreateReader();
assert(loader);
loader->Game = GAME_Smite;
if(GSmiteManifest != nullptr) {
delete GSmiteManifest;
}
GSmiteManifest = new FSmiteManifest;
GSmiteManifest->Serialize(*loader);
delete loader;

unguard
}


FArchive* GetSmiteBlob(const FGuid& guid, int level, const char* ext) {
guard(GetSmiteBlob);

if(GSmiteManifest == nullptr) {
return nullptr;
}

TArray<FSmiteFile>* item = GSmiteManifest->Files.Find(guid);
if(item == nullptr) {
return nullptr;
}

int i;
for(i = 0; i < item->Num(); i++) {
FSmiteFile* entry = item->GetData() + i;
if(entry->tier == level) {
FString* bulk = GSmiteManifest->BulkFiles.Find(entry->guid);
char filename[512];
appSprintf(ARRAY_ARG(filename), "%s.%s", bulk->GetDataArray().GetData(), ext);
const CGameFileInfo* info = CGameFileInfo::Find(filename);
if(info == nullptr) {
return nullptr;
}

FArchive* Ar = info->CreateReader();
Ar->Game = GAME_Smite;
Ar->Seek(entry->offset);
byte *data = (byte*)appMalloc(entry->blob_size);
Ar->Serialize(data, entry->blob_size);
delete Ar;
Ar = new FMemReader(data, entry->blob_size);
Ar->Game = GAME_Smite;
return Ar;
}
}
unguard

return nullptr;
}
#endif // SMITE
34 changes: 34 additions & 0 deletions Unreal/FileSystem/GameFileSystemSmite.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#include "Core.h"
#include "UnCore.h"

#if SMITE
struct FSmiteFile {
int32 tier;
int32 size;
int32 offset;
int32 blob_size;
FGuid guid;

friend FArchive& operator<<(FArchive &Ar, FSmiteFile &H)
{
return Ar << H.tier << H.size << H.offset << H.blob_size << H.guid;
}
};

struct FSmiteManifest
{
TMap<FGuid, TArray<FSmiteFile>> Files;
TMap<FGuid, FString> BulkFiles;

void Serialize(FArchive& Ar)
{
Ar << Files;
Ar << BulkFiles;
}
};

void LoadSmiteManifest(const CGameFileInfo* info);

FArchive* GetSmiteBlob(const FGuid& guid, int level, const char* ext);

#endif // SMITE
12 changes: 12 additions & 0 deletions Unreal/UnCore.h
Original file line number Diff line number Diff line change
Expand Up @@ -1027,6 +1027,13 @@ class FMemReader : public FArchive
return DataSize;
}

void Free() {
appFree((void*)DataPtr);
DataPtr = nullptr;
DataSize = 0;
ArPos = 0;
}

protected:
const byte *DataPtr;
int DataSize;
Expand Down Expand Up @@ -2555,6 +2562,11 @@ void appReadCompressedChunk(FArchive &Ar, byte *Buffer, int Size, int Compressio
#define BULKDATA_SeparateData 0x40 // unknown name - bulk stored in a different place in the same file
#define BULKDATA_CompressedLzx 0x80 // unknown name

#if SMITE
#define BULKDATA_Unkn 0x100 // ??? on mip 1+ if in tfc
#define BULKDATA_CompressedOodle_SMITE 0x200 // oodle
#endif

#if BLADENSOUL
#define BULKDATA_CompressedLzoEncr 0x100 // encrypted LZO
#endif
Expand Down
77 changes: 77 additions & 0 deletions Unreal/UnrealMaterial/UnTexture3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -643,6 +643,76 @@ static int GetRealTextureOffset_MH(const UTexture2D *Obj, int MipIndex)

#endif // MARVEL_HEROES

#if SMITE
#include <md5/md5.h>
#include "../FileSystem/GameFileSystemSmite.h"
#include "../UnrealPackage/UnPackageUE3Reader.h"

static bool LoadBulkTextureSMITE(const UTexture2D* texture, const TArray<FTexture2DMipMap> &MipsArray, int MipIndex, bool verbose) {
static char buf[2048];
texture->GetFullName(ARRAY_ARG(buf), true, true, true); char *s = buf;
int len = 0;
if(verbose) {
appPrintf("Smite: Finding %s (Mip %d) in MergedFileIndexCache\n", buf, MipIndex);
}
while (*s) {
*s = toupper((unsigned char) *s);
len++;
s++;
}
MD5Context ctx;
md5Init(&ctx);
md5Update(&ctx, (unsigned char*)buf, len);
md5Finalize(&ctx);

const FTexture2DMipMap &Mip = MipsArray[MipIndex];
FArchive* Ar = GetSmiteBlob(*reinterpret_cast<FGuid*>(ctx.digest), MipIndex, "tfc");
if(Ar == NULL) {
appPrintf("Smite: unable to find %s (Mip %d) in MergedFileIndexCache\n", buf, MipIndex);
return false;
}
FArchive* free = Ar;

FCompressedChunkHeader H;
*Ar << H;
TArray<FCompressedChunk> Chunks;
FCompressedChunk *Chunk = new (Chunks) FCompressedChunk;
Chunk->UncompressedOffset = 0;
Chunk->UncompressedSize = H.Sum.UncompressedSize;
Chunk->CompressedOffset = 0;
Chunk->CompressedSize = H.Sum.CompressedSize;
FByteBulkData *Bulk = const_cast<FByteBulkData*>(&Mip.Data);
int flags = 0;
if (Bulk->BulkDataFlags & BULKDATA_CompressedOodle_SMITE) flags = COMPRESS_OODLE;
else if (Bulk->BulkDataFlags & BULKDATA_CompressedZlib) flags = COMPRESS_ZLIB;
else if (Bulk->BulkDataFlags & BULKDATA_CompressedLzo) flags = COMPRESS_LZO;
else if (Bulk->BulkDataFlags & BULKDATA_CompressedLzx) flags = COMPRESS_LZX;

if(flags > 0) {
FUE3ArchiveReader* UE3Loader = new FUE3ArchiveReader(Ar, flags, Chunks);
UE3Loader->IsFullyCompressed = true;
Ar = UE3Loader;
}

if (verbose)
{
appPrintf("Reading %s mip level %d (%dx%d) from TFC\n", texture->Name, MipIndex, Mip.SizeX, Mip.SizeY);
}

Bulk->BulkDataSizeOnDisk = H.Sum.UncompressedSize;
Bulk->ElementCount = H.Sum.UncompressedSize;
Bulk->BulkDataOffsetInFile = 0;
int backup = Bulk->BulkDataFlags;
Bulk->BulkDataFlags = 0; // wipe compression flags temporarily
Bulk->SerializeData(*Ar);
Bulk->BulkDataFlags = backup;

reinterpret_cast<FMemReader*>(free)->Free();
delete Ar;
return true;
}
#endif // SMITE


bool UTexture2D::LoadBulkTexture(const TArray<FTexture2DMipMap> &MipsArray, int MipIndex, const char* tfcSuffix, bool verbose) const
{
Expand All @@ -656,6 +726,13 @@ bool UTexture2D::LoadBulkTexture(const TArray<FTexture2DMipMap> &MipsArray, int
FStaticString<MAX_PACKAGE_PATH> bulkFileName;
if (TextureFileCacheName != "None")
{
#if SMITE
if(GForceGame == GAME_Smite) {
if(LoadBulkTextureSMITE(this, MipsArray, MipIndex, verbose)) {
return true;
}
}
#endif
// TFC file is assigned
bulkFileName = *TextureFileCacheName;

Expand Down
4 changes: 4 additions & 0 deletions common.project
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,10 @@ sources(UE4_LIBS) = {
$R/libs/rijndael/*.c
}

LIBINCLUDES += $R/libs/md5
sources(MD5_LIBS) = {
$R/libs/md5/*.c
}

#------------------------------------------------
# Project-specific options
Expand Down
1 change: 1 addition & 0 deletions libs/md5/SOURCE
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
https://github.com/Zunawe/md5-c
Loading

0 comments on commit fc617e5

Please sign in to comment.