This repository has been archived by the owner on May 27, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
toc.c
123 lines (105 loc) · 3.64 KB
/
toc.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#include "libra/dat_container.h"
#include "libra/table_of_contents.h"
static void list_archives(const char* input_file);
static void list_assets(const char* input_file);
static void lookup(const char* input_file, const char* asset_hash_str, u32 group);
static void print_help();
int main(int argc, char** argv) {
if(argc == 3 && strcmp(argv[1], "list_archives") == 0) {
list_archives(argv[2]);
} else if(argc == 3 && strcmp(argv[1], "list_assets") == 0) {
list_assets(argv[2]);
} else if((argc == 4 || argc == 5) && strcmp(argv[1], "lookup") == 0) {
if(argc == 5) {
lookup(argv[2], argv[3], (u32) strtoll(argv[4], NULL, 10));
} else {
lookup(argv[2], argv[3], 0);
}
} else {
print_help();
return 1;
}
}
static void list_archives(const char* input_file) {
RA_Result result;
u8* data;
s64 size;
if((result = RA_file_read(input_file, &data, &size)) != RA_SUCCESS) {
fprintf(stderr, "Failed to read input file '%s'.\n", input_file);
exit(1);
}
RA_TableOfContents toc;
if((result = RA_toc_parse(&toc, data, (u32) size)) != RA_SUCCESS) {
fprintf(stderr, "Failed to parse TOC file '%s' (%s).\n", input_file, result->message);
exit(1);
}
for(u32 i = 0; i < toc.archive_count; i++) {
RA_TocArchive* archive = &toc.archives[i];
printf("%s\n", archive->data);
}
RA_toc_free(&toc, true);
}
static void list_assets(const char* input_file) {
RA_Result result;
u8* data;
s64 size;
if((result = RA_file_read(input_file, &data, &size)) != RA_SUCCESS) {
fprintf(stderr, "Failed to read input file '%s'.\n", input_file);
exit(1);
}
RA_TableOfContents toc;
if((result = RA_toc_parse(&toc, data, (u32) size)) != RA_SUCCESS) {
fprintf(stderr, "Failed to parse TOC file '%s' (%s).\n", input_file, result->message);
exit(1);
}
printf("Path CRC Offset Size Hdr Ofs Arch Idx Group\n");
printf("======== ====== ==== ======= ======== =====\n");
for(u32 i = 0; i < toc.asset_count; i++) {
RA_TocAsset* asset = &toc.assets[i];
printf("%16" PRIx64 " %8x %8x %8x %8x %8x\n",
asset->path_hash,
asset->metadata.offset,
asset->metadata.size,
asset->metadata.header_offset,
asset->metadata.archive_index,
asset->group);
}
RA_toc_free(&toc, true);
}
static void lookup(const char* input_file, const char* asset_hash_str, u32 group) {
RA_Result result;
u8* data;
s64 size;
if((result = RA_file_read(input_file, &data, &size)) != RA_SUCCESS) {
fprintf(stderr, "Failed to read input file '%s'.\n", input_file);
exit(1);
}
RA_TableOfContents toc;
if((result = RA_toc_parse(&toc, data, (u32) size)) != RA_SUCCESS) {
fprintf(stderr, "Failed to parse TOC file '%s' (%s).\n", input_file, result->message);
exit(1);
}
u64 asset_hash = strtoull(asset_hash_str, NULL, 16);
RA_TocAsset* asset = RA_toc_lookup_asset(toc.assets, toc.asset_count, asset_hash, group);
if(asset) {
printf("Path CRC Offset Size Hdr Ofs Arch Idx Group\n");
printf("======== ====== ==== ======= ======== =====\n");
printf("%16" PRIx64 " %8x %8x %8x %8x %8x\n",
asset->path_hash,
asset->metadata.offset,
asset->metadata.size,
asset->metadata.header_offset,
asset->metadata.archive_index,
asset->group);
} else {
fprintf(stderr, "No asset with that hash.\n");
}
}
static void print_help() {
puts("A utility for working with Insomniac Games Archive TOC files, such as those used by the PC version of Rift Apart.");
puts("");
puts("Commands:");
puts(" list_archives <input file> --- List all the asset archives.");
puts(" list_assets <input file> --- List all the assets.");
puts(" lookup <input file> <asset hash> [group index] --- List an asset by its hash.");
}