From 55742137083997c2bed9300b19d7b0d6955a225d Mon Sep 17 00:00:00 2001 From: qaate47 Date: Sat, 23 Nov 2024 21:01:31 +0100 Subject: [PATCH] fix log space, oodle lib, tests bo4, iw8 opcodes and vm opcodes --- src/acts/tools/exe_mapper_bo4.cpp | 54 +++++- src/acts/tools/gsc_opcodes.cpp | 73 +++++++- src/acts/tools/gsc_opcodes_load.cpp | 14 ++ src/acts/tools/gsc_opcodes_load.hpp | 1 + src/acts/tools/gsc_vm/vm_iw8_opcodes.cpp | 209 ++++++++++++++++++++++- src/acts/tools/gsc_vm_gscbin.cpp | 10 ++ src/acts/tools/test.cpp | 6 +- src/shared/core/logs.cpp | 3 +- src/shared/deps/oodle.cpp | 87 ---------- src/shared/deps/oodle.hpp | 93 +++++++++- 10 files changed, 432 insertions(+), 118 deletions(-) delete mode 100644 src/shared/deps/oodle.cpp diff --git a/src/acts/tools/exe_mapper_bo4.cpp b/src/acts/tools/exe_mapper_bo4.cpp index a9d15e2..2c2137a 100644 --- a/src/acts/tools/exe_mapper_bo4.cpp +++ b/src/acts/tools/exe_mapper_bo4.cpp @@ -1,37 +1,81 @@ #include #include #include +#include namespace { struct { - + char locationDir[MAX_PATH + 1]{}; } bo4; hook::library::Detour Com_Error_Detour; + hook::library::Detour Sys_GetAbsZoneDir_Detour; void Com_Error_Stub(uint32_t code) { throw std::runtime_error(utils::va("Com_Error(0x%x)", code)); } + const char* Sys_GetAbsZoneDir_Stub() { + return utils::va("%s/zone", bo4.locationDir); + } + + enum PMemStack : __int32 + { + PMEM_STACK_DB = 0x0, + PMEM_STACK_DB2 = 0x1, + PMEM_STACK_GAME = 0x2, + PMEM_STACK_SERVER = 0x3, + PMEM_STACK_HOT = 0x4, + PMEM_STACK_CINEMATICS = 0x5, + PMEM_STACK_DYNAMIC_IMAGES = 0x6, + PMEM_STACK_LIGHTING = 0x7, + PMEM_STACK_BINARY_PATCH = 0x8, + PMEM_STACK_DEMO_DOWNLOAD = 0x9, + PMEM_STACK_MOTION_MATCHING_KEYFRAMES = 0xA, + PMEM_STACK_COUNT = 0xB, + PMEM_STACK_INVALID = -1, + PHYS_ALLOC_LOW = 0x0, + PHYS_ALLOC_HIGH = 0x2, + PHYS_ALLOC_COUNT = 0xB, + }; + typedef void DB_Interrupt(void); + + + int bo4_exe_mapper(int argc, const char* argv[]) { - if (tool::NotEnoughParam(argc, 1)) return tool::BAD_USAGE; + if (tool::NotEnoughParam(argc, 2)) return tool::BAD_USAGE; - hook::module_mapper::Module mod{}; + hook::module_mapper::Module mod{ true }; if (!mod.Load(argv[2])) { LOG_ERROR("Can't map module {}", argv[2]); return tool::BASIC_ERROR; } + strcpy_s(bo4.locationDir, argv[3]); + LOG_INFO("Module loaded"); + deps::oodle::Oodle oodle{}; + + if (!oodle.LoadOodleFromGame(*mod)) { + LOG_ERROR("Can't load oodle"); + return tool::BASIC_ERROR; + } + + LOG_INFO("Deps loaded"); + Com_Error_Detour.Create((*mod)[0x288B110], Com_Error_Stub); + Sys_GetAbsZoneDir_Detour.Create((*mod)[0x2895E40], Sys_GetAbsZoneDir_Stub); - LOG_INFO("Hook loaded"); + LOG_INFO("Hooks loaded"); + //DB_LoadXFile(char const*, int, XZoneBuffer*, char const*, XAssetList*, XBlock*, void (*)(void), uchar*, PMemStack, int).text 0000000002E0CC10 00001573 00000808 0000004C R . . ..B T . + void (*DB_LoadXFile)(char const* path, int file, void* buffer, char const* filename, void* assetlist, void* xblock, DB_Interrupt inter, byte * buf, PMemStack side, int flags) + = (decltype(DB_LoadXFile))(*mod)[0x2E0CC1]; return tool::OK; } - ADD_TOOL(bo4_exe_mapper, "bo4", "[exe]", "test bo4 mapping", bo4_exe_mapper); + ADD_TOOL(bo4_exe_mapper, "bo4", "[exe] [gamedir]", "test bo4 mapping", bo4_exe_mapper); } \ No newline at end of file diff --git a/src/acts/tools/gsc_opcodes.cpp b/src/acts/tools/gsc_opcodes.cpp index 64923e2..4bb4a88 100644 --- a/src/acts/tools/gsc_opcodes.cpp +++ b/src/acts/tools/gsc_opcodes.cpp @@ -1278,7 +1278,9 @@ class OPCodeInfoGetHash : public OPCodeInfo { class OPCodeInfoJump : public OPCodeInfo { public: - using OPCodeInfo::OPCodeInfo; + bool jump32; +public: + OPCodeInfoJump(OPCode id, const char* name, bool jump32 = false) : jump32(jump32), OPCodeInfo(id, name) {} int Dump(std::ostream& out, uint16_t value, ASMContext& context, tool::gsc::T8GSCOBJContext& objctx) const override { // get the jump opcode location @@ -1330,6 +1332,7 @@ class OPCodeInfoJump : public OPCodeInfo { name = "jumpdev"; break; case OPCODE_Jump: + case OPCODE_IW_Jump32: name = "goto"; break; default: @@ -1342,14 +1345,28 @@ class OPCodeInfoJump : public OPCodeInfo { assert(!context.m_runDecompiler || name != nullptr); if (objctx.m_vmInfo->HasFlag(VmFlags::VMF_ALIGN)) { - context.Aligned(); + if (jump32) { + context.Aligned(); + } + else { + context.Aligned(); + } } auto& bytecode = context.m_bcl; - int16_t delta = *(int16_t*)bytecode; + int32_t delta; + + if (jump32) { + delta = *(int32_t*)bytecode; - bytecode += 2; + bytecode += 4; + } + else { + delta = *(int16_t*)bytecode; + + bytecode += 2; + } // push a location and mark it as referenced byte* newLoc = &context.m_bcl[delta]; @@ -1378,7 +1395,7 @@ class OPCodeInfoJump : public OPCodeInfo { if (delta != 0 || m_id == OPCODE_DevblockBegin) { if (context.m_runDecompiler) { bool inject = true; - if (m_id == OPCODE_Jump && delta > 0) { + if ((m_id == OPCODE_Jump || m_id == OPCODE_IW_Jump32) && delta > 0) { // might be ternary //ASMContextNodeTernary if (context.m_stack.size() && context.m_funcBlock.m_statements.size()) { @@ -1469,13 +1486,26 @@ class OPCodeInfoJump : public OPCodeInfo { int Skip(uint16_t value, ASMSkipContext& ctx) const override { int32_t m_jumpLocation = ctx.FunctionRelativeLocation(ctx.m_bcl - 2); if (ctx.m_vminfo->HasFlag(VmFlags::VMF_ALIGN | VmFlags::VMF_OPCODE_U16)) { - ctx.Aligned(); + if (jump32) { + ctx.Aligned(); + } + else { + ctx.Aligned(); + } } auto& bytecode = ctx.m_bcl; - int16_t delta = *(int16_t*)bytecode; + int32_t delta; + if (jump32) { + delta = *(int32_t*)bytecode; - bytecode += 2; + bytecode += 4; + } + else { + delta = *(int16_t*)bytecode; + + bytecode += 2; + } ctx.PushLocation(&ctx.m_bcl[delta]); @@ -2966,6 +2996,29 @@ class OPCodeInfoStatement : public OPCodeInfo { return 0; } }; +class OPCodeInfoGscBinStrToken : public OPCodeInfo { +public: + using OPCodeInfo::OPCodeInfo; + + int Dump(std::ostream& out, uint16_t value, ASMContext& context, tool::gsc::T8GSCOBJContext& objctx) const override { + int32_t token{ *(int32_t*)context.m_bcl }; + context.m_bcl += 4; + + out << "0x" << std::hex << token; + if (context.m_runDecompiler) { + auto* ref = new ASMContextNodeValue(token, TYPE_VALUE, true); + // convert it to statement + ref->m_priority = PRIORITY_INST; + context.PushASMCNode(ref); + context.CompleteStatement(); + } + out << "\n"; + return 0; + } + int Skip(uint16_t value, ASMSkipContext& ctx) const override { + return 0; + } +}; class OPCodeInfoSkip : public OPCodeInfo { const char* m_operatorName; public: @@ -5095,8 +5148,9 @@ namespace tool::gsc::opcode { RegisterOpCodeHandler(new OPCodeInfoUnknown(OPCODE_GSCBIN_SKIP_N, "GscBinSkipN")); RegisterOpCodeHandler(new OPCodeInfoUnknown(OPCODE_GSCBIN_SKIP_3BC_4SD, "GscBinSkip3BC4SD")); RegisterOpCodeHandler(new OPCodeInfoUnknown(OPCODE_GSCBIN_SKIP_4BC_4SD, "GscBinSkip4BC4SD")); - RegisterOpCodeHandler(new OPCodeInfoUnknown(OPCODE_GSCBIN_SKIP_STR_TOKEN, "GscBinSkipSTRTOKEN")); RegisterOpCodeHandler(new OPCodeInfoUnknown(OPCODE_GSCBIN_SKIP_4BC_1STR, "GscBinSkip4BC1STR")); + + RegisterOpCodeHandler(new OPCodeInfoGscBinStrToken(OPCODE_GSCBIN_SKIP_STR_TOKEN, "GscBinSkipSTRTOKEN")); // all op without params RegisterOpCodeHandler(new OPCodeInfoStatement(OPCODE_ProfileStart, "ProfileStart", "profilestart()")); @@ -5116,6 +5170,7 @@ namespace tool::gsc::opcode { RegisterOpCodeHandler(new OPCodeInfoEndSwitch()); // dev/jump RegisterOpCodeHandler(new OPCodeInfoJump(OPCODE_DevblockBegin, "DevblockBegin")); + RegisterOpCodeHandler(new OPCodeInfoJump(OPCODE_IW_Jump32, "Jump", true)); RegisterOpCodeHandler(new OPCodeInfoJump(OPCODE_Jump, "Jump")); RegisterOpCodeHandler(new OPCodeInfoJump(OPCODE_JumpOnTrue, "JumpOnTrue")); RegisterOpCodeHandler(new OPCodeInfoJump(OPCODE_JumpOnGreaterThan, "JumpOnGreaterThan")); diff --git a/src/acts/tools/gsc_opcodes_load.cpp b/src/acts/tools/gsc_opcodes_load.cpp index 17a2eee..3e0c1bd 100644 --- a/src/acts/tools/gsc_opcodes_load.cpp +++ b/src/acts/tools/gsc_opcodes_load.cpp @@ -338,6 +338,20 @@ namespace tool::gsc::opcode { RegisterOpCode(OPCODE_GSCBIN_SKIP_4BC_4SD, "GscBinSkip4BC4SD"); RegisterOpCode(OPCODE_GSCBIN_SKIP_STR_TOKEN, "GscBinSkipSTRTOKEN"); RegisterOpCode(OPCODE_GSCBIN_SKIP_4BC_1STR, "GscBinSkip4BC1STR"); + RegisterOpCode(OPCODE_IW_CallBuiltinFunction0, "CallBuiltinFunction0"); + RegisterOpCode(OPCODE_IW_CallBuiltinFunction1, "CallBuiltinFunction1"); + RegisterOpCode(OPCODE_IW_CallBuiltinFunction2, "CallBuiltinFunction2"); + RegisterOpCode(OPCODE_IW_CallBuiltinFunction3, "CallBuiltinFunction3"); + RegisterOpCode(OPCODE_IW_CallBuiltinFunction4, "CallBuiltinFunction4"); + RegisterOpCode(OPCODE_IW_CallBuiltinFunction5, "CallBuiltinFunction5"); + RegisterOpCode(OPCODE_IW_CallBuiltinMethod0, "CallBuiltinMethod0"); + RegisterOpCode(OPCODE_IW_CallBuiltinMethod1, "CallBuiltinMethod1"); + RegisterOpCode(OPCODE_IW_CallBuiltinMethod2, "CallBuiltinMethod2"); + RegisterOpCode(OPCODE_IW_CallBuiltinMethod3, "CallBuiltinMethod3"); + RegisterOpCode(OPCODE_IW_CallBuiltinMethod4, "CallBuiltinMethod4"); + RegisterOpCode(OPCODE_IW_CallBuiltinMethod5, "CallBuiltinMethod5"); + RegisterOpCode(OPCODE_IW_ScriptFunctionCall2, "ScriptFunctionCall2"); + RegisterOpCode(OPCODE_IW_Jump32, "Jump32"); RegisterOpCode(OPCODE_InvalidOpCode, "InvalidOpCode"); } }; diff --git a/src/acts/tools/gsc_opcodes_load.hpp b/src/acts/tools/gsc_opcodes_load.hpp index dfeabf2..9c624a3 100644 --- a/src/acts/tools/gsc_opcodes_load.hpp +++ b/src/acts/tools/gsc_opcodes_load.hpp @@ -392,6 +392,7 @@ namespace tool::gsc::opcode { OPCODE_IW_CallBuiltinMethod5, OPCODE_IW_ScriptFunctionCall2, + OPCODE_IW_Jump32, OPCODE_COUNT, }; diff --git a/src/acts/tools/gsc_vm/vm_iw8_opcodes.cpp b/src/acts/tools/gsc_vm/vm_iw8_opcodes.cpp index a48e719..fa2b4e5 100644 --- a/src/acts/tools/gsc_vm/vm_iw8_opcodes.cpp +++ b/src/acts/tools/gsc_vm/vm_iw8_opcodes.cpp @@ -4,6 +4,201 @@ #include namespace { + enum ScriptOpcode : byte { + OP_CastFieldObject = 0x0, + OP_SetLocalVariableFieldCached = 0x1, + OP_plus = 0x2, + OP_RemoveLocalVariables = 0x3, + OP_EvalSelfFieldVariableRef = 0x4, + OP_ScriptFarMethodChildThreadCall = 0x5, + OP_GetGameRef = 0x6, + OP_EvalAnimFieldVariable = 0x7, + OP_EvalLevelFieldVariableRef = 0x8, + OP_GetThisthread = 0x9, + OP_greater = 0xA, + OP_waittillmatch = 0xB, + OP_shift_right = 0xC, + OP_dec = 0xD, + OP_JumpOnTrue = 0xE, + OP_bit_or = 0xF, + OP_equality = 0x10, + OP_ClearLocalVariableFieldCached0 = 0x11, + OP_notify = 0x12, + OP_GetVector = 0x13, + OP_ScriptMethodChildThreadCallPointer = 0x14, + OP_PreScriptCall = 0x15, + OP_GetByte = 0x16, + OP_ScriptFarThreadCall = 0x17, + OP_SetSelfFieldVariableField = 0x18, + OP_JumpOnFalseExpr = 0x19, + OP_GetUndefined = 0x1A, + OP_jumpback = 0x1B, + OP_JumpOnTrueExpr = 0x1C, + OP_CallBuiltin0 = 0x1D, + OP_CallBuiltin1 = 0x1E, + OP_CallBuiltin2 = 0x1F, + OP_CallBuiltin3 = 0x20, + OP_CallBuiltin4 = 0x21, + OP_CallBuiltin5 = 0x22, + OP_CallBuiltin = 0x23, + OP_SetLocalVariableFieldCached0 = 0x24, + OP_ClearFieldVariable = 0x25, + OP_GetLevel = 0x26, + OP_size = 0x27, + OP_SafeSetWaittillVariableFieldCached = 0x28, + OP_ScriptLocalMethodThreadCall = 0x29, + OP_AddArray = 0x2A, + OP_endon = 0x2B, + OP_EvalFieldVariable = 0x2C, + OP_shift_left = 0x2D, + OP_EvalLocalArrayRefCached0 = 0x2E, + OP_Return = 0x2F, + OP_CreateLocalVariable = 0x30, + OP_SafeSetVariableFieldCached0 = 0x31, + OP_GetBuiltinFunction = 0x32, + OP_ScriptLocalMethodCall = 0x33, + OP_CallBuiltinMethodPointer = 0x34, + OP_ScriptLocalChildThreadCall = 0x35, + OP_GetSelfObject = 0x36, + OP_GetGame = 0x37, + OP_SetLevelFieldVariableField = 0x38, + OP_EvalArray = 0x39, + OP_GetSelf = 0x3A, + OP_End = 0x3B, + OP_EvalSelfFieldVariable = 0x3C, + OP_less_equal = 0x3D, + OP_EvalLocalVariableCached0 = 0x3E, + OP_EvalLocalVariableCached1 = 0x3F, + OP_EvalLocalVariableCached2 = 0x40, + OP_EvalLocalVariableCached3 = 0x41, + OP_EvalLocalVariableCached4 = 0x42, + OP_EvalLocalVariableCached5 = 0x43, + OP_EvalLocalVariableCached = 0x44, + OP_EvalNewLocalArrayRefCached0 = 0x45, + OP_ScriptChildThreadCallPointer = 0x46, + OP_EvalLocalVariableObjectCached = 0x47, + OP_ScriptLocalThreadCall = 0x48, + OP_GetInteger = 0x49, + OP_ScriptMethodCallPointer = 0x4A, + OP_checkclearparams = 0x4B, + OP_SetAnimFieldVariableField = 0x4C, + OP_waittillmatch2 = 0x4D, + OP_minus = 0x4E, + OP_ScriptLocalFunctionCall2 = 0x4F, + OP_GetNegUnsignedShort = 0x50, + OP_GetNegByte = 0x51, + OP_SafeCreateVariableFieldCached = 0x52, + OP_greater_equal = 0x53, + OP_vector = 0x54, + OP_GetBuiltinMethod = 0x55, + OP_endswitch = 0x56, + OP_ClearArray = 0x57, + OP_DecTop = 0x58, + OP_CastBool = 0x59, + OP_EvalArrayRef = 0x5A, + OP_SetNewLocalVariableFieldCached0 = 0x5B, + OP_GetZero = 0x5C, + OP_wait = 0x5D, + OP_waittill = 0x5E, + OP_GetIString = 0x5F, + OP_ScriptFarFunctionCall = 0x60, + OP_GetAnimObject = 0x61, + OP_GetAnimTree = 0x62, + OP_EvalLocalArrayCached = 0x63, + OP_mod = 0x64, + OP_ScriptFarMethodThreadCall = 0x65, + OP_GetUnsignedShort = 0x66, + OP_clearparams = 0x67, + OP_ScriptMethodThreadCallPointer = 0x68, + OP_ScriptFunctionCallPointer = 0x69, + OP_EmptyArray = 0x6A, + OP_SafeSetVariableFieldCached = 0x6B, + OP_ClearVariableField = 0x6C, + OP_EvalFieldVariableRef = 0x6D, + OP_ScriptLocalMethodChildThreadCall = 0x6E, + OP_EvalNewLocalVariableRefCached0 = 0x6F, + OP_GetFloat = 0x70, + OP_EvalLocalVariableRefCached = 0x71, + OP_JumpOnFalse = 0x72, + OP_BoolComplement = 0x73, + OP_ScriptThreadCallPointer = 0x74, + OP_ScriptFarFunctionCall2 = 0x75, + OP_less = 0x76, + OP_BoolNot = 0x77, + OP_waittillFrameEnd = 0x78, + OP_waitframe = 0x79, + OP_GetString = 0x7A, + OP_EvalLevelFieldVariable = 0x7B, + OP_GetLevelObject = 0x7C, + OP_inc = 0x7D, + OP_CallBuiltinMethod0 = 0x7E, + OP_CallBuiltinMethod1 = 0x7F, + OP_CallBuiltinMethod2 = 0x80, + OP_CallBuiltinMethod3 = 0x81, + OP_CallBuiltinMethod4 = 0x82, + OP_CallBuiltinMethod5 = 0x83, + OP_CallBuiltinMethod = 0x84, + OP_GetAnim = 0x85, + OP_switch = 0x86, + OP_SetVariableField = 0x87, + OP_divide = 0x88, + OP_GetLocalFunction = 0x89, + OP_ScriptFarChildThreadCall = 0x8A, + OP_multiply = 0x8B, + OP_ClearLocalVariableFieldCached = 0x8C, + OP_EvalAnimFieldVariableRef = 0x8D, + OP_EvalLocalArrayRefCached = 0x8E, + OP_EvalLocalVariableRefCached0 = 0x8F, + OP_bit_and = 0x90, + OP_GetAnimation = 0x91, + OP_GetFarFunction = 0x92, + OP_CallBuiltinPointer = 0x93, + OP_jump = 0x94, + OP_voidCodepos = 0x95, + OP_ScriptFarMethodCall = 0x96, + OP_inequality = 0x97, + OP_ScriptLocalFunctionCall = 0x98, + OP_bit_ex_or = 0x99, + OP_NOP = 0x9A, + OP_abort = 0x9B, + OP_object = 0x9C, + OP_thread_object = 0x9D, + OP_EvalLocalVariable = 0x9E, + OP_EvalLocalVariableRef = 0x9F, + OP_prof_begin = 0xA0, + OP_prof_end = 0xA1, + OP_breakpoint = 0xA2, + OP_assignmentBreakpoint = 0xA3, + OP_manualAndAssignmentBreakpoint = 0xA4, + OP_BoolNotAfterAnd = 0xA5, + OP_FormalParams = 0xA6, + OP_IsDefined = 0xA7, + OP_IsTrue = 0xA8, + OP_NativeGetLocalFunction = 0xA9, + OP_NativeLocalFunctionCall = 0xAA, + OP_NativeLocalFunctionCall2 = 0xAB, + OP_NativeLocalMethodCall = 0xAC, + OP_NativeLocalFunctionThreadCall = 0xAD, + OP_NativeLocalMethodThreadCall = 0xAE, + OP_NativeLocalFunctionChildThreadCall = 0xAF, + OP_NativeLocalMethodChildThreadCall = 0xB0, + OP_NativeGetFarFunction = 0xB1, + OP_NativeFarFunctionCall = 0xB2, + OP_NativeFarFunctionCall2 = 0xB3, + OP_NativeFarMethodCall = 0xB4, + OP_NativeFarFunctionThreadCall = 0xB5, + OP_NativeFarMethodThreadCall = 0xB6, + OP_NativeFarFunctionChildThreadCall = 0xB7, + OP_NativeFarMethodChildThreadCall = 0xB8, + OP_EvalNewLocalArrayRefCached0_Precompiled = 0xB9, + OP_SetNewLocalVariableFieldCached0_Precompiled = 0xBA, + OP_CreateLocalVariable_Precompiled = 0xBB, + OP_SafeCreateVariableFieldCached_Precompiled = 0xBC, + OP_FormalParams_Precompiled = 0xBD, + OP_count = 0xBE, + }; + + using namespace tool::gsc::opcode; void OpCode() { VmInfo* gscbin = RegisterVM(VMI_IW_BIN_MW19, "Call of Duty: Modern Warfare (2019)", "iw8", "mw19", VmFlags::VMF_GSCBIN | VmFlags::VMF_NO_MAGIC | VmFlags::VMF_VAR_ID | VmFlags::VMF_NO_PARAM_FLAGS | VmFlags::VMF_IW_LIKE | VmFlags::VMF_IW_CALLS | VmFlags::VMF_CALL_NO_PARAMS); @@ -138,7 +333,7 @@ namespace { gscbin->RegisterOpCode(PLATFORM_PC, OPCODE_GetString, 0x7A); gscbin->RegisterOpCode(PLATFORM_PC, OPCODE_GSCBIN_SKIP_STR_TOKEN, 0x7B); gscbin->RegisterOpCode(PLATFORM_PC, OPCODE_IW_GetLevelGRef, 0x7C); - gscbin->RegisterOpCode(PLATFORM_PC, OPCODE_Inc, 0x7D); + gscbin->RegisterOpCode(PLATFORM_PC, OPCODE_Inc, OP_inc); gscbin->RegisterOpCode(PLATFORM_PC, OPCODE_IW_CallBuiltinMethod0, 0x7E); gscbin->RegisterOpCode(PLATFORM_PC, OPCODE_IW_CallBuiltinMethod1, 0x7F); gscbin->RegisterOpCode(PLATFORM_PC, OPCODE_IW_CallBuiltinMethod2, 0x80); @@ -158,18 +353,18 @@ namespace { gscbin->RegisterOpCode(PLATFORM_PC, OPCODE_IW_GetAnimation, 0x91); gscbin->RegisterOpCode(PLATFORM_PC, OPCODE_Undefined, 0x92); gscbin->RegisterOpCode(PLATFORM_PC, OPCODE_GSCBIN_SKIP_1, 0x93); - gscbin->RegisterOpCode(PLATFORM_PC, OPCODE_GSCBIN_SKIP_4, 0x94); + gscbin->RegisterOpCode(PLATFORM_PC, OPCODE_IW_Jump32, OP_jump); gscbin->RegisterOpCode(PLATFORM_PC, OPCODE_GSCBIN_SKIP_0, 0x95); - gscbin->RegisterOpCode(PLATFORM_PC, OPCODE_Undefined, 0x96); - gscbin->RegisterOpCode(PLATFORM_PC, OPCODE_NotEqual, 0x97); + gscbin->RegisterOpCode(PLATFORM_PC, OPCODE_ScriptMethodCall, OP_ScriptFarMethodCall); + gscbin->RegisterOpCode(PLATFORM_PC, OPCODE_NotEqual, OP_inequality); gscbin->RegisterOpCode(PLATFORM_PC, OPCODE_GSCBIN_SKIP_3, 0x98); gscbin->RegisterOpCode(PLATFORM_PC, OPCODE_GSCBIN_SKIP_0, 0x99); - gscbin->RegisterOpCode(PLATFORM_PC, OPCODE_Nop, 0x9A); - gscbin->RegisterOpCode(PLATFORM_PC, OPCODE_Abort, 0x9B); + gscbin->RegisterOpCode(PLATFORM_PC, OPCODE_Nop, OP_NOP); + gscbin->RegisterOpCode(PLATFORM_PC, OPCODE_Abort, OP_abort); gscbin->RegisterOpCode(PLATFORM_PC, OPCODE_GSCBIN_SKIP_5, 0xA0); gscbin->RegisterOpCode(PLATFORM_PC, OPCODE_GSCBIN_SKIP_1, 0xA1); gscbin->RegisterOpCode(PLATFORM_PC, OPCODE_GSCBIN_SKIP_0, 0xA5); - gscbin->RegisterOpCode(PLATFORM_PC, OPCODE_SafeCreateLocalVariables, 0xA6); + gscbin->RegisterOpCode(PLATFORM_PC, OPCODE_SafeCreateLocalVariables, OP_FormalParams); gscbin->RegisterOpCode(PLATFORM_PC, OPCODE_GSCBIN_SKIP_3, 0xA9); gscbin->RegisterOpCode(PLATFORM_PC, OPCODE_GSCBIN_SKIP_3, 0xAA); gscbin->RegisterOpCode(PLATFORM_PC, OPCODE_GSCBIN_SKIP_3, 0xAB); diff --git a/src/acts/tools/gsc_vm_gscbin.cpp b/src/acts/tools/gsc_vm_gscbin.cpp index cc84063..3d49985 100644 --- a/src/acts/tools/gsc_vm_gscbin.cpp +++ b/src/acts/tools/gsc_vm_gscbin.cpp @@ -237,6 +237,9 @@ namespace { case OPCODE_EvalArray: case OPCODE_EvalArrayRef: case OPCODE_SetVariableField: + case OPCODE_IW_SingleWaitTill: + case OPCODE_ClearParams: + case OPCODE_BoolNot: case OPCODE_GSCBIN_SKIP_0: asmout << "\n"; break; @@ -274,6 +277,7 @@ namespace { case OPCODE_GetUnsignedInteger: case OPCODE_GetNegUnsignedInteger: case OPCODE_GetFloat: + case OPCODE_IW_Jump32: case OPCODE_GSCBIN_SKIP_4: SkipNBytes(4) << "\n"; break; @@ -421,6 +425,12 @@ namespace { SkipNBytes(1) << "\n"; break; } + case OPCODE_GSCBIN_SKIP_3BC_4SD: { + + + break; + } + case OPCODE_GSCBIN_SKIP_4BC_4SD: default: { const char* err{ utils::va("Operator not handled %x (%d/%s)", opcode, opcode, nfo->m_name) }; asmout << err << std::endl; diff --git a/src/acts/tools/test.cpp b/src/acts/tools/test.cpp index cfdd0e8..0cd3caa 100644 --- a/src/acts/tools/test.cpp +++ b/src/acts/tools/test.cpp @@ -106,12 +106,14 @@ namespace { return tool::BASIC_ERROR; } - if (!deps::oodle::LoadOodleFromGame(*mod)) { + deps::oodle::Oodle oodle{}; + + if (!oodle.LoadOodleFromGame(*mod)) { LOG_ERROR("Can't load oodle"); return tool::BASIC_ERROR; } - LOG_INFO("Oodle 0x{:x} loaded: {}", deps::oodle::GetVersion(), deps::oodle::GetOodleLib()); + LOG_INFO("Oodle 0x{:x} loaded: {}", oodle.GetVersion(), oodle.GetOodleLib()); return tool::OK; } diff --git a/src/shared/core/logs.cpp b/src/shared/core/logs.cpp index 1dc6579..684bce7 100644 --- a/src/shared/core/logs.cpp +++ b/src/shared/core/logs.cpp @@ -138,8 +138,9 @@ namespace core::logs { if (g_loglevel == LVL_TRACE_PATH) { out << '[' << file << '@' << std::dec << line << ']'; } + out << " "; } - out << " " << str; + out << str; if (color) { out << cli::clicolor::Reset(); diff --git a/src/shared/deps/oodle.cpp b/src/shared/deps/oodle.cpp deleted file mode 100644 index 09f3f60..0000000 --- a/src/shared/deps/oodle.cpp +++ /dev/null @@ -1,87 +0,0 @@ -#include -#include "oodle.hpp" -#include - -namespace deps::oodle { - namespace { - hook::library::Library oodle{}; - - size_t(*OodleLZ_DecompressPtr)( - void* src, size_t srcLen, void* dest, size_t destLen, - int a5, - int a6, - int a7, - __int64 a8, - __int64 a9, - unsigned int(*a10)(__int64, __int64, __int64, __int64), - __int64 a11, - __int64 a12, - __int64 a13, - int a14) {}; - void (*Oodle_GetConfigValuesPtr)(int32_t* cfg){}; - } - - bool LoadOodle(const char* libname) { - FreeOodle(); - oodle.SetModule(libname, false, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS); - - if (!oodle) { - LOG_ERROR("Can't load oodle lib {}", libname); - return false; - } - - OodleLZ_DecompressPtr = oodle.GetProc("OodleLZ_Decompress"); - if (!OodleLZ_DecompressPtr) { - LOG_ERROR("Can't load find OodleLZ_Decompress in lib {}, is this a oodle dll?", libname); - FreeOodle(); - return false; - } - if (Oodle_GetConfigValuesPtr = oodle.GetProc("Oodle_GetConfigValues")) { - LOG_TRACE("Loaded oodle version 0x{:x}", GetVersion()); - } - - return true; - } - bool LoadOodleFromGame(const hook::library::Library& game) { - for (const char* depNameCS : game.GetIATModules()) { - std::string_view depName{ depNameCS }; - - if (depName.starts_with(OO2CORE_PREFIX)) { - return LoadOodle(depNameCS); - } - } - - LOG_ERROR("Can't find Oodle core library prefix in {}", game); - return false; - } - - void FreeOodle() { - oodle.Free(); - OodleLZ_DecompressPtr = nullptr; - } - - void GetConfigValues(int32_t* cfg) { - if (!Oodle_GetConfigValuesPtr) { - throw std::runtime_error("Oodle_GetConfigValues not available or oodle not loaded"); - } - Oodle_GetConfigValuesPtr(cfg); - } - - int32_t GetVersion() { - int32_t cfg[7]; - GetConfigValues(cfg); - return cfg[6]; - } - - const hook::library::Library& GetOodleLib() { - return oodle; - } - - size_t Decompress(void* src, size_t srcLen, void* dest, size_t destLen) { - if (!OodleLZ_DecompressPtr) { - throw std::runtime_error("Oodle not loaded"); - } - - return OodleLZ_DecompressPtr(src, srcLen, dest, destLen, 0, 0, 0, 0, 0, nullptr, 0, 0, 0, 0); - } -} \ No newline at end of file diff --git a/src/shared/deps/oodle.hpp b/src/shared/deps/oodle.hpp index 561ff6c..d2a2205 100644 --- a/src/shared/deps/oodle.hpp +++ b/src/shared/deps/oodle.hpp @@ -7,11 +7,90 @@ namespace deps::oodle { constexpr const char* OO2CORE_7 = "oo2core_7_win64"; constexpr const char* OO2CORE_8 = "oo2core_8_win64"; - bool LoadOodle(const char* libname); - bool LoadOodleFromGame(const hook::library::Library& game); - void FreeOodle(); - void GetConfigValues(int32_t* cfg); - const hook::library::Library& GetOodleLib(); - int32_t GetVersion(); - size_t Decompress(void* src, size_t srcLen, void* dest, size_t destLen); + typedef size_t(*POodleLZ_Decompress)(void* src, size_t srcLen, void* dest, size_t destLen, int a5, int a6, int a7, __int64 a8, __int64 a9, unsigned int(*a10)(__int64, __int64, __int64, __int64), __int64 a11, __int64 a12, __int64 a13, int a14); + typedef void(*POodle_GetConfigValues)(int32_t* cfg); + + class Oodle { + hook::library::Library oodle{}; + POodleLZ_Decompress OodleLZ_Decompress{}; + POodle_GetConfigValues Oodle_GetConfigValues{}; + + public: + Oodle() {} + Oodle(const char* libname) { + LoadOodle(libname); + } + ~Oodle() { + oodle.Free(); + } + + constexpr operator bool() const { + return oodle; + } + + bool LoadOodle(const char* libname) { + FreeOodle(); + oodle.SetModule(libname, false, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS); + + if (!oodle) { + LOG_ERROR("Can't load oodle lib {}", libname); + return false; + } + + if (!(OodleLZ_Decompress = oodle.GetProc("OodleLZ_Decompress"))) { + LOG_ERROR("Can't load find OodleLZ_Decompress in lib {}, is this an oodle dll?", libname); + FreeOodle(); + return false; + } + if (Oodle_GetConfigValues = oodle.GetProc("Oodle_GetConfigValues")) { + LOG_TRACE("Loaded oodle version 0x{:x}", GetVersion()); + } + + return true; + } + + bool LoadOodleFromGame(const hook::library::Library& game) { + for (const char* depNameCS : game.GetIATModules()) { + std::string_view depName{ depNameCS }; + + if (depName.starts_with(OO2CORE_PREFIX)) { + return LoadOodle(depNameCS); + } + } + + LOG_ERROR("Can't find Oodle core library prefix in {}", game); + return false; + } + + void FreeOodle() { + oodle.Free(); + OodleLZ_Decompress = nullptr; + Oodle_GetConfigValues = nullptr; + } + + void GetConfigValues(int32_t* cfg) const { + if (!Oodle_GetConfigValues) { + throw std::runtime_error("Oodle_GetConfigValues not available or oodle not loaded"); + } + Oodle_GetConfigValues(cfg); + } + + int32_t GetVersion() const { + int32_t cfg[7]; + GetConfigValues(cfg); + return cfg[6]; + } + + constexpr const hook::library::Library& GetOodleLib() const { + return oodle; + } + + size_t Decompress(void* src, size_t srcLen, void* dest, size_t destLen) const { + if (!OodleLZ_Decompress) { + throw std::runtime_error("Oodle not loaded"); + } + + return OodleLZ_Decompress(src, srcLen, dest, destLen, 0, 0, 0, 0, 0, nullptr, 0, 0, 0, 0); + } + }; } \ No newline at end of file