Skip to content

Commit

Permalink
fix cw compile and dump gametype table
Browse files Browse the repository at this point in the history
  • Loading branch information
ate47 committed Dec 31, 2023
1 parent 6276af1 commit ef78570
Show file tree
Hide file tree
Showing 2 changed files with 203 additions and 21 deletions.
42 changes: 21 additions & 21 deletions src/cli/tools/gsc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -736,30 +736,30 @@ namespace tool::gsc {
};

enum T9GSCExportFlags : UINT8 {
AUTOEXEC = 0x01,
LINKED = 0x02,
PRIVATE = 0x04,
CLASS_MEMBER = 0x08,
CLASS_DESTRUCTOR = 0x10,
VE = 0x20,
EVENT = 0x40,
CLASS_LINKED = 0x80,
CLASS_VTABLE = 0x86
T9_EF_AUTOEXEC = 0x01,
T9_EF_LINKED = 0x02,
T9_EF_PRIVATE = 0x04,
T9_EF_CLASS_MEMBER = 0x08,
T9_EF_CLASS_DESTRUCTOR = 0x10,
T9_EF_VE = 0x20,
T9_EF_EVENT = 0x40,
T9_EF_CLASS_LINKED = 0x80,
T9_EF_CLASS_VTABLE = 0x86
};

enum T9GSCImportFlags : UINT8 {
METHOD_CHILDTHREAD = 0x1,
METHOD_THREAD = 0x2,
FUNCTION_CHILDTHREAD = 0x3,
FUNCTION = 0x4,
FUNC_METHOD = 0x5,
FUNCTION_THREAD = 0x6,
METHOD = 0x7,
CALLTYPE_MASK = 0xF,
DEV_CALL = 0x10,
GET_CALL = 0x20,
UKN40 = 0x40,
UKN80 = 0x80
T9_IF_METHOD_CHILDTHREAD = 0x1,
T9_IF_METHOD_THREAD = 0x2,
T9_IF_FUNCTION_CHILDTHREAD = 0x3,
T9_IF_FUNCTION = 0x4,
T9_IF_FUNC_METHOD = 0x5,
T9_IF_FUNCTION_THREAD = 0x6,
T9_IF_METHOD = 0x7,
T9_IF_CALLTYPE_MASK = 0xF,
T9_IF_DEV_CALL = 0x10,
T9_IF_GET_CALL = 0x20,
T9_IF_UKN40 = 0x40,
T9_IF_UKN80 = 0x80
};

struct T8GSCString {
Expand Down
182 changes: 182 additions & 0 deletions src/cli/tools/pool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,71 @@ struct ScriptBundle {
SB_ObjectsArray sbObjectsArray;
};

enum eModes : INT32 {
MODE_ZOMBIES = 0x0,
MODE_MULTIPLAYER = 0x1,
MODE_CAMPAIGN = 0x2,
MODE_WARZONE = 0x3,
MODE_COUNT = 0x4,
MODE_INVALID = 0x4,
MODE_FIRST = 0x0,
};

const char* EModeName(eModes mode) {
switch (mode) {
case MODE_ZOMBIES: return "zombies";
case MODE_MULTIPLAYER: return "multiplayer";
case MODE_CAMPAIGN: return "campaign";
case MODE_WARZONE: return "warzone";
default: return "<invalid>";
}

}

struct Hash {
uint64_t name;
uint64_t nullpad;
};

struct GameTypeTableEntry {
Hash name;
Hash baseGameType;
uint64_t unk20;
Hash nameRef;
Hash nameRefCaps;
Hash descriptionRef;
Hash unk58;
bool isHardcoreAvailable;
Hash hardcoreNameRef;
bool isTeamBased;
bool hideHudScore;
uint64_t groupName;
uintptr_t image; // GfxImage*
Hash presenceString;
uint64_t unkA8;
uint64_t scoreInfoFile;
uint64_t unkB8;
uint64_t unkC0;
uint64_t unkC8;
uint64_t unkD0;
uint64_t unkD8;
uint64_t unkE0;
uint64_t unkE8;
uint64_t unkF0;
int uniqueID;
uint64_t unk100;
uint64_t unk108;
};

struct GameTypeTable {
UINT64 name;
UINT64 namepad;
UINT32 gameTypeCount;
uintptr_t gameTypes; // GameTypeTableEntry*
eModes sessionMode;
};


struct GametypeEntry {
uintptr_t v1; // 0x8
uintptr_t pad0; // 0x10
Expand Down Expand Up @@ -479,6 +544,15 @@ bool ReadSBObject(const Process& proc, std::ostream& defout, int depth, const SB
return true;
}

const char* ReadTmpStr(const Process& proc, uintptr_t location) {
static CHAR tmp_buff[0x1000];

if (proc.ReadString(tmp_buff, location, sizeof(tmp_buff)) < 0) {
sprintf_s(tmp_buff, "<invalid:%llx>", location);
}
return tmp_buff;
}

int pooltool(const Process& proc, int argc, const char* argv[]) {
using namespace pool;
if (argc < 3) {
Expand Down Expand Up @@ -883,6 +957,114 @@ int pooltool(const Process& proc, int argc, const char* argv[]) {
std::cout << "Dump " << readFile << " new file(s)\n";
}
break;
case ASSET_TYPE_GAMETYPETABLE:
{
hashutils::ReadDefaultFile();
size_t readFile = 0;


auto pool = std::make_unique<GameTypeTable[]>(entry.itemAllocCount);

if (!proc.ReadMemory(&pool[0], entry.pool, sizeof(pool[0]) * entry.itemAllocCount)) {
std::cerr << "Can't read pool data\n";
return tool::BASIC_ERROR;
}
CHAR dumpbuff[MAX_PATH + 10];

for (size_t i = 0; i < entry.itemAllocCount; i++) {
auto& p = pool[i];

auto n = hashutils::ExtractPtr(p.name);

std::cout << std::dec << i << ": ";

if (n) {
std::cout << n;
sprintf_s(dumpbuff, "%s/gametypetable/%s.json", opt.m_output, n);
}
else {
std::cout << "file_" << std::hex << p.name << std::dec;
sprintf_s(dumpbuff, "%s/gametypetable/file_%llx.json", opt.m_output, p.name);
}

if (!p.gameTypes || !proc.ReadMemory<UINT64>(p.gameTypes)) {
std::cerr << "error when reading buffer at " << p.gameTypes << "\n";
continue;
}

std::filesystem::path file(dumpbuff);
std::filesystem::create_directories(file.parent_path(), ec);

std::cout << "->" << file;

if (!std::filesystem::exists(file, ec)) {
readFile++;
std::cout << " (new)";
}

auto entries = std::make_unique<GameTypeTableEntry[]>(p.gameTypeCount);


if (!proc.ReadMemory(&entries[0], p.gameTypes, sizeof(entries[0]) * p.gameTypeCount)) {
std::cerr << "Can't read entries data\n";
break;
}

std::ofstream out{ file };

if (!out) {
std::cerr << "Can't open output file\n";
break;
}

out
<< "{\n"
<< " \"name\": \"" << hashutils::ExtractTmp("hash", p.name) << std::flush << "\",\n"
<< " \"sessionMode\": \"" << EModeName(p.sessionMode) << "\",\n"
<< " \"gametypes\": ["
;

for (size_t j = 0; j < p.gameTypeCount; j++) {
auto& e = entries[j];

if (j) {
out << ",";
}
out
<< "\n"
<< " {\n"
<< " \"uniqueID\": " << std::dec << e.uniqueID << ",\n"
<< " \"name\": \"" << ReadTmpStr(proc, e.name.name) << std::flush << "\",\n"
<< " \"baseGameType\": \"" << ReadTmpStr(proc, e.baseGameType.name) << std::flush << "\",\n"
<< " \"nameRef\": \"#" << hashutils::ExtractTmp("hash", e.nameRef.name) << std::flush << "\",\n"
<< " \"nameRefCaps\": \"#" << hashutils::ExtractTmp("hash", e.nameRefCaps.name) << std::flush << "\",\n"
<< " \"descriptionRef\": \"#" << hashutils::ExtractTmp("hash", e.descriptionRef.name) << std::flush << "\",\n"
<< " \"isHardcoreAvailable\": " << (e.isHardcoreAvailable ? "true" : "false") << ",\n"
<< " \"hardcoreNameRef\": \"#" << hashutils::ExtractTmp("hash", e.hardcoreNameRef.name) << std::flush << "\",\n"
<< " \"isTeamBased\": " << (e.isTeamBased ? "true" : "false") << ",\n"
<< " \"hideHudScore\": " << (e.hideHudScore ? "true" : "false") << ",\n"
<< " \"groupname\": \"" << ReadTmpStr(proc, e.groupName) << "\",\n"
<< " \"presenceString\": \"#" << hashutils::ExtractTmp("hash", e.presenceString.name) << std::flush << "\"\n"
<< " }"
;
}

out
<< "\n"
<< " ]\n"
<< "}"
;

out.close();

std::cout << "\n";

}
std::cout << "Dump " << readFile << " new file(s)\n";


break;
}
case ASSET_TYPE_DDL:
{

Expand Down

0 comments on commit ef78570

Please sign in to comment.