From 9057687ca94274e1e2df20fd080fc774e759c989 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=99=AF=E5=A4=A7=E4=BE=A0?= Date: Fri, 27 Oct 2023 22:17:54 +0800 Subject: [PATCH] doors --- NatvisFile.natvis | 2 +- appdata/il2cpp-functions.h | 2 ++ appdata/il2cpp-types.h | 64 +++++++++++++++++++++----------------- gui/tabs/doors_tab.cpp | 21 ++++++++++--- hooks/DirectX.cpp | 2 +- hooks/Doors.cpp | 7 +++++ hooks/PlainDoor.cpp | 44 ++++++++++++++++++-------- hooks/PlayerControl.cpp | 5 +++ hooks/_hooks.cpp | 4 +++ hooks/_hooks.h | 2 ++ used_types.txt | 3 ++ user/utility.cpp | 9 +++--- user/utility.h | 5 +-- 13 files changed, 115 insertions(+), 55 deletions(-) diff --git a/NatvisFile.natvis b/NatvisFile.natvis index ca85c6f7..5aac2dc5 100644 --- a/NatvisFile.natvis +++ b/NatvisFile.natvis @@ -99,7 +99,7 @@ - + diff --git a/appdata/il2cpp-functions.h b/appdata/il2cpp-functions.h index ef9aeef8..83207ae4 100644 --- a/appdata/il2cpp-functions.h +++ b/appdata/il2cpp-functions.h @@ -243,3 +243,5 @@ DO_APP_FUNC(LogicOptions*, GameManager_get_LogicOptions, (GameManager* __this, M // 2023.10.24e DO_APP_FUNC(void, FungleShipStatus_OnEnable, (FungleShipStatus* __this, MethodInfo* method), "Assembly-CSharp, System.Void FungleShipStatus::OnEnable()"); +DO_APP_FUNC(void, MushroomWallDoor_SetDoorway, (MushroomWallDoor* __this, bool open, MethodInfo* method), "Assembly-CSharp, System.Void MushroomWallDoor::SetDoorway(System.Boolean)"); +DO_APP_FUNC(void, MushroomDoorSabotageMinigame_Begin, (MushroomDoorSabotageMinigame* __this, PlayerTask* task, MethodInfo* method), "Assembly-CSharp, System.Void MushroomDoorSabotageMinigame::Begin(PlayerTask)"); diff --git a/appdata/il2cpp-types.h b/appdata/il2cpp-types.h index 4048fa13..3456acf2 100644 --- a/appdata/il2cpp-types.h +++ b/appdata/il2cpp-types.h @@ -8419,6 +8419,27 @@ namespace app }; #pragma endregion +#pragma region MushroomDoorSabotageMinigame + struct MushroomDoorSabotageMinigame__Fields { + struct Minigame__Fields _; + void* mushroomInvisibleSeconds; + void* mushroomVisibleSeconds; + struct TextMeshPro* counterText; + void* spawnPoints; + void* mushroomVariants; + struct OpenableDoor* myDoor; + int32_t mushroomWhackCount; + void* spawnPointBag; + void* mushrooms; + }; + + struct MushroomDoorSabotageMinigame { + Il2CppClass* klass; + MonitorData* monitor; + struct MushroomDoorSabotageMinigame__Fields fields; + }; +#pragma endregion + #pragma region SabotageTask struct SabotageTask__Fields { @@ -9769,39 +9790,26 @@ namespace app float size; }; - struct PlainDoor - { - struct PlainDoor__Class* klass; - void* monitor; + struct PlainDoor { + Il2CppClass* klass; + MonitorData* monitor; struct PlainDoor__Fields fields; }; - struct PlainDoor__VTable - { - VirtualInvokeData Equals; - VirtualInvokeData Finalize; - VirtualInvokeData GetHashCode; - VirtualInvokeData ToString; - VirtualInvokeData SetDoorway; - VirtualInvokeData get_IsOpen; - VirtualInvokeData Serialize; - VirtualInvokeData Deserialize; - VirtualInvokeData DoUpdate; - VirtualInvokeData Start; - }; - - struct PlainDoor__StaticFields - { + struct MushroomWallDoor__Fields { + struct OpenableDoor__Fields _; + void* wallCollider; + struct Collider2D* shadowColl; + void* mushrooms; + void* openSound; + void* closeSound; + bool open; }; - struct PlainDoor__Class - { - Il2CppClass_0 _0; - Il2CppRuntimeInterfaceOffsetPair* interfaceOffsets; - struct PlainDoor__StaticFields* static_fields; - const Il2CppRGCTXData* rgctx_data; - Il2CppClass_1 _1; - struct PlainDoor__VTable vtable; + struct MushroomWallDoor { + Il2CppClass* klass; + MonitorData* monitor; + struct MushroomWallDoor__Fields fields; }; #pragma endregion diff --git a/gui/tabs/doors_tab.cpp b/gui/tabs/doors_tab.cpp index 70a6ac07..43068f3e 100644 --- a/gui/tabs/doors_tab.cpp +++ b/gui/tabs/doors_tab.cpp @@ -6,6 +6,8 @@ #include "state.hpp" #include "utility.h" +using namespace std::string_view_literals; + namespace DoorsTab { void Render() { GameOptions options; @@ -19,7 +21,17 @@ namespace DoorsTab { || systemType == SystemTypes__Enum::Decontamination3) { continue; } - auto plainDoor = GetPlainDoorByRoom(systemType); + bool isOpen; + auto openableDoor = GetOpenableDoorByRoom(systemType); + if ("PlainDoor"sv == openableDoor->klass->parent->name + || "PlainDoor"sv == openableDoor->klass->name) { + isOpen = reinterpret_cast(openableDoor)->fields.Open; + } else if ("MushroomWallDoor"sv == openableDoor->klass->name) { + isOpen = reinterpret_cast(openableDoor)->fields.open; + } + else { + continue; + } if (!(std::find(State.pinnedDoors.begin(), State.pinnedDoors.end(), systemType) == State.pinnedDoors.end())) { ImGui::PushStyleColor(ImGuiCol_Text, { 0.9f, 0.1f, 0.25f, 1.f }); @@ -27,7 +39,7 @@ namespace DoorsTab { State.selectedDoor = systemType; ImGui::PopStyleColor(1); } - else if (!plainDoor->fields.Open) + else if (!isOpen) { ImGui::PushStyleColor(ImGuiCol_Text, { 0.85f, 0.2f, 0.5f, 1.f }); if (ImGui::Selectable(TranslateSystemTypes(systemType), State.selectedDoor == systemType)) @@ -87,8 +99,6 @@ namespace DoorsTab { } ImGui::NewLine(); if (State.selectedDoor != SystemTypes__Enum::Hallway) { - auto plainDoor = GetPlainDoorByRoom(State.selectedDoor); - if (ImGui::Button("Close Door")) { State.rpcQueue.push(new RpcCloseDoorsOfType(State.selectedDoor, false)); } @@ -104,7 +114,8 @@ namespace DoorsTab { } } } - if (State.mapType == Settings::MapType::Pb || State.mapType == Settings::MapType::Airship) + if (State.mapType == Settings::MapType::Pb || State.mapType == Settings::MapType::Airship + || State.mapType == Settings::MapType::Fungle) { ImGui::Dummy(ImVec2(4, 4) * State.dpiScale); if (ImGui::Checkbox("Auto Open Doors", &State.AutoOpenDoors)) { diff --git a/hooks/DirectX.cpp b/hooks/DirectX.cpp index 03738d28..653f0253 100644 --- a/hooks/DirectX.cpp +++ b/hooks/DirectX.cpp @@ -153,7 +153,7 @@ bool ImGuiInitialization(IDXGISwapChain* pSwapChain) { maps.push_back({ D3D11Image(Resource(IDB_PNG2), pDevice), 115.F, 240.F, 9.25F }); maps.push_back({ D3D11Image(Resource(IDB_PNG3), pDevice), 8.F, 21.F, 10.F }); maps.push_back({ D3D11Image(Resource(IDB_PNG4), pDevice), 162.F, 107.F, 6.F }); - maps.push_back({ D3D11Image(Resource(IDB_PNG15), pDevice), 252.F, 140.F, 9.F }); + maps.push_back({ D3D11Image(Resource(IDB_PNG15), pDevice), 237.F, 140.F, 8.5F }); icons.insert({ ICON_TYPES::VENT_IN, { D3D11Image(Resource(IDB_PNG5), pDevice), 0.02f }}); icons.insert({ ICON_TYPES::VENT_OUT, { D3D11Image(Resource(IDB_PNG6), pDevice), 0.02f }}); diff --git a/hooks/Doors.cpp b/hooks/Doors.cpp index 815a3cef..e13efc7d 100644 --- a/hooks/Doors.cpp +++ b/hooks/Doors.cpp @@ -10,6 +10,13 @@ void dPlainDoor_SetDoorway(PlainDoor* __this, bool open, MethodInfo* method) { app::PlainDoor_SetDoorway(__this, open, method); } +void dMushroomWallDoor_SetDoorway(MushroomWallDoor* __this, bool open, MethodInfo* method) { + if (open && (std::find(State.pinnedDoors.begin(), State.pinnedDoors.end(), __this->fields._.Room) != State.pinnedDoors.end())) { + State.rpcQueue.push(new RpcCloseDoorsOfType(__this->fields._.Room, false)); + } + app::MushroomWallDoor_SetDoorway(__this, open, method); +} + bool dAutoOpenDoor_DoUpdate(AutoOpenDoor* __this, float dt, MethodInfo* method) { if ((std::find(State.pinnedDoors.begin(), State.pinnedDoors.end(), __this->fields._._.Room) != State.pinnedDoors.end()) && __this->fields.ClosedTimer < 1.5f) { State.rpcQueue.push(new RpcCloseDoorsOfType(__this->fields._._.Room, false)); diff --git a/hooks/PlainDoor.cpp b/hooks/PlainDoor.cpp index 5c33f7bc..07572bf6 100644 --- a/hooks/PlainDoor.cpp +++ b/hooks/PlainDoor.cpp @@ -3,31 +3,49 @@ #include "state.hpp" #include +using namespace std::string_view_literals; + +static bool OpenDoor(OpenableDoor* door) { + if ("PlainDoor"sv == door->klass->name) { + app::PlainDoor_SetDoorway(reinterpret_cast(door), true, {}); + } + else if ("MushroomWallDoor"sv == door->klass->name) { + app::MushroomWallDoor_SetDoorway(reinterpret_cast(door), true, {}); + } + else { + return false; + } + State.rpcQueue.push(new RpcRepairSystem(SystemTypes__Enum::Doors, door->fields.Id | 64)); + return true; +} + +void dMushroomDoorSabotageMinigame_Begin(MushroomDoorSabotageMinigame* __this, PlayerTask* task, MethodInfo* method) { + if (State.AutoOpenDoors) { + if (OpenDoor(__this->fields.myDoor)) { + Minigame_Close((Minigame*)__this, {}); + return; + } + } + app::MushroomDoorSabotageMinigame_Begin(__this, task, method); +} + void dDoorBreakerGame_Start(DoorBreakerGame* __this, MethodInfo* method) { if (State.AutoOpenDoors) { - static Il2CppClass* klassPlainDoor = get_class("Assembly-CSharp, PlainDoor"); - if (il2cpp_class_is_assignable_from(klassPlainDoor, __this->fields.MyDoor->klass)) { - State.rpcQueue.push(new RpcRepairSystem(SystemTypes__Enum::Doors, __this->fields.MyDoor->fields.Id | 64)); - PlainDoor_SetDoorway((PlainDoor*)__this->fields.MyDoor, true, NULL); - Minigame_Close((Minigame*)__this, NULL); + if (OpenDoor(__this->fields.MyDoor)) { + Minigame_Close((Minigame*)__this, {}); return; } - // TODO 231024 } DoorBreakerGame_Start(__this, method); } void dDoorCardSwipeGame_Begin(DoorCardSwipeGame* __this, PlayerTask* playerTask, MethodInfo* method) { if (State.AutoOpenDoors) { - static Il2CppClass* klassPlainDoor = get_class("Assembly-CSharp, PlainDoor"); - if (il2cpp_class_is_assignable_from(klassPlainDoor, __this->fields.MyDoor->klass)) { - __this->fields.State = DoorCardSwipeGame_TaskStages__Enum::Inserted; - State.rpcQueue.push(new RpcRepairSystem(SystemTypes__Enum::Doors, __this->fields.MyDoor->fields.Id | 64)); - PlainDoor_SetDoorway((PlainDoor*)__this->fields.MyDoor, true, NULL); - Minigame_Close((Minigame*)__this, NULL); + __this->fields.State = DoorCardSwipeGame_TaskStages__Enum::Inserted; + if (OpenDoor(__this->fields.MyDoor)) { + Minigame_Close((Minigame*)__this, {}); return; } - // TODO 231024 } DoorCardSwipeGame_Begin(__this, playerTask, method); } \ No newline at end of file diff --git a/hooks/PlayerControl.cpp b/hooks/PlayerControl.cpp index 1e6ca445..24285aa9 100644 --- a/hooks/PlayerControl.cpp +++ b/hooks/PlayerControl.cpp @@ -312,6 +312,11 @@ void dPlayerControl_RpcSyncSettings(PlayerControl* __this, Byte__Array* optionsB void dPlayerControl_MurderPlayer(PlayerControl* __this, PlayerControl* target, MurderResultFlags__Enum resultFlags, MethodInfo* method) { + if (static_cast(resultFlags) & static_cast(MurderResultFlags__Enum::FailedError)) { + app::PlayerControl_MurderPlayer(__this, target, resultFlags, method); + return; + } + if (PlayerIsImpostor(GetPlayerData(__this)) && PlayerIsImpostor(GetPlayerData(target))) { synchronized(Replay::replayEventMutex) { State.liveReplayEvents.emplace_back(std::make_unique(GetEventPlayerControl(__this).value(), CHEAT_ACTIONS::CHEAT_KILL_IMPOSTOR)); diff --git a/hooks/_hooks.cpp b/hooks/_hooks.cpp index 9d12ee74..1ce6af31 100644 --- a/hooks/_hooks.cpp +++ b/hooks/_hooks.cpp @@ -157,6 +157,8 @@ void DetourInitilization() { HOOKFUNC(ExileController_ReEnableGameplay); HOOKFUNC(SabotageSystemType_SetInitialSabotageCooldown); HOOKFUNC(FungleShipStatus_OnEnable); + HOOKFUNC(MushroomWallDoor_SetDoorway); + HOOKFUNC(MushroomDoorSabotageMinigame_Begin); if (!HookFunction(&(PVOID&)oPresent, dPresent, "D3D_PRESENT_FUNCTION")) return; @@ -239,6 +241,8 @@ void DetourUninitialization() UNHOOKFUNC(ExileController_ReEnableGameplay); UNHOOKFUNC(SabotageSystemType_SetInitialSabotageCooldown); UNHOOKFUNC(FungleShipStatus_OnEnable); + UNHOOKFUNC(MushroomWallDoor_SetDoorway); + UNHOOKFUNC(MushroomDoorSabotageMinigame_Begin); if (DetourDetach(&(PVOID&)oPresent, dPresent) != 0) return; diff --git a/hooks/_hooks.h b/hooks/_hooks.h index af6d17db..f161505f 100644 --- a/hooks/_hooks.h +++ b/hooks/_hooks.h @@ -74,3 +74,5 @@ void dGameOptionsManager_set_CurrentGameOptions(GameOptionsManager* __this, IGam void dExileController_ReEnableGameplay(ExileController* __this, MethodInfo* method); void dSabotageSystemType_SetInitialSabotageCooldown(SabotageSystemType* __this, MethodInfo* method); void dFungleShipStatus_OnEnable(FungleShipStatus* __this, MethodInfo* method); +void dMushroomWallDoor_SetDoorway(MushroomWallDoor* __this, bool open, MethodInfo* method); +void dMushroomDoorSabotageMinigame_Begin(MushroomDoorSabotageMinigame* __this, PlayerTask* task, MethodInfo* method); diff --git a/used_types.txt b/used_types.txt index ac07ea4f..fa6bd65b 100644 --- a/used_types.txt +++ b/used_types.txt @@ -222,3 +222,6 @@ FreeChatInputField__Fields FreeChatInputField MurderResultFlags__Enum FungleShipStatus +OpenableDoor +MushroomWallDoor +MushroomDoorSabotageMinigame diff --git a/user/utility.cpp b/user/utility.cpp index 2714d24c..5b7de1e0 100644 --- a/user/utility.cpp +++ b/user/utility.cpp @@ -288,20 +288,19 @@ PlayerControl* GetPlayerControlById(Game::PlayerId id) { return NULL; } -PlainDoor* GetPlainDoorByRoom(SystemTypes__Enum room) { - for (auto door : il2cpp::Array((*Game::pShipStatus)->fields.AllDoors)) +OpenableDoor* GetOpenableDoorByRoom(SystemTypes__Enum room) { + for (auto door : GetAllOpenableDoors()) { if (door->fields.Room == room) { - // TODO 231024 - return (PlainDoor*)door; + return door; } } return nullptr; } -il2cpp::Array GetAllPlainDoors() { +il2cpp::Array GetAllOpenableDoors() { return (*Game::pShipStatus)->fields.AllDoors; } diff --git a/user/utility.h b/user/utility.h index d6bed85a..8f15eb22 100644 --- a/user/utility.h +++ b/user/utility.h @@ -147,8 +147,9 @@ GameData_PlayerInfo* GetPlayerData(PlayerControl* player); Vector2 GetTrueAdjustedPosition(PlayerControl* player); GameData_PlayerInfo* GetPlayerDataById(Game::PlayerId id); PlayerControl* GetPlayerControlById(Game::PlayerId id); -PlainDoor* GetPlainDoorByRoom(SystemTypes__Enum room); -il2cpp::Array GetAllPlainDoors(); +// MushroomWallDoor or PlainDoor +OpenableDoor* GetOpenableDoorByRoom(SystemTypes__Enum room); +il2cpp::Array GetAllOpenableDoors(); il2cpp::List GetAllPlayerControl(); il2cpp::List GetAllPlayerData(); il2cpp::Array GetAllDeadBodies();