-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathmain.cpp
More file actions
135 lines (114 loc) · 3.79 KB
/
Copy pathmain.cpp
File metadata and controls
135 lines (114 loc) · 3.79 KB
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
124
125
126
127
128
129
130
131
132
133
134
135
#include <filesystem>
#include <iomanip>
#include <iostream>
#include <libim/io/vfstream.h>
#include <libim/common.h>
#include <libim/io/filestream.h>
#include <libim/log/log.h>
#include <cmdutils/cmdutils.h>
#include <cmdutils/options.h>
#include "config.h"
#define SETW(n, f) std::right << std::setfill(f) << std::setw(n)
#define SET_FINFO_LW(n) SETW(10 + n, '.')
static constexpr auto OPT_OTPUT_DIR ("--output-dir");
static constexpr auto OPT_OTPUT_DIR_SHORT ("-o");
static constexpr auto OPT_VERBOSE ("--verbose");
static constexpr auto OPT_VERBOSE_SHORT ("-v");
static constexpr auto OPT_HELP ("--help");
static constexpr auto OPT_HELP_SHORT ("-h");
using namespace cmdutils;
using namespace gobext;
using namespace libim;
namespace fs = std::filesystem;
void printHelp()
{
std::cout << "Extracts resources from CND file!\n";
std::cout << " Usage: gobext <gob file> [options]" << std::endl << std::endl;
std::cout << "Option Long option Meaning\n";
std::cout << OPT_HELP_SHORT << SETW(18, ' ') << OPT_HELP << SETW(31, ' ') << "Show this message\n";
std::cout << OPT_OTPUT_DIR_SHORT << SETW(24, ' ') << OPT_OTPUT_DIR << SETW(34, ' ') << "Output folder <output dir>\n";
std::cout << OPT_VERBOSE_SHORT << SETW(21, ' ') << OPT_VERBOSE << SETW(25, ' ') << "Verbose output\n";
}
bool extractGob(const VfContainer c, const fs::path& outDir, const bool verbose)
{
try
{
/* Save entries to files */
for(const auto& [filePath, file] : c)
{
std::cout << "Extracting file: " << filePath << std::endl;
/* Set entry file path */
auto outPath = outDir / filePath;
if(!makePath(outPath))
{
printError("Could not make file path %!", outPath);
return false;
}
/* Open output file stream */
OutputFileStream ofs(outPath, /*truncate=*/true);
ofs.write(file);
}
std::cout << (!verbose ? "\n" : "") << "--------------------------\nTotal files extracted: " << c.size() << std::endl << std::endl;
return true;
}
catch (const std::exception& e)
{
printError("An exception was thrown while extracting assets from GOB file: %", e.what());
return false;
}
}
int main(int argc, const char *argv[])
{
gLogLevel = LogLevel::Error;
std::cout << "\nIndiana Jones and The Infernal Machine GOB file extractor v" << kVersion << std::endl;
std::cout << kProgramUrl << std::endl << std::endl;
CmdArgs opt(argc, argv);
if(argc < 2 ||
opt.hasArg(OPT_HELP) ||
opt.hasArg(OPT_HELP_SHORT) ||
opt.positionalArgs().empty())
{
printHelp();
return 1;
}
fs::path inputFile = opt.positionalArgs().at(0);
if(!fileExists(inputFile))
{
printError("File % does not exists!", inputFile);
return 1;
}
fs::path outdir;
if (opt.hasArg(OPT_OTPUT_DIR_SHORT)) {
outdir = opt.arg(OPT_OTPUT_DIR_SHORT);
}
else if (opt.hasArg(OPT_OTPUT_DIR)) {
outdir = opt.arg(OPT_OTPUT_DIR);
}
bool bVerboseOutput = false;
if (opt.hasArg(OPT_VERBOSE_SHORT)) {
bVerboseOutput = true;
}
else if (opt.hasArg(OPT_VERBOSE)) {
bVerboseOutput = true;
}
/* Extract files from gob file */
int result = 0;
try
{
auto vfs = gobLoad(inputFile);
if (outdir == "")
{
outdir /= inputFile.stem().string() + "_GOB";
}
makePath(outdir);
if(!extractGob(vfs, outdir, bVerboseOutput)) {
result = 1;
}
}
catch(const std::exception& e)
{
printError("Failed to read GOB file!\n Error: %", e.what());
result = 1;
}
return result;
}