Skip to content

Commit

Permalink
better vararg decomp/comp t10, remove hash.cpp
Browse files Browse the repository at this point in the history
  • Loading branch information
ate47 committed Nov 4, 2024
1 parent d944448 commit 9923503
Show file tree
Hide file tree
Showing 14 changed files with 215 additions and 99 deletions.
16 changes: 16 additions & 0 deletions src/acts/compiler/gsc_compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5616,6 +5616,22 @@ namespace acts::compiler {
return nullptr;
}

if (obj.gscHandler->HasFlag(tool::gsc::GOHF_VAR_VA_COUNT)) {
std::string paramIdfCount = "varargcount";
if (exp.m_params == 256) {
obj.info.PrintLineMessage(alogs::LVL_ERROR, param, std::format("Can't register param '{}': too many params", paramIdfCount));
return nullptr;
}
exp.m_params++;

auto [err, vardef] = exp.RegisterVar(paramIdfCount, false);
if (err) {
obj.info.PrintLineMessage(alogs::LVL_ERROR, param, err);
return nullptr;
}
}


continue;
}

Expand Down
3 changes: 3 additions & 0 deletions src/acts/hashutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,14 +191,17 @@ namespace hashutils {
Add("system", true, iw, true);
Add("scripts/core_common/system_shared.csc", true, iw, true);
Add("scripts/core_common/system_shared.gsc", true, iw, true);
Add("scripts/common/system.gsc", true, iw, true);
Add("register", true, iw, true);
Add("__init__system__", true, iw, true);
Add("__init__", true, iw, true);
Add("__main__", true, iw, true);
Add("main", true, iw, true);
Add("init", true, iw, true);
// it seems all the varargs are called "vararg", but a flag is also describing, so idk
// in t10 the vararg param is followed by varargcount
Add("vararg", true, iw, true);
Add("varargcount", true, iw, true);

// basic letter
char buff[2] = { 0, 0 };
Expand Down
4 changes: 2 additions & 2 deletions src/acts/hashutils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
#include <hash.hpp>

namespace hashutils {
constexpr uint64_t MASK62 = 0xFFFFFFFFFFFFFFFull;
constexpr uint64_t MASK63 = 0x7FFFFFFFFFFFFFFFull;
constexpr uint64_t MASK62 = hash::MASK62;
constexpr uint64_t MASK63 = hash::MASK63;
constexpr auto DEFAULT_HASH_FILE = "strings.txt";

/*
Expand Down
66 changes: 63 additions & 3 deletions src/acts/tools/gsc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ enum DumpVTableAnswer : int {
GscInfoOption::GscInfoOption() {
// set default formatter
m_formatter = &tool::gsc::formatter::GetFromName();
}

bool tool::gsc::GscDecompilerGlobalContext::WarningType(GscDecompilerGlobalContextWarn warn) {
core::async::opt_lock_guard lg{ asyncMtx };
if ((warningOpt & warn)) return false;
warningOpt |= warn;
return true;
}

bool GscInfoOption::Compute(const char** args, INT startIndex, INT endIndex) {
Expand Down Expand Up @@ -111,6 +118,9 @@ bool GscInfoOption::Compute(const char** args, INT startIndex, INT endIndex) {
else if (!_strcmpi("--vtable", arg)) {
m_vtable = true;
}
else if (!_strcmpi("--debug-hashes", arg)) {
m_debugHashes = true;
}
else if (!_strcmpi("--vtable-dump", arg)) {
if (i + 1 == endIndex) {
LOG_ERROR("Missing value for param: {}!", arg);
Expand Down Expand Up @@ -355,6 +365,7 @@ void GscInfoOption::PrintHelp() {
LOG_DEBUG("--ignore-dbg-plt : ignore debug platform info");
LOG_DEBUG("-A --sync [mode] : Sync mode: async or sync");
LOG_DEBUG("--vtable : Do not hide and decompile vtable functions");
LOG_DEBUG("--debug-hashes : Debug hash alogrithm");
LOG_DEBUG("-i --ignore[t + ] : ignore step : ");
LOG_DEBUG(" a : all, d: devblocks, s : switch, e : foreach, w : while, i : if, f : for, r : return");
LOG_DEBUG(" R : bool return, c: class members, D: devblocks inline, S : special patterns");
Expand Down Expand Up @@ -1182,6 +1193,16 @@ int GscInfoHandleData(byte* data, size_t size, const char* path, GscDecompilerGl

char asmfnamebuff[1000];

const char* extractedName{ hashutils::ExtractPtr(scriptfile->GetName()) };

if (opt.m_debugHashes && extractedName) {
uint64_t hashPath{ vmInfo->HashPath(extractedName) };

if (hashPath != scriptfile->GetName() && gdctx.WarningType(GDGCW_BAD_HASH_PATH)) {
LOG_WARNING("Invalid hash algorithm for extracted name 0x{:x} != 0x{:x} for {}", scriptfile->GetName(), hashPath, extractedName);
}
}

if (opt.m_outputDir) {
const char* name = opt.m_noPath ? nullptr : hashutils::ExtractPtr(scriptfile->GetName());

Expand Down Expand Up @@ -1462,6 +1483,17 @@ int GscInfoHandleData(byte* data, size_t size, const char* path, GscDecompilerGl

for (size_t i = 0; i < scriptfile->GetIncludesCount(); i++) {
asmout << "#using " << hashutils::ExtractTmpScript(includes[i]) << ";\n";

if (opt.m_debugHashes) {
const char* incExt{ hashutils::ExtractPtr(includes[i]) };
if (incExt) {
uint64_t hashPath{ vmInfo->HashPath(incExt) };

if (hashPath != includes[i] && gdctx.WarningType(GDGCW_BAD_HASH_PATH_INCLUDE)) {
LOG_WARNING("Invalid hash alogithm for extracted include 0x{:x} != 0x{:x} for {}", includes[i], hashPath, incExt);
}
}
}
}
if (scriptfile->GetIncludesCount()) {
asmout << "\n";
Expand Down Expand Up @@ -1717,6 +1749,31 @@ int GscInfoHandleData(byte* data, size_t size, const char* path, GscDecompilerGl

auto& asmctx = r.first->second;


if (opt.m_debugHashes) {
uint64_t name{ exp->GetName() };
const char* namePtr{ hashutils::ExtractPtr(name) };
if (namePtr) {
uint64_t hashScr{ vmInfo->HashField(namePtr) };

if (hashScr != name && gdctx.WarningType(GDGCW_BAD_HASH_FIELD)) {
LOG_WARNING("Invalid hash algorithm for extracted field 0x{:x} != 0x{:x} for {}", name, hashScr, namePtr);
}
}
uint64_t fileNameSpace{ exp->GetFileNamespace() };
if (fileNameSpace) {

const char* fnsPtr{ hashutils::ExtractPtr(fileNameSpace) };
if (fnsPtr) {
uint64_t hashFSScr{ vmInfo->HashFilePath(fnsPtr) };

if (hashFSScr != fileNameSpace && gdctx.WarningType(GDGCW_BAD_HASH_FILE)) {
LOG_WARNING("Invalid hash algorithm for extracted field 0x{:x} != 0x{:x} for {}", fileNameSpace, hashFSScr, fnsPtr);
}
}
}
}

DumpFunctionHeader(*exp, output, *scriptfile, ctx, asmctx);

if (asmctx.m_opt.m_formatter->flags & tool::gsc::formatter::FFL_NEWLINE_AFTER_BLOCK_START) {
Expand Down Expand Up @@ -3072,13 +3129,16 @@ void tool::gsc::DumpFunctionHeader(GSCExportReader& exp, std::ostream& asmout, G
}

for (size_t i = 0; i < exp.GetParamCount(); i++) {
// -1 to avoid the <empty> object, -1 because we are in reverse order
const auto& lvar = ctx.m_localvars[ctx.m_localvars.size() - i - 2];

if ((lvar.flags & T8GSCLocalVarFlag::IW_VARIADIC_COUNT) && !lvar.defaultValueNode) {
continue; // ignore if the varargcount is used
}
if (i) {
asmout << ", ";
}

// -1 to avoid the <empty> object, -1 because we are in reverse order
const auto& lvar = ctx.m_localvars[ctx.m_localvars.size() - i - 2];

if (lvar.flags & T8GSCLocalVarFlag::VARIADIC) {
asmout << "...";
}
Expand Down
15 changes: 14 additions & 1 deletion src/acts/tools/gsc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ namespace tool::gsc {
GOHF_STRING_NAMES = 0x2000,
GOHF_NOTIFY_CRC_STRING = 0x4000,
GOHF_FILENAMESPACE = 0x8000,
GOHF_VAR_VA_COUNT = 0x10000,
};
static_assert(
((GOHF_FOREACH_TYPE_T8 | GOHF_FOREACH_TYPE_T9 | GOHF_FOREACH_TYPE_JUP | GOHF_FOREACH_TYPE_T7
Expand Down Expand Up @@ -95,6 +96,7 @@ namespace tool::gsc {
bool m_ignoreDebugPlatform{};
bool m_sync{ true };
bool m_vtable{};
bool m_debugHashes{};
const char* vtable_dump{};
uint32_t m_stepskip{};
opcode::Platform m_platform{ opcode::Platform::PLATFORM_PC };
Expand Down Expand Up @@ -267,7 +269,8 @@ namespace tool::gsc {
enum T8GSCLocalVarFlag : uint8_t {
ARRAY_REF = 0x01,
VARIADIC = 0x02,
T9_VAR_REF = 0x04 // T9
T9_VAR_REF = 0x04, // T9
IW_VARIADIC_COUNT = 0x80, // Special value
};

class OPCodeInfo {
Expand Down Expand Up @@ -733,9 +736,17 @@ namespace tool::gsc {
std::unordered_set<NameLocated, NameLocatedHash, NameLocatedEquals> m_vtableMethods{};
std::unordered_map<uint64_t, asmcontext_func> m_vtable{};
};
enum GscDecompilerGlobalContextWarn : uint64_t {
GDGCW_BAD_HASH_PATH = 1,
GDGCW_BAD_HASH_FIELD = 1 << 1,
GDGCW_BAD_HASH_FILE = 1 << 2,
GDGCW_BAD_HASH_PATH_INCLUDE = 1 << 3,
};

struct GscDecompilerGlobalContext {
std::mutex* asyncMtx{};
GscInfoOption opt{};
uint64_t warningOpt{};
std::unordered_map<uint64_t, tool::gsc::gdb::ACTS_GSC_GDB*> debugObjects{};
size_t decompiledFiles{};
std::unordered_map<uint64_t, std::unordered_map<uint64_t, std::unordered_set<NameLocated, NameLocatedHash, NameLocatedEquals>>> vtables{};
Expand All @@ -745,6 +756,8 @@ namespace tool::gsc {
delete d;
}
}

bool WarningType(GscDecompilerGlobalContextWarn warn);
};
// Result context for T8GSCOBJ::PatchCode
class T8GSCOBJContext {
Expand Down
18 changes: 15 additions & 3 deletions src/acts/tools/gsc_opcodes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ uint64_t VmInfo::HashPath(const char* value) const {
if (hash::TryHashPattern(value, t)) {
return t;
}
if (HasFlag(VmFlags::VMF_HASH_CER) || HasFlag(VmFlags::VMF_HASH_CER_SP) || HasFlag(VmFlags::VMF_HASH_IW)) {
if (HasFlag(VmFlags::VMF_HASH_PATH_IW)) {
return hash::HashIWRes(value);
}
return hash::Hash64(value);
Expand Down Expand Up @@ -798,6 +798,7 @@ class OPCodeInfoSafeCreateLocalVariables : public OPCodeInfo {
context.m_localvars.insert(context.m_localvars.begin(), { hash::HashT89Scr("<error>"), 0 });
}

bool lastVa{};
for (size_t i = 0; i < count; i++) {
context.WritePadding(out);
uint64_t varName;
Expand All @@ -817,7 +818,7 @@ class OPCodeInfoSafeCreateLocalVariables : public OPCodeInfo {
context.m_bcl += 4;
}
auto& bytecode = context.m_bcl;

byte flags;
if (objctx.m_vmInfo->flags & VmFlags::VMF_NO_PARAM_FLAGS) {
flags = 0;
Expand All @@ -826,13 +827,24 @@ class OPCodeInfoSafeCreateLocalVariables : public OPCodeInfo {
flags = *(bytecode++);
}

byte flagsGen{ flags };

if (lastVa) {
out << "(va count)";
flagsGen |= T8GSCLocalVarFlag::IW_VARIADIC_COUNT;
lastVa = false;
}

// the variables are in reversed order
context.m_localvars.insert(context.m_localvars.begin(), { varName, flags });
context.m_localvars.insert(context.m_localvars.begin(), { varName, flagsGen });

out << hashutils::ExtractTmp("var", varName);

if (flags & T8GSCLocalVarFlag::VARIADIC) {
out << "...";
if (context.m_gscReader.HasFlag(tool::gsc::GOHF_VAR_VA_COUNT)) {
lastVa = true;
}
}
else if (flags & T8GSCLocalVarFlag::ARRAY_REF) {
out << "&";
Expand Down
1 change: 1 addition & 0 deletions src/acts/tools/gsc_opcodes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ namespace tool::gsc::opcode {
VMF_CRC_DUMP = 1 << 17,
VMF_EXPORT_CRC32 = 1 << 18,
VMF_HASH_CER_SP = 1 << 19,
VMF_HASH_PATH_IW = 1 << 20,
};
enum VmOperatorFunctionData : uint64_t {
VPFD_NONE = 0,
Expand Down
4 changes: 2 additions & 2 deletions src/acts/tools/gsc_vm/vm_jup_opcodes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace {
using namespace tool::gsc::opcode;
void OpCode() {

VmInfo* v8a = RegisterVM(VMI_JUP_8A, "Call of Duty: Modern Warfare III", "jup", "mwiiia", VmFlags::VMF_FOREACH_IW | VmFlags::VMF_HASH64 | VmFlags::VMF_NO_PARAM_FLAGS | VmFlags::VMF_FULL_FILE_NAMESPACE | VmFlags::VMF_HASH_IW | VmFlags::VMF_CALL_NO_PARAMS | VmFlags::VMF_IW_CALLS);
VmInfo* v8a = RegisterVM(VMI_JUP_8A, "Call of Duty: Modern Warfare III", "jup", "mwiiia", VmFlags::VMF_FOREACH_IW | VmFlags::VMF_HASH64 | VmFlags::VMF_NO_PARAM_FLAGS | VmFlags::VMF_FULL_FILE_NAMESPACE | VmFlags::VMF_HASH_IW | VmFlags::VMF_HASH_PATH_IW | VmFlags::VMF_CALL_NO_PARAMS | VmFlags::VMF_IW_CALLS);
v8a->RegisterVmName("jupa", "s5a", "mwiiia", "modernwarfareiiia", "mw23a");
v8a->AddPlatform(PLATFORM_PC);
v8a->RegisterSameCodePlatform(PLATFORM_PC, PLATFORM_PLAYSTATION);
Expand All @@ -34,7 +34,7 @@ namespace {
v8a->RegisterOpCode(PLATFORM_PC, OPCODE_SafeCreateLocalVariables, 0x98);
v8a->RegisterOpCode(PLATFORM_PC, OPCODE_IW_RegisterVariable, 0x2B, 0xA4);

VmInfo* v8b = RegisterVM(VMI_JUP_8B, "Call of Duty: Modern Warfare III (8B)", "jup8b", "mwiii", VmFlags::VMF_CRC_DUMP | VmFlags::VMF_FOREACH_IW | VmFlags::VMF_HASH64 | VmFlags::VMF_NO_PARAM_FLAGS | VmFlags::VMF_FULL_FILE_NAMESPACE | VmFlags::VMF_HASH_IW | VmFlags::VMF_CALL_NO_PARAMS | VmFlags::VMF_IW_CALLS);
VmInfo* v8b = RegisterVM(VMI_JUP_8B, "Call of Duty: Modern Warfare III (8B)", "jup8b", "mwiii", VmFlags::VMF_CRC_DUMP | VmFlags::VMF_FOREACH_IW | VmFlags::VMF_HASH64 | VmFlags::VMF_NO_PARAM_FLAGS | VmFlags::VMF_FULL_FILE_NAMESPACE | VmFlags::VMF_HASH_IW | VmFlags::VMF_HASH_PATH_IW | VmFlags::VMF_CALL_NO_PARAMS | VmFlags::VMF_IW_CALLS);
v8b->RegisterVmName("jup", "s5", "mwiii", "modernwarfareiii", "mw23");
v8b->AddPlatform(PLATFORM_PC);
v8b->RegisterVMGlobalVariable("level", OPCODE_IW_GetLevel);
Expand Down
10 changes: 5 additions & 5 deletions src/acts/tools/gsc_vm/vm_t10.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace {

class T1006GSCOBJHandler : public GSCOBJHandler {
public:
T1006GSCOBJHandler(byte* file, size_t fileSize) : GSCOBJHandler(file, fileSize, GOHF_ANIMTREE | GOHF_ANIMTREE_DOUBLE | GOHF_FOREACH_TYPE_JUP | GOHF_NOTIFY_CRC_STRING | GOHF_SUPPORT_EV_HANDLER | GOHF_SUPPORT_VAR_VA) {}
T1006GSCOBJHandler(byte* file, size_t fileSize) : GSCOBJHandler(file, fileSize, GOHF_ANIMTREE | GOHF_ANIMTREE_DOUBLE | GOHF_FOREACH_TYPE_JUP | GOHF_NOTIFY_CRC_STRING | GOHF_SUPPORT_EV_HANDLER | GOHF_SUPPORT_VAR_VA | GOHF_VAR_VA_COUNT) {}

void DumpHeader(std::ostream& asmout, const GscInfoOption& opt) override {
GscObj24* data = Ptr<GscObj24>();
Expand Down Expand Up @@ -342,7 +342,7 @@ namespace {

class T1007GSCOBJHandler : public GSCOBJHandler {
public:
T1007GSCOBJHandler(byte* file, size_t fileSize) : GSCOBJHandler(file, fileSize, GOHF_ANIMTREE | GOHF_ANIMTREE_DOUBLE | GOHF_FOREACH_TYPE_JUP | GOHF_NOTIFY_CRC_STRING | GOHF_SUPPORT_EV_HANDLER | GOHF_SUPPORT_VAR_VA) {}
T1007GSCOBJHandler(byte* file, size_t fileSize) : GSCOBJHandler(file, fileSize, GOHF_ANIMTREE | GOHF_ANIMTREE_DOUBLE | GOHF_FOREACH_TYPE_JUP | GOHF_NOTIFY_CRC_STRING | GOHF_SUPPORT_EV_HANDLER | GOHF_SUPPORT_VAR_VA | GOHF_VAR_VA_COUNT) {}

void DumpHeader(std::ostream& asmout, const GscInfoOption& opt) override {
GscObj24* data = Ptr<GscObj24>();
Expand Down Expand Up @@ -671,7 +671,7 @@ namespace {

class T100CGSCOBJHandler : public GSCOBJHandler {
public:
T100CGSCOBJHandler(byte* file, size_t fileSize) : GSCOBJHandler(file, fileSize, GOHF_ANIMTREE | GOHF_ANIMTREE_DOUBLE | GOHF_FOREACH_TYPE_JUP | GOHF_NOTIFY_CRC_STRING | GOHF_SUPPORT_EV_HANDLER | GOHF_SUPPORT_VAR_VA) {}
T100CGSCOBJHandler(byte* file, size_t fileSize) : GSCOBJHandler(file, fileSize, GOHF_ANIMTREE | GOHF_ANIMTREE_DOUBLE | GOHF_FOREACH_TYPE_JUP | GOHF_NOTIFY_CRC_STRING | GOHF_SUPPORT_EV_HANDLER | GOHF_SUPPORT_VAR_VA | GOHF_VAR_VA_COUNT) {}

void DumpHeader(std::ostream& asmout, const GscInfoOption& opt) override {
GscObj24* data = Ptr<GscObj24>();
Expand Down Expand Up @@ -997,12 +997,12 @@ namespace {
};



/*****************************************************************************************************************************/

class T100BGSCOBJHandler : public GSCOBJHandler {
public:
T100BGSCOBJHandler(byte* file, size_t fileSize) : GSCOBJHandler(file, fileSize, GOHF_ANIMTREE | GOHF_ANIMTREE_DOUBLE | GOHF_FOREACH_TYPE_JUP | GOHF_NOTIFY_CRC_STRING | GOHF_SUPPORT_EV_HANDLER | GOHF_SUPPORT_VAR_VA) {}
T100BGSCOBJHandler(byte* file, size_t fileSize) : GSCOBJHandler(file, fileSize, GOHF_ANIMTREE | GOHF_ANIMTREE_DOUBLE | GOHF_FOREACH_TYPE_JUP | GOHF_NOTIFY_CRC_STRING | GOHF_SUPPORT_EV_HANDLER | GOHF_SUPPORT_VAR_VA | GOHF_VAR_VA_COUNT) {}

void DumpHeader(std::ostream& asmout, const GscInfoOption& opt) override {
GscObj24* data = Ptr<GscObj24>();
Expand Down
8 changes: 4 additions & 4 deletions src/acts/tools/gsc_vm/vm_t10_opcodes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace {
using namespace tool::gsc::opcode;
void OpCode() {

VmInfo* t106 = RegisterVM(VMI_T10_06, "Call of Duty: Black Ops 6 (06)", "t10_6", "bo6_6", VmFlags::VMF_EXPORT_NOCHECKSUM | VmFlags::VMF_CRC_DUMP | VmFlags::VMF_FOREACH_IW | VmFlags::VMF_HASH64 | VmFlags::VMF_FULL_FILE_NAMESPACE | VmFlags::VMF_HASH_CER | VmFlags::VMF_CALL_NO_PARAMS); // VmFlags::VMF_IW_CALLS | VmFlags::VMF_NO_PARAM_FLAGS
VmInfo* t106 = RegisterVM(VMI_T10_06, "Call of Duty: Black Ops 6 (06)", "t10_6", "bo6_6", VmFlags::VMF_EXPORT_NOCHECKSUM | VmFlags::VMF_CRC_DUMP | VmFlags::VMF_FOREACH_IW | VmFlags::VMF_HASH64 | VmFlags::VMF_FULL_FILE_NAMESPACE | VmFlags::VMF_HASH_CER | VmFlags::VMF_HASH_PATH_IW | VmFlags::VMF_CALL_NO_PARAMS); // VmFlags::VMF_IW_CALLS | VmFlags::VMF_NO_PARAM_FLAGS
t106->RegisterVmName("cer6", "t10_6", "blackops6_6");
t106->AddPlatform(PLATFORM_PC);
t106->RegisterVMGlobalVariable("level", OPCODE_IW_GetLevel);
Expand Down Expand Up @@ -149,7 +149,7 @@ namespace {
t106->RegisterOpCode(PLATFORM_PC, OPCODE_IW_GetAnimationTree, 0xa0);


VmInfo* t107 = RegisterVM(VMI_T10_07, "Call of Duty: Black Ops 6 (07)", "t10", "bo6_7", VmFlags::VMF_CRC_DUMP | VmFlags::VMF_FOREACH_IW | VmFlags::VMF_EXPORT_NOCHECKSUM | VmFlags::VMF_HASH64 | VmFlags::VMF_FULL_FILE_NAMESPACE | VmFlags::VMF_HASH_CER | VmFlags::VMF_CALL_NO_PARAMS); // VmFlags::VMF_IW_CALLS | VmFlags::VMF_NO_PARAM_FLAGS
VmInfo* t107 = RegisterVM(VMI_T10_07, "Call of Duty: Black Ops 6 (07)", "t10", "bo6_7", VmFlags::VMF_CRC_DUMP | VmFlags::VMF_FOREACH_IW | VmFlags::VMF_EXPORT_NOCHECKSUM | VmFlags::VMF_HASH64 | VmFlags::VMF_FULL_FILE_NAMESPACE | VmFlags::VMF_HASH_CER | VmFlags::VMF_HASH_PATH_IW | VmFlags::VMF_CALL_NO_PARAMS); // VmFlags::VMF_IW_CALLS | VmFlags::VMF_NO_PARAM_FLAGS
t107->RegisterVmName("cer7", "t10_7", "blackops6_7");
t107->AddPlatform(PLATFORM_PC);
t107->RegisterVMGlobalVariable("level", OPCODE_IW_GetLevel);
Expand Down Expand Up @@ -183,7 +183,7 @@ namespace {
t107->RegisterOpCode(PLATFORM_PC, OPCODE_SafeCreateLocalVariables, 0x5a);
t107->RegisterOpCode(PLATFORM_PC, OPCODE_IW_RegisterMultipleVariables, 0x53);

VmInfo* t10b = RegisterVM(VMI_T10_0B, "Call of Duty: Black Ops 6 (0B)", "t10", "bo6_b", VmFlags::VMF_CRC_DUMP | VmFlags::VMF_FOREACH_IW | VmFlags::VMF_EXPORT_CRC32 | VmFlags::VMF_HASH64 | VmFlags::VMF_FULL_FILE_NAMESPACE | VmFlags::VMF_HASH_CER_SP | VmFlags::VMF_CALL_NO_PARAMS); // VmFlags::VMF_IW_CALLS | VmFlags::VMF_NO_PARAM_FLAGS
VmInfo* t10b = RegisterVM(VMI_T10_0B, "Call of Duty: Black Ops 6 (0B)", "t10", "bo6_b", VmFlags::VMF_CRC_DUMP | VmFlags::VMF_FOREACH_IW | VmFlags::VMF_EXPORT_CRC32 | VmFlags::VMF_HASH64 | VmFlags::VMF_FULL_FILE_NAMESPACE | VmFlags::VMF_HASH_CER_SP | VmFlags::VMF_HASH_PATH_IW | VmFlags::VMF_CALL_NO_PARAMS); // VmFlags::VMF_IW_CALLS | VmFlags::VMF_NO_PARAM_FLAGS
t10b->RegisterVmName("cerb", "t10_b", "blackops6_b", "t10sp", "bo6sp");
t10b->AddPlatform(PLATFORM_PC);
t10b->RegisterVMGlobalVariable("level", OPCODE_IW_GetLevel);
Expand Down Expand Up @@ -211,7 +211,7 @@ namespace {
t10b->RegisterOpCode(PLATFORM_PC, OPCODE_SafeCreateLocalVariables, 0x20);
t10b->RegisterOpCode(PLATFORM_PC, OPCODE_IW_RegisterMultipleVariables, 0x93);

VmInfo* t10c = RegisterVM(VMI_T10_0C, "Call of Duty: Black Ops 6", "t10", "bo6", VmFlags::VMF_CRC_DUMP | VmFlags::VMF_FOREACH_IW | VmFlags::VMF_EXPORT_CRC32 | VmFlags::VMF_HASH64 | VmFlags::VMF_FULL_FILE_NAMESPACE | VmFlags::VMF_HASH_CER | VmFlags::VMF_CALL_NO_PARAMS); // VmFlags::VMF_IW_CALLS | VmFlags::VMF_NO_PARAM_FLAGS
VmInfo* t10c = RegisterVM(VMI_T10_0C, "Call of Duty: Black Ops 6", "t10", "bo6", VmFlags::VMF_CRC_DUMP | VmFlags::VMF_FOREACH_IW | VmFlags::VMF_EXPORT_CRC32 | VmFlags::VMF_HASH64 | VmFlags::VMF_FULL_FILE_NAMESPACE | VmFlags::VMF_HASH_CER | VmFlags::VMF_HASH_PATH_IW | VmFlags::VMF_CALL_NO_PARAMS); // VmFlags::VMF_IW_CALLS | VmFlags::VMF_NO_PARAM_FLAGS
t10c->RegisterVmName("cer", "t10", "blackops6");
t10c->AddPlatform(PLATFORM_PC);
t10c->RegisterVMGlobalVariable("level", OPCODE_IW_GetLevel);
Expand Down
Loading

0 comments on commit 9923503

Please sign in to comment.