From c38ffdd9a4e815410bb623a830c6ec5d39edaef6 Mon Sep 17 00:00:00 2001 From: g0aty Date: Tue, 7 May 2024 18:48:28 +0530 Subject: [PATCH] Update to v3.4 --- appdata/il2cpp-functions.h | 3 +- appdata/il2cpp-types.h | 46 +++++++++++-- gui/esp.cpp | 130 +++++++++++++++++++++++++++++++------ gui/tabs/game_tab.cpp | 28 ++++++++ gui/tabs/players_tab.cpp | 84 +++++++++++++----------- gui/tabs/self_tab.cpp | 26 ++++---- hooks/Doors.cpp | 6 +- hooks/HudManager.cpp | 17 +++-- hooks/InnerNetClient.cpp | 15 ++--- hooks/PlayerControl.cpp | 79 +++++++++++++++++++--- hooks/ShipStatus.cpp | 5 +- hooks/_hooks.cpp | 18 +++-- hooks/_hooks.h | 1 + rpc/RpcMurderPlayer.cpp | 46 ++++++++++++- rpc/_rpc.h | 14 +++- user/main.cpp | 2 +- user/state.cpp | 2 + user/state.hpp | 3 +- user/utility.cpp | 18 +++-- user/utility.h | 1 + 20 files changed, 426 insertions(+), 118 deletions(-) diff --git a/appdata/il2cpp-functions.h b/appdata/il2cpp-functions.h index 4b32f94..1230173 100644 --- a/appdata/il2cpp-functions.h +++ b/appdata/il2cpp-functions.h @@ -321,4 +321,5 @@ DO_APP_FUNC(bool, LogicGameFlowNormal_IsGameOverDueToDeath, (LogicGameFlowNormal DO_APP_FUNC(bool, LogicGameFlowHnS_IsGameOverDueToDeath, (LogicGameFlowHnS* __this, MethodInfo* method), "Assembly-CSharp, System.Boolean LogicGameFlowHnS::IsGameOverDueToDeath()"); DO_APP_FUNC(void, ChatController_OnResolutionChanged, (ChatController* __this, float aspectRatio, int32_t width, int32_t height, bool fullscreen, MethodInfo* method), "Assembly-CSharp, System.Void ChatController::OnResolutionChanged(System.Single, System.Int32, System.Int32, System.Boolean)"); DO_APP_FUNC(void, ChatController_ForceClosed, (ChatController* __this, MethodInfo* method), "Assembly-CSharp, System.Void ChatController::ForceClosed()"); -DO_APP_FUNC(Byte__Array*, GameOptionsFactory_ToBytes, (GameOptionsFactory* __this, IGameOptions* data, bool forceAprilFoolsMode, MethodInfo* method), "Assembly-CSharp, System.Byte[] AmongUs.GameOptions.GameOptionsFactory::ToBytes(AmongUs.GameOptions.IGameOptions, System.Boolean)"); \ No newline at end of file +//DO_APP_FUNC(Byte__Array*, GameOptionsFactory_ToBytes, (GameOptionsFactory* __this, IGameOptions* data, bool forceAprilFoolsMode, MethodInfo* method), "Assembly-CSharp, System.Byte[] AmongUs.GameOptions.GameOptionsFactory::ToBytes(AmongUs.GameOptions.IGameOptions, System.Boolean)"); +DO_APP_FUNC(void, NotificationPopper_AddItem, (NotificationPopper* __this, String* item, MethodInfo* method), "Assembly-CSharp, System.Void NotificationPopper::AddItem(System.String)"); \ No newline at end of file diff --git a/appdata/il2cpp-types.h b/appdata/il2cpp-types.h index 8ba6656..1512d68 100644 --- a/appdata/il2cpp-types.h +++ b/appdata/il2cpp-types.h @@ -7758,7 +7758,7 @@ namespace app void* shhhEmblem; void* IntroPrefab; void* GameMenu; - void* Notifier; + struct NotificationPopper* Notifier; void* roomTracker; void* TaskCompleteSound; void* TaskUpdateSound; @@ -8234,8 +8234,6 @@ namespace app #endif #pragma endregion - typedef Il2CppObject GameOptionsFactory; - #pragma region InnerNetClient #if defined(_CPLUSPLUS_) @@ -8355,7 +8353,7 @@ namespace app void* LastMatchmakerError; void* PreSpawnDispatcher; void* Dispatcher; - GameOptionsFactory* gameOptionsFactory; + void* gameOptionsFactory; bool _IsGamePublic_k__BackingField; #if defined(_CPLUSPLUS_) InnerNetClient_GameStates__Enum GameState; @@ -11553,6 +11551,46 @@ namespace app }; #pragma endregion +#pragma region NotificationPopper + struct NotificationPopper__Fields { + struct MonoBehaviour__Fields _; + struct TextMeshPro* TextArea; + float zPos; + float alphaTimer; + float ShowDuration; + float FadeDuration; + struct Color textColor; + struct AudioClip* NotificationSound; + struct Camera* mainCamera; + struct StringBuilder* builder; + }; + + struct NotificationPopper { + struct NotificationPopper__Class* klass; + MonitorData* monitor; + struct NotificationPopper__Fields fields; + }; + + struct NotificationPopper__VTable { + VirtualInvokeData Equals; + VirtualInvokeData Finalize; + VirtualInvokeData GetHashCode; + VirtualInvokeData ToString; + }; + + struct NotificationPopper__StaticFields { + }; + + struct NotificationPopper__Class { + Il2CppClass_0 _0; + Il2CppRuntimeInterfaceOffsetPair* interfaceOffsets; + struct NotificationPopper__StaticFields* static_fields; + const Il2CppRGCTXData* rgctx_data; + Il2CppClass_1 _1; + struct NotificationPopper__VTable vtable; + }; +#pragma endregion + typedef Il2CppReflectionMethod MonoMethod; typedef Il2CppObject ActivityManager; diff --git a/gui/esp.cpp b/gui/esp.cpp index 3ad460d..9e1458f 100644 --- a/gui/esp.cpp +++ b/gui/esp.cpp @@ -23,7 +23,7 @@ static void RenderText(std::string_view text, const ImVec2& pos, const ImVec4& c { CurrentWindow->DrawList->AddText(nullptr, 0.f, ImScreen + 0.5f * State.dpiScale, - ImGui::GetColorU32(ImVec4(0.f, 0.f, 0.f, 0.f)), text.data(), text.data() + text.length()); + ImGui::GetColorU32(IM_COL32_BLACK), text.data(), text.data() + text.length()); } CurrentWindow->DrawList->AddText(nullptr, 0.f, ImScreen, ImGui::GetColorU32(color), text.data(), text.data() + text.length()); @@ -59,7 +59,7 @@ static void RenderBox(const ImVec2& top, const ImVec2& bottom, const float heigh }; if (wantsShadow) { - const ImVec4& shadowColor = ImVec4(0.f, 0.f, 0.f, 0.f); + const ImVec4& shadowColor = ImGui::ColorConvertU32ToFloat4(ImGui::GetColorU32(color) & IM_COL32_A_MASK); for (size_t i = 0; i < std::size(points); i += 2) { RenderLine(points[i] + 0.5f * State.dpiScale, points[i + 1] + 0.5f * State.dpiScale, shadowColor, false); } @@ -69,6 +69,8 @@ static void RenderBox(const ImVec2& top, const ImVec2& bottom, const float heigh } } +bool renderPlayerEsp = false; + void Esp::Render() { CurrentWindow = ImGui::GetCurrentWindow(); @@ -77,11 +79,54 @@ void Esp::Render() // Lock our mutex when we render (this will unlock when it goes out of scope) synchronized(instance.m_DrawingMutex) { + // testing some stuffs + if (renderPlayerEsp) { + for (auto& it : instance.m_Players) + { + if (const auto& player = it.playerData.validate(); + player.has_value() //Verify PlayerControl hasn't been destroyed (happens when disconnected) + && !player.is_Disconnected() //Sanity check, shouldn't ever be true + && player.is_LocalPlayer() //highlight yourself, you're ugly + && (!player.get_PlayerData()->fields.IsDead || State.ShowEsp_Ghosts) + && it.OnScreen) + { + if (State.ShowEsp_Box) + { + float width = GetScaleFromValue(35.0f); + float height = GetScaleFromValue(120.0f); + + ImVec2 top{ it.Position.x + width, it.Position.y }; + ImVec2 bottom{ it.Position.x - width, it.Position.y - height }; + + RenderBox(top, bottom, height, width, it.Color); + } + + // TODO: show x and y + if (State.ShowEsp_Distance) + { + const ImVec2 position{ it.Position.x, it.Position.y + 15.0f * State.dpiScale }; + + Vector2 mouse = { + ImGui::GetMousePos().x, ImGui::GetMousePos().y + }; + + std::string lel = std::to_string(ScreenToWorld(mouse).x) + ", " + std::to_string(ScreenToWorld(mouse).y); + + std::string lol = std::to_string(it.Position.x) + ", " + std::to_string(it.Position.y); + char* player = lol.data(); + + RenderText(player, position, it.Color); + } + } + } + } + // track player codes for (auto& it : instance.m_Players) { if (const auto& player = it.playerData.validate(); player.has_value() //Verify PlayerControl hasn't been destroyed (happens when disconnected) && !player.is_Disconnected() //Sanity check, shouldn't ever be true + && !player.is_LocalPlayer() //Don't highlight yourself, you're ugly && (!player.get_PlayerData()->fields.IsDead || State.ShowEsp_Ghosts) && it.OnScreen) { @@ -98,28 +143,75 @@ void Esp::Render() RenderBox(top, bottom, height, width, it.Color); } - if (!player.is_LocalPlayer()) { //Don't highlight yourself, you're ugly - ///////////////////////////////// - //// Distance /////////////////// - ///////////////////////////////// - if (State.ShowEsp_Distance) - { - const ImVec2 position{ it.Position.x, it.Position.y + 15.0f * State.dpiScale }; + ///////////////////////////////// + //// Distance /////////////////// + ///////////////////////////////// + + if (State.ShowEsp_Distance) + { + // logic and calculation + ImVec2 position = { it.Position.x, it.Position.y + 15.0f * State.dpiScale }; + ImVec2 position2 = { it.Position.x, it.Position.y + 30.0f * State.dpiScale }; + + // infamous trash codes + float minX = 40.0f, minY = 0.0f, + maxX = DirectX::GetWindowSize().x - 46.0f, // 1320 + maxY = DirectX::GetWindowSize().y - 38.0f; // 730 - char distance[32]; - sprintf_s(distance, "[%.2fm]", it.Distance); + float x = it.Position.x, y = it.Position.y; + float offset = 15.0f * State.dpiScale; - RenderText(distance, position, it.Color); + if (x < minX) { + x = minX; } - ///////////////////////////////// - //// Tracers //////////////////// - ///////////////////////////////// - if (State.ShowEsp_Tracers && !player.is_LocalPlayer()) - { - RenderLine(instance.LocalPosition, it.Position, it.Color, true); + else if (x > maxX) { + x = maxX; + } + + if (y < minY) { + y = minY; } + else if (y > maxY) { + y = maxY; + } + + position = { x, y + offset }; + position2 = { x, y + 2 * offset }; + + // strings + char distance[32]; + sprintf_s(distance, "[%.0fm]", it.Distance); + + std::string lol = it.Name; + char* player = lol.data(); + + //std::string lol2 = std::to_string(it.Position.x) + ", " + std::to_string(it.Position.y); + //char* pl = lol2.data(); + + // kill cd update + GameOptions options; + if (const auto& player = it.playerData.validate(); + State.ShowKillCD + && !player.get_PlayerData()->fields.IsDead + && player.get_PlayerData()->fields.Role + && player.get_PlayerData()->fields.Role->fields.CanUseKillButton + ) { + float killTimer = player.get_PlayerControl()->fields.killTimer; + sprintf_s(distance, "[%.1fs]", killTimer); + } + + // render info + RenderText(player, position, it.Color); + RenderText(distance, position2, it.Color); + } + ///////////////////////////////// + //// Tracers //////////////////// + ///////////////////////////////// + if (State.ShowEsp_Tracers) + { + RenderLine(instance.LocalPosition, it.Position, it.Color, true); } } } } -} +} \ No newline at end of file diff --git a/gui/tabs/game_tab.cpp b/gui/tabs/game_tab.cpp index a0bc700..40fc75e 100644 --- a/gui/tabs/game_tab.cpp +++ b/gui/tabs/game_tab.cpp @@ -187,6 +187,34 @@ namespace GameTab { State.rpcQueue.push(new RpcVent(*Game::pLocalPlayer, 1, true)); }*/ + if (IsInLobby() && ImGui::Button("Allow Everyone to NoClip")) { + for (auto p : GetAllPlayerControl()) + State.lobbyRpcQueue.push(new RpcMurderLoop(*Game::pLocalPlayer, p, 1, true)); + State.NoClip = true; + ShowHudNotification("Allowed everyone to NoClip!"); + } + ImGui::SameLine(); + if ((IsInGame() || IsInLobby()) && ImGui::Button("Kill Everyone")) { + for (auto player : GetAllPlayerControl()) { + if (IsInGame()) + State.rpcQueue.push(new RpcMurderPlayer(*Game::pLocalPlayer, player)); + else if (IsInLobby()) + State.lobbyRpcQueue.push(new RpcMurderPlayer(*Game::pLocalPlayer, player)); + } + } + if ((IsInGame() || IsInLobby()) && (IsHost() || !State.SafeMode)) { + ImGui::SameLine(); + if (ImGui::Button("Protect Everyone")) { + for (auto player : GetAllPlayerControl()) { + uint8_t colorId = GetPlayerOutfit(GetPlayerData(player))->fields.ColorId; + if (IsInGame()) + State.rpcQueue.push(new RpcProtectPlayer(*Game::pLocalPlayer, PlayerSelection(player), colorId)); + else if (IsInLobby()) + State.lobbyRpcQueue.push(new RpcProtectPlayer(*Game::pLocalPlayer, PlayerSelection(player), colorId)); + } + } + } + if (IsInGame() && ToggleButton("Disable Venting", &State.DisableVents)) { State.Save(); } diff --git a/gui/tabs/players_tab.cpp b/gui/tabs/players_tab.cpp index 42ad48c..3aef3fc 100644 --- a/gui/tabs/players_tab.cpp +++ b/gui/tabs/players_tab.cpp @@ -164,13 +164,6 @@ namespace PlayersTab { } } std::string platformText = std::format("Platform: {}", platform); - ImGui::Text(const_cast(platformText.c_str())); - if (convert_from_string(selectedPlayer.get_PlayerData()->fields.FriendCode) != "" && ImGui::Button("Set as Fake Friend Code")) { - State.FakeFriendCode = convert_from_string(selectedPlayer.get_PlayerData()->fields.FriendCode); - State.Save(); - } - if (convert_from_string(selectedPlayer.get_PlayerData()->fields.FriendCode) != "" || convert_from_string(selectedPlayer.get_PlayerData()->fields.Puid) != "") - ImGui::Text("These friend codes and product\nuser ID's will only be applied\nafter restarting the game."); } ImGui::EndChild(); @@ -188,14 +181,16 @@ namespace PlayersTab { if (State.DisableMeetings && IsHost()) ImGui::TextColored(ImVec4(1.0f, 0.0f, 0.0f, 1.0f), "Meetings have been disabled."); GameOptions options; - if (IsInGame() && !GetPlayerData(*Game::pLocalPlayer)->fields.IsDead && (!State.DisableMeetings && IsHost())) { //Player selection doesn't matter + if (IsInGame() && !GetPlayerData(*Game::pLocalPlayer)->fields.IsDead && (!State.DisableMeetings || !IsHost())) { //Player selection doesn't matter if (!State.InMeeting) { if (ImGui::Button("Call Meeting")) { + RepairSabotage(*Game::pLocalPlayer); State.rpcQueue.push(new RpcReportBody({})); } } else { if (ImGui::Button("Call Meeting")) { + RepairSabotage(*Game::pLocalPlayer); State.rpcQueue.push(new RpcForceMeeting(*Game::pLocalPlayer, {})); } } @@ -208,7 +203,6 @@ namespace PlayersTab { }*/ State.rpcQueue.push(new RpcVotePlayer(player, player, true)); } - State.rpcQueue.push(new RpcEndMeeting()); State.InMeeting = false; } } @@ -302,31 +296,37 @@ namespace PlayersTab { } } - if (IsHost() && ImGui::Button("Kick")) { - app::InnerNetClient_KickPlayer((InnerNetClient*)(*Game::pAmongUsClient), selectedPlayer.get_PlayerControl()->fields._.OwnerId, false, NULL); - } - if (ImGui::Button("Votekick")) { - if (IsInGame()) { - State.rpcQueue.push(new RpcVoteKick(selectedPlayer.get_PlayerControl())); + if ((IsInMultiplayerGame() || IsInLobby()) && !selectedPlayer.is_LocalPlayer()) { + if (IsHost() && ImGui::Button("Kick")) { + app::InnerNetClient_KickPlayer((InnerNetClient*)(*Game::pAmongUsClient), selectedPlayer.get_PlayerControl()->fields._.OwnerId, false, NULL); } - else if (IsInLobby()) { - State.lobbyRpcQueue.push(new RpcVoteKick(selectedPlayer.get_PlayerControl())); - } - } - if (!State.SafeMode) { - ImGui::SameLine(); - if (ImGui::Button("Kick Exploit")) { + if (ImGui::Button("Votekick")) { if (IsInGame()) { - State.rpcQueue.push(new RpcVoteKick(selectedPlayer.get_PlayerControl(), true)); + State.rpcQueue.push(new RpcVoteKick(selectedPlayer.get_PlayerControl())); } else if (IsInLobby()) { - State.lobbyRpcQueue.push(new RpcVoteKick(selectedPlayer.get_PlayerControl(), true)); + State.lobbyRpcQueue.push(new RpcVoteKick(selectedPlayer.get_PlayerControl())); } } - } - if (IsHost()) ImGui::SameLine(); - if (IsHost() && ImGui::Button("Ban")) { - app::InnerNetClient_KickPlayer((InnerNetClient*)(*Game::pAmongUsClient), selectedPlayer.get_PlayerControl()->fields._.OwnerId, true, NULL); + if (!State.SafeMode) { + if (ImGui::Button("Kick Exploit")) { + if (IsInGame()) { + State.rpcQueue.push(new RpcVoteKick(selectedPlayer.get_PlayerControl(), true)); + } + else if (IsInLobby()) { + State.lobbyRpcQueue.push(new RpcVoteKick(selectedPlayer.get_PlayerControl(), true)); + } + } + } + else if (IsInGame()) { + if (ImGui::Button("Attempt to Ban")) { + State.rpcQueue.push(new RpcMurderLoop(*Game::pLocalPlayer, selectedPlayer.get_PlayerControl(), 200, true)); + } + } + if (IsHost()) ImGui::SameLine(); + if (IsHost() && ImGui::Button("Ban")) { + app::InnerNetClient_KickPlayer((InnerNetClient*)(*Game::pAmongUsClient), selectedPlayer.get_PlayerControl()->fields._.OwnerId, true, NULL); + } } if (framesPassed == 0) @@ -352,7 +352,7 @@ namespace PlayersTab { State.lobbyRpcQueue.push(new RpcShapeshift(*Game::pLocalPlayer, State.selectedPlayer, !State.AnimationlessShapeshift)); } } - else if (role == RoleTypes__Enum::Shapeshifter) { + else if (State.RealRole == RoleTypes__Enum::Shapeshifter && role == RoleTypes__Enum::Shapeshifter) { app::ShapeshifterRole* shapeshifterRole = (app::ShapeshifterRole*)playerRole; if (shapeshifterRole->fields.cooldownSecondsRemaining <= 0 && ImGui::Button("Shift")) { @@ -366,7 +366,7 @@ namespace PlayersTab { if (IsHost() || !State.SafeMode) { if (ImGui::Button("Protect Player")) { - app::GameData_PlayerOutfit* outfit = GetPlayerOutfit(GetPlayerData(*Game::pLocalPlayer)); + app::GameData_PlayerOutfit* outfit = GetPlayerOutfit(selectedPlayer.get_PlayerData()); auto colorId = outfit->fields.ColorId; if (IsInGame()) State.rpcQueue.push(new RpcProtectPlayer(*Game::pLocalPlayer, State.selectedPlayer, colorId)); @@ -374,7 +374,7 @@ namespace PlayersTab { State.lobbyRpcQueue.push(new RpcProtectPlayer(*Game::pLocalPlayer, State.selectedPlayer, colorId)); } } - else if (role == RoleTypes__Enum::GuardianAngel) { + else if (State.RealRole == RoleTypes__Enum::GuardianAngel && role == RoleTypes__Enum::GuardianAngel) { app::GuardianAngelRole* guardianAngelRole = (app::GuardianAngelRole*)playerRole; if (guardianAngelRole->fields.cooldownSecondsRemaining <= 0 && ImGui::Button("Protect Player")) { if (IsInGame()) @@ -451,8 +451,11 @@ namespace PlayersTab { ImGui::SameLine(); if (!State.InMeeting) { if (ImGui::Button("Self-Report")) { - if (!(IsHost() || !State.SafeMode)) State.rpcQueue.push(new RpcReportBody(State.selectedPlayer)); - State.rpcQueue.push(new RpcForceMeeting(selectedPlayer.get_PlayerControl(), State.selectedPlayer)); + if (IsHost() || !State.SafeMode) State.rpcQueue.push(new RpcForceReportBody(selectedPlayer.get_PlayerControl(), selectedPlayer)); + else { + State.rpcQueue.push(new RpcReportBody(selectedPlayer)); + State.rpcQueue.push(new RpcForceMeeting(selectedPlayer.get_PlayerControl(), selectedPlayer)); + } } } else { @@ -544,7 +547,6 @@ namespace PlayersTab { } } - if (!State.SafeMode && ImGui::Button("Impersonate Everyone To")) { app::GameData_PlayerOutfit* outfit = GetPlayerOutfit(selectedPlayer.get_PlayerData()); auto petId = outfit->fields.PetId; @@ -601,6 +603,14 @@ namespace PlayersTab { } } } + + if (IsInLobby() && ImGui::Button("Allow Player to NoClip")) { + if (selectedPlayer.is_LocalPlayer()) State.NoClip = true; + else State.lobbyRpcQueue.push(new RpcMurderLoop(*Game::pLocalPlayer, selectedPlayer.get_PlayerControl(), 1, true)); + ShowHudNotification(std::format("Allowed {} to NoClip!", + convert_from_string(GameData_PlayerInfo_get_PlayerName(selectedPlayer.get_PlayerData(), NULL)))); + } + if (!State.SafeMode) { if (ImGui::Button("Suicide")) { if (IsInGame()) { @@ -758,16 +768,16 @@ namespace PlayersTab { } } - if ((IsInGame() || IsInLobby()) && !selectedPlayer.is_Disconnected() && selectedPlayer.has_value()) + if ((IsInGame() || IsInLobby()) && selectedPlayer.has_value()) { - if (State.playerToAttach.equals(State.selectedPlayer) && State.ActiveAttach && (selectedPlayer.is_LocalPlayer() && selectedPlayer.has_value())) { + if ((State.playerToAttach.equals(State.selectedPlayer) && State.ActiveAttach) || (selectedPlayer.is_LocalPlayer() && selectedPlayer.has_value())) { if (ImGui::Button("Stop Attaching")) { State.playerToAttach = {}; State.ActiveAttach = false; } } else { - if (ImGui::Button("Attach To")) { + if (ImGui::Button("Attach To") && !selectedPlayer.is_LocalPlayer()) { State.playerToAttach = State.selectedPlayer; State.ActiveAttach = true; } diff --git a/gui/tabs/self_tab.cpp b/gui/tabs/self_tab.cpp index 2bc1d78..d1d18ab 100644 --- a/gui/tabs/self_tab.cpp +++ b/gui/tabs/self_tab.cpp @@ -236,6 +236,10 @@ namespace SelfTab { State.Save(); } + if (ToggleButton("Unlock Kill Button", &State.UnlockKillButton)) { + State.Save(); + } + ImGui::SameLine(); if (ToggleButton("Shapeshift without Animation", &State.AnimationlessShapeshift)) { State.Save(); } @@ -284,7 +288,7 @@ namespace SelfTab { if (!State.SafeMode && ToggleButton("Hold ALT to Teleport Everyone", &State.TeleportEveryone)) { State.Save(); } - if (ToggleButton("Rotate Everyone", &State.RotateEveryone)) { + if (ToggleButton((State.SafeMode ? "Rotate Everyone (Client-sided ONLY)" : "Rotate Everyone"), &State.RotateEveryone)) { State.Save(); } if (!State.SafeMode) ImGui::SameLine(); @@ -448,16 +452,16 @@ namespace SelfTab { if (ImGui::CollapsingHeader("Cycler Name Options")) { - if (CustomListBoxInt("Random Name Generation###Cycler", &State.cyclerNameGeneration, NAMEGENERATION, 75 * State.dpiScale)) { + if (CustomListBoxInt("Cycler Name Generation", &State.cyclerNameGeneration, NAMEGENERATION, 75 * State.dpiScale)) { State.Save(); } if (State.cyclerNameGeneration == 2) { if (State.cyclerUserNames.empty()) ImGui::TextColored(ImVec4(1.0f, 0.0f, 0.0f, 1.0f), "Username generation will fall back to word combo as you have no names in the cycler."); static std::string newName = ""; - InputString("New Name###Cycler", &newName, ImGuiInputTextFlags_EnterReturnsTrue); + InputString("New Name", &newName, ImGuiInputTextFlags_EnterReturnsTrue); ImGui::SameLine(); - if (ImGui::Button("Add Name###Cycler")) { + if (ImGui::Button("Add Name")) { State.cyclerUserNames.push_back(newName); State.Save(); newName = ""; @@ -472,9 +476,9 @@ namespace SelfTab { for (size_t i = 0; i < State.cyclerUserNames.size(); i++) { nameVector[i] = State.cyclerUserNames[i].c_str(); } - CustomListBoxInt("Select Name to Delete###Cycler", &selectedNameIndex, nameVector); + CustomListBoxInt("Cycler Name to Delete", &selectedNameIndex, nameVector); ImGui::SameLine(); - if (ImGui::Button("Delete###Cycler")) + if (ImGui::Button("Delete")) State.cyclerUserNames.erase(State.cyclerUserNames.begin() + selectedNameIndex); } } @@ -548,16 +552,16 @@ namespace SelfTab { } } if (ImGui::CollapsingHeader("Confuser Name Options")) { - if (CustomListBoxInt("Random Name Generation###Cycler", &State.confuserNameGeneration, NAMEGENERATION, 75 * State.dpiScale)) { + if (CustomListBoxInt("Confuser Name Generation", &State.confuserNameGeneration, NAMEGENERATION, 75 * State.dpiScale)) { State.Save(); } if (State.confuserNameGeneration == 2) { if (State.cyclerUserNames.empty()) ImGui::TextColored(ImVec4(1.0f, 0.0f, 0.0f, 1.0f), "Username generation will fall back to word combo as you have no names in the cycler."); static std::string newName = ""; - InputString("New Name###Cycler", &newName, ImGuiInputTextFlags_EnterReturnsTrue); + InputString("New Name ", &newName, ImGuiInputTextFlags_EnterReturnsTrue); ImGui::SameLine(); - if (ImGui::Button("Add Name###Cycler")) { + if (ImGui::Button("Add Name ")) { State.cyclerUserNames.push_back(newName); State.Save(); newName = ""; @@ -572,9 +576,9 @@ namespace SelfTab { for (size_t i = 0; i < State.cyclerUserNames.size(); i++) { nameVector[i] = State.cyclerUserNames[i].c_str(); } - CustomListBoxInt("Select Name to Delete###Cycler", &selectedNameIndex, nameVector); + CustomListBoxInt("Confuser Name to Delete", &selectedNameIndex, nameVector); ImGui::SameLine(); - if (ImGui::Button("Delete###Cycler")) + if (ImGui::Button("Delete ")) State.cyclerUserNames.erase(State.cyclerUserNames.begin() + selectedNameIndex); } } diff --git a/hooks/Doors.cpp b/hooks/Doors.cpp index e13efc7..cf1603a 100644 --- a/hooks/Doors.cpp +++ b/hooks/Doors.cpp @@ -4,21 +4,21 @@ #include "_rpc.h" void dPlainDoor_SetDoorway(PlainDoor* __this, bool open, MethodInfo* method) { - if (open && (std::find(State.pinnedDoors.begin(), State.pinnedDoors.end(), __this->fields._.Room) != State.pinnedDoors.end())) { + if (__this->fields.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::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())) { + if (__this->fields.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) { + if (__this->fields._.Open && (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)); } return app::AutoOpenDoor_DoUpdate(__this, dt, method); diff --git a/hooks/HudManager.cpp b/hooks/HudManager.cpp index f6d09c3..02bac3f 100644 --- a/hooks/HudManager.cpp +++ b/hooks/HudManager.cpp @@ -75,20 +75,29 @@ void dHudManager_Update(HudManager* __this, MethodInfo* method) { } else { - app::GameObject_SetActive(ImpostorVentButton, (State.UnlockVents || (((*Game::pLocalPlayer)->fields.inVent && role == RoleTypes__Enum::Engineer)) || (PlayerIsImpostor(localData) && GameOptions().GetGameMode() == GameModes__Enum::Normal) && !State.PanicMode), nullptr); + app::GameObject_SetActive(ImpostorVentButton, (State.UnlockVents && !State.PanicMode) || (((*Game::pLocalPlayer)->fields.inVent && role == RoleTypes__Enum::Engineer)) || (PlayerIsImpostor(localData) && GameOptions().GetGameMode() == GameModes__Enum::Normal), nullptr); } - if ((IsInGame() || IsInLobby()) && !State.PanicMode) { + if ((IsInGame() || IsInLobby())) { for (auto player : GetAllPlayerControl()) { auto playerInfo = GetPlayerData(player); if (!playerInfo) break; //This happens sometimes during loading - if (State.KillImpostors && !playerInfo->fields.IsDead && PlayerIsImpostor(localData)) + if (!State.PanicMode && State.KillImpostors && !playerInfo->fields.IsDead && PlayerIsImpostor(localData)) playerInfo->fields.Role->fields.CanBeKilled = true; else if (PlayerIsImpostor(playerInfo)) playerInfo->fields.Role->fields.CanBeKilled = false; } + GameObject* KillButton = app::Component_get_gameObject((Component_1*)__this->fields.KillButton, NULL); + if ((!State.PanicMode && State.UnlockKillButton && !localData->fields.IsDead) || PlayerIsImpostor(localData)) { + app::GameObject_SetActive(KillButton, true, nullptr); + playerRole->fields.CanUseKillButton = true; + } + else { + app::GameObject_SetActive(KillButton, false, nullptr); + playerRole->fields.CanUseKillButton = false; + } } } } @@ -134,7 +143,7 @@ void dPingTracker_Update(PingTracker* __this, MethodInfo* method) { std::string hostText = State.ShowHost ? (IsHost() ? "\nYou are Host" : std::format("\nHost: {}", GetHostUsername(true))) : ""; std::string voteKicksText = (State.ShowVoteKicks && State.VoteKicks > 0) ? std::format("\nVote Kicks: {}", State.VoteKicks) : ""; - std::string pingText = std::format("<#0f0>Sicko<#f00>Menu <#fb0>{} by <#9ef>goaty ~ {}{}{}{}{}{}{}", State.SickoVersion, ping, fpsText, hostText, autoKill, noClip, freeCam, spectating); + std::string pingText = std::format("<#0f0>Sicko<#f00>Menu <#fb0>{} by <#9ef>goaty ~ {}{}{}{}{}{}{}", State.SickoVersion, ping, fpsText, hostText, voteKicksText, autoKill, noClip, freeCam, spectating); app::TMP_Text_set_alignment((app::TMP_Text*)__this->fields.text, app::TextAlignmentOptions__Enum::TopRight, nullptr); app::TMP_Text_set_text((app::TMP_Text*)__this->fields.text, convert_to_string(pingText), nullptr); } diff --git a/hooks/InnerNetClient.cpp b/hooks/InnerNetClient.cpp index 1df607f..172603d 100644 --- a/hooks/InnerNetClient.cpp +++ b/hooks/InnerNetClient.cpp @@ -252,7 +252,8 @@ void dInnerNetClient_Update(InnerNetClient* __this, MethodInfo* method) } if (IsInGame()) { (*Game::pLocalPlayer)->fields.RemainingEmergencies = 69420; - (*Game::pShipStatus)->fields.EmergencyCooldown = 0.f; + //if (GameOptions().HasOptions()) + //(*Game::pShipStatus)->fields.EmergencyCooldown = (float)GameOptions().GetInt(app::Int32OptionNames__Enum::EmergencyCooldown); } } } @@ -363,10 +364,10 @@ void dInnerNetClient_Update(InnerNetClient* __this, MethodInfo* method) } static int nameChangeCycleDelay = 0; //If we spam too many name changes, we're banned - if ((nameChangeCycleDelay <= 0 && State.SetName && !State.activeImpersonation && !State.ServerSideCustomName) || onStart) { + if (nameChangeCycleDelay <= 0 && State.SetName && !State.activeImpersonation && !State.ServerSideCustomName) { if ((((IsInGame() || IsInLobby()) && (convert_from_string(GameData_PlayerOutfit_get_PlayerName(GetPlayerOutfit(GetPlayerData(*Game::pLocalPlayer)), nullptr)) != State.userName)) || ((!IsInGame() && !IsInLobby()) && GetPlayerName() != State.userName)) - && !State.userName.empty() && (!IsNameValid(State.userName) || (IsHost() || !State.SafeMode))) { + && !State.userName.empty() && (IsNameValid(State.userName) || (IsHost() || !State.SafeMode))) { SetPlayerName(State.userName); LOG_INFO("Name mismatch, setting name to \"" + State.userName + "\""); if (IsInGame()) @@ -651,18 +652,14 @@ void dInnerNetClient_Update(InnerNetClient* __this, MethodInfo* method) State.RgbColor.z = color_b; } - static int attachDelay = 0; //If we spam too many name changes, we're banned + //static int attachDelay = 0; //If we spam too many name changes, we're banned auto playerToAttach = State.playerToAttach.validate(); - if (attachDelay <= 0 && State.ActiveAttach && State.playerToAttach.has_value()) { + if (State.ActiveAttach && State.playerToAttach.has_value()) { if (IsInGame()) State.rpcQueue.push(new RpcSnapTo(GetTrueAdjustedPosition(playerToAttach.get_PlayerControl()))); else if (IsInLobby()) State.lobbyRpcQueue.push(new RpcSnapTo(GetTrueAdjustedPosition(playerToAttach.get_PlayerControl()))); - attachDelay = 25; //Should be approximately 0.5 second - } - else { - attachDelay--; } // Shift + Right-click Teleport diff --git a/hooks/PlayerControl.cpp b/hooks/PlayerControl.cpp index 547f3cc..8058b1e 100644 --- a/hooks/PlayerControl.cpp +++ b/hooks/PlayerControl.cpp @@ -587,19 +587,24 @@ void dPlayerControl_FixedUpdate(PlayerControl* __this, MethodInfo* method) { BYTE arr[256]; if (GetKeyboardState(arr) && !State.ChatFocused) { + float xOffset = 0, yOffset = 0; if ((arr[0x57] & 0x80) != 0) { - State.camPos.y = State.camPos.y + (0.1f * State.FreeCamSpeed); + yOffset = 1; } if ((arr[0x41] & 0x80) != 0) { - State.camPos.x = State.camPos.x - (0.1f * State.FreeCamSpeed); + xOffset = -1; } if ((arr[0x53] & 0x80) != 0) { - State.camPos.y = State.camPos.y - (0.1f * State.FreeCamSpeed); + yOffset = -1; } if ((arr[0x44] & 0x80) != 0) { - State.camPos.x = State.camPos.x + (0.1f * State.FreeCamSpeed); + xOffset = 1; } + float magnitude = (xOffset == 0 && yOffset == 0) ? 1 : sqrt(xOffset * xOffset + yOffset * yOffset); + //check for zero and prevent you from moving ~1.414 times faster diagonally + State.camPos.x += float(0.1f * State.FreeCamSpeed * xOffset / magnitude); + State.camPos.y += float(0.1f * State.FreeCamSpeed * yOffset / magnitude); } Transform_set_position(cameraTransform, { State.camPos.x, State.camPos.y }, NULL); @@ -814,7 +819,7 @@ void dPlayerControl_CmdCheckMurder(PlayerControl* __this, PlayerControl* target, if (!State.PanicMode) { if (State.DisableKills || (State.GodMode && __this == *Game::pLocalPlayer)) return; - if (State.AlwaysUseKillExploit) + if (State.AlwaysUseKillExploit || State.NoAbilityCD) PlayerControl_RpcMurderPlayer(*Game::pLocalPlayer, target, target->fields.protectedByGuardianId < 0 || State.BypassAngelProt, NULL); else if (IsInLobby()) PlayerControl_RpcMurderPlayer(*Game::pLocalPlayer, target, target->fields.protectedByGuardianId < 0 || State.BypassAngelProt, NULL); @@ -830,20 +835,20 @@ void dPlayerControl_CmdCheckMurder(PlayerControl* __this, PlayerControl* target, void dPlayerControl_RpcShapeshift(PlayerControl* __this, PlayerControl* target, bool animate, MethodInfo* method) { - if (!State.PanicMode && __this == *Game::pLocalPlayer) PlayerControl_RpcShapeshift(__this, target, (State.PanicMode ? animate : (!State.AnimationlessShapeshift || animate)), method); + if (!State.PanicMode && __this == *Game::pLocalPlayer) PlayerControl_RpcShapeshift(__this, target, (State.PanicMode ? animate : (!State.AnimationlessShapeshift && animate)), method); else PlayerControl_RpcShapeshift(__this, target, animate, method); } void dPlayerControl_CmdCheckShapeshift(PlayerControl* __this, PlayerControl* target, bool animate, MethodInfo* method) { - if (!State.PanicMode && !State.SafeMode && __this == *Game::pLocalPlayer) PlayerControl_RpcShapeshift(__this, target, (!State.AnimationlessShapeshift || animate), method); - else PlayerControl_CmdCheckShapeshift(__this, target, (State.PanicMode ? animate : (!State.AnimationlessShapeshift || animate)), method); + if (!State.PanicMode && !State.SafeMode && __this == *Game::pLocalPlayer) PlayerControl_RpcShapeshift(__this, target, (!State.AnimationlessShapeshift && animate), method); + else PlayerControl_CmdCheckShapeshift(__this, target, (State.PanicMode ? animate : (!State.AnimationlessShapeshift && animate)), method); } void dPlayerControl_CmdCheckRevertShapeshift(PlayerControl* __this, bool animate, MethodInfo* method) { - if (!State.PanicMode && !State.SafeMode && __this == *Game::pLocalPlayer) PlayerControl_RpcShapeshift(__this, __this, (!State.AnimationlessShapeshift || animate), method); - else PlayerControl_CmdCheckRevertShapeshift(__this, (State.PanicMode ? animate : (!State.AnimationlessShapeshift || animate)), method); + if (!State.PanicMode && !State.SafeMode && __this == *Game::pLocalPlayer) PlayerControl_RpcShapeshift(__this, __this, (!State.AnimationlessShapeshift && animate), method); + else PlayerControl_CmdCheckRevertShapeshift(__this, (State.PanicMode ? animate : (!State.AnimationlessShapeshift && animate)), method); } /*void dPlayerControl_RpcRevertShapeshift(PlayerControl* __this, bool animate, MethodInfo* method) @@ -887,6 +892,15 @@ void dPlayerControl_HandleRpc(PlayerControl* __this, uint8_t callId, MessageRead (State.DisableSabotages && (callId == (uint8_t)RpcCalls__Enum::CloseDoorsOfType || callId == (uint8_t)RpcCalls__Enum::UpdateSystem)) || (State.DisableKills && callId == (uint8_t)RpcCalls__Enum::CheckMurder))) //we cannot prevent murderplayer because the player will force it return; + int crew = 0, imp = 0; + for (auto p : GetAllPlayerData()) { + if (p->fields.IsDead) continue; + PlayerIsImpostor(p) ? imp++ : crew++; + } + bool shouldCheckMeeting = (imp >= crew) || imp == 0; + if (State.NoGameEnd && shouldCheckMeeting && + (callId == (uint8_t)RpcCalls__Enum::ReportDeadBody || callId == (uint8_t)RpcCalls__Enum::StartMeeting)) + return; } } catch (...) { @@ -1043,6 +1057,51 @@ void dPlayerControl_RemoveProtection(PlayerControl* __this, MethodInfo* method) PlayerControl_RemoveProtection(__this, method); } +void dKillButton_SetTarget(KillButton* __this, PlayerControl* target, MethodInfo* method) { + auto result = target; + bool amImpostor = PlayerIsImpostor(GetPlayerData(*Game::pLocalPlayer)); + if (State.UnlockKillButton && !amImpostor) { + if (!State.PanicMode && result == nullptr) { + PlayerControl* new_result = nullptr; + float defaultKillDist = 2.5f; + auto killDistSetting = GameOptions().GetInt(Int32OptionNames__Enum::KillDistance); + switch (killDistSetting) { + case 0: + defaultKillDist = 1.f; + break; //short + case 1: + defaultKillDist = 1.8f; + break; //medium + case 2: + defaultKillDist = 2.5f; + break; //long + } + float max_dist = State.InfiniteKillRange ? FLT_MAX : defaultKillDist; //medium kill distance is 1.8 + auto localPos = GetTrueAdjustedPosition(*Game::pLocalPlayer); + for (auto p : GetAllPlayerControl()) { + if (p == *Game::pLocalPlayer) continue; //we don't want to kill ourselves + auto pData = GetPlayerData(p); + if (PlayerIsImpostor(pData) && !State.KillImpostors) continue; //neither impostors + if (pData->fields.IsDead) continue; //nor ghosts + float currentDist = GetDistanceBetweenPoints_Unity(GetTrueAdjustedPosition(p), localPos); + if (currentDist < max_dist) { + new_result = p; + max_dist = currentDist; + } + } + result = new_result; + } + + if (!State.PanicMode && result != nullptr && State.AutoKill && (State.AlwaysMove || PlayerControl_get_CanMove(*Game::pLocalPlayer, NULL)) && (*Game::pLocalPlayer)->fields.killTimer <= 0.f) { + if (IsInGame()) State.rpcQueue.push(new RpcMurderPlayer(*Game::pLocalPlayer, result)); + else State.lobbyRpcQueue.push(new RpcMurderPlayer(*Game::pLocalPlayer, result)); + } + KillButton_SetTarget(__this, result, NULL); + } + else if (amImpostor) KillButton_SetTarget(__this, result, NULL); + else KillButton_SetTarget(__this, NULL, NULL); +} + PlayerControl* dImpostorRole_FindClosestTarget(ImpostorRole* __this, MethodInfo* method) { auto result = ImpostorRole_FindClosestTarget(__this, method); if (!State.PanicMode && result == nullptr && State.InfiniteKillRange) { diff --git a/hooks/ShipStatus.cpp b/hooks/ShipStatus.cpp index 7617369..46bd6a7 100644 --- a/hooks/ShipStatus.cpp +++ b/hooks/ShipStatus.cpp @@ -70,10 +70,11 @@ void dShipStatus_RpcCloseDoorsOfType (ShipStatus* __this, SystemTypes__Enum type void dGameStartManager_Update(GameStartManager* __this, MethodInfo* method) { try { if (State.HideCode && IsStreamerMode() && !State.PanicMode) { + std::string customCode = State.HideCode ? State.customCode : "******"; if (State.RgbLobbyCode) - TMP_Text_set_text((TMP_Text*)__this->fields.GameRoomNameCode, convert_to_string(State.rgbCode + State.customCode), NULL); + TMP_Text_set_text((TMP_Text*)__this->fields.GameRoomNameCode, convert_to_string(State.rgbCode + customCode), NULL); else - TMP_Text_set_text((TMP_Text*)__this->fields.GameRoomNameCode, convert_to_string(State.customCode), NULL); + TMP_Text_set_text((TMP_Text*)__this->fields.GameRoomNameCode, convert_to_string(customCode), NULL); } else { std::string LobbyCode = convert_from_string(InnerNet_GameCode_IntToGameName((*Game::pAmongUsClient)->fields._.GameId, NULL)); diff --git a/hooks/_hooks.cpp b/hooks/_hooks.cpp index 5d3be26..15aa122 100644 --- a/hooks/_hooks.cpp +++ b/hooks/_hooks.cpp @@ -41,7 +41,7 @@ void DetourInitilization() { return; } else { // Attempting to hook the Steam overlay - do { + /*do { if (oPresent) break; HMODULE hModule = GetModuleHandleA("GameOverlayRenderer.dll"); @@ -60,10 +60,12 @@ void DetourInitilization() { #endif return; } - oPresent = d3d11.presentFunction; - } while (0); + LOG_ERROR("Failed to hook the Steam overlay D3DPresent function. This may cause the menu to be visible to streaming applications."); + //move to logs so user doesn't get a popup every time + //oPresent = d3d11.presentFunction; + } while (0);*/ // Attempting to hook the Epic overlay - do { + /*do { if (oPresent) break; HMODULE hModule = GetModuleHandleA("EOSOVH-Win32-Shipping.dll"); @@ -82,8 +84,10 @@ void DetourInitilization() { #endif return; } - oPresent = d3d11.presentFunction; - } while (0); + LOG_ERROR("Failed to hook the Epic overlay D3DPresent function. This may cause the menu to be visible to streaming applications."); + //move to logs so user doesn't get a popup every time + //oPresent = d3d11.presentFunction; + } while (0);*/ if (!oPresent) oPresent = d3d11.presentFunction; } @@ -181,6 +185,7 @@ void DetourInitilization() { //HOOKFUNC(ActivityManager_UpdateActivity); HOOKFUNC(PingTracker_Update); HOOKFUNC(KillOverlay_ShowKillAnimation_1); + HOOKFUNC(KillButton_SetTarget); HOOKFUNC(ImpostorRole_FindClosestTarget); HOOKFUNC(MushroomDoorSabotageMinigame_Begin); //HOOKFUNC(AmongUsClient_CoStartGameHost); @@ -301,6 +306,7 @@ void DetourUninitialization() //UNHOOKFUNC(ActivityManager_UpdateActivity); UNHOOKFUNC(PingTracker_Update); UNHOOKFUNC(KillOverlay_ShowKillAnimation_1); + UNHOOKFUNC(KillButton_SetTarget); UNHOOKFUNC(ImpostorRole_FindClosestTarget); UNHOOKFUNC(MushroomDoorSabotageMinigame_Begin); //UNHOOKFUNC(AmongUsClient_CoStartGameHost); diff --git a/hooks/_hooks.h b/hooks/_hooks.h index 45e7f2c..10317e9 100644 --- a/hooks/_hooks.h +++ b/hooks/_hooks.h @@ -98,6 +98,7 @@ void dExileController_ReEnableGameplay(ExileController* __this, MethodInfo* meth //void dActivityManager_UpdateActivity(void* __this, Activity_1 activity, void* callback, MethodInfo* method); void dPingTracker_Update(PingTracker* __this, MethodInfo* method); void dKillOverlay_ShowKillAnimation_1(KillOverlay* __this, GameData_PlayerInfo* killer, GameData_PlayerInfo* victim, MethodInfo* method); +void dKillButton_SetTarget(KillButton* __this, PlayerControl* target, MethodInfo* method); PlayerControl* dImpostorRole_FindClosestTarget(ImpostorRole* __this, MethodInfo* method); void dMushroomDoorSabotageMinigame_Begin(MushroomDoorSabotageMinigame* __this, PlayerTask* task, MethodInfo* method); //void* dAmongUsClient_CoStartGameHost(AmongUsClient* __this, MethodInfo* method); diff --git a/rpc/RpcMurderPlayer.cpp b/rpc/RpcMurderPlayer.cpp index 5f8af43..55c5167 100644 --- a/rpc/RpcMurderPlayer.cpp +++ b/rpc/RpcMurderPlayer.cpp @@ -39,6 +39,48 @@ void RpcMurderPlayer::Process() } } +RpcMurderLoop::RpcMurderLoop(PlayerControl* Player, PlayerControl* target, int count, bool onlyOnTarget) +{ + this->Player = Player; + this->target = target; + this->count = count; + this->onlyOnTarget = onlyOnTarget; +} + +void RpcMurderLoop::Process() +{ + if (onlyOnTarget && (IsInMultiplayerGame() || IsInLobby())) { + for (size_t i = 1; i <= (size_t)count; ++i) { + if (!PlayerSelection(Player).has_value() || !PlayerSelection(target).has_value()) break; + auto writer = InnerNetClient_StartRpcImmediately((InnerNetClient*)(*Game::pAmongUsClient), Player->fields._.NetId, + uint8_t(RpcCalls__Enum::MurderPlayer), SendOption__Enum::None, target->fields._.OwnerId, NULL); + MessageExtensions_WriteNetObject(writer, (InnerNetObject*)target, NULL); + MessageWriter_WriteInt32(writer, int32_t(MurderResultFlags__Enum::Succeeded), NULL); + InnerNetClient_FinishRpcImmediately((InnerNetClient*)(*Game::pAmongUsClient), writer, NULL); + } + } + else if (IsInLobby() && target == *Game::pLocalPlayer) { + for (size_t i = 1; i <= (size_t)count; ++i) { + if (!PlayerSelection(Player).has_value() || !PlayerSelection(target).has_value()) break; + for (auto p : GetAllPlayerControl()) { + if (p != *Game::pLocalPlayer) { + auto writer = InnerNetClient_StartRpcImmediately((InnerNetClient*)(*Game::pAmongUsClient), Player->fields._.NetId, + uint8_t(RpcCalls__Enum::MurderPlayer), SendOption__Enum::None, p->fields._.OwnerId, NULL); + MessageWriter_WriteInt32(writer, int32_t(MurderResultFlags__Enum::Succeeded), NULL); + MessageExtensions_WriteNetObject(writer, (InnerNetObject*)target, NULL); + InnerNetClient_FinishRpcImmediately((InnerNetClient*)(*Game::pAmongUsClient), writer, NULL); + } + } + } + } + else { + for (size_t i = 1; i <= (size_t)count; ++i) { + if (!PlayerSelection(Player).has_value() || !PlayerSelection(target).has_value()) break; + PlayerControl_RpcMurderPlayer(Player, target, true, NULL); + } + } +} + //damn im too lazy to add new files RpcShapeshift::RpcShapeshift(PlayerControl* Player, const PlayerSelection& target, bool animate) @@ -301,7 +343,7 @@ void RpcForceAumChat::Process() std::string chatVisual = "<#f55>[AUM Chat]\n" + msg; ChatController_AddChat(Game::HudManager.GetInstance()->fields.Chat, player, convert_to_string(chatVisual), false, NULL); } - +/* RpcSyncSettings::RpcSyncSettings() { } @@ -312,4 +354,4 @@ void RpcSyncSettings::Process() GameOptionsFactory* gameOptionsFactory = (GameOptionsFactory*)((InnerNetClient*)(*Game::pAmongUsClient))->fields.gameOptionsFactory; Byte__Array* arr = GameOptionsFactory_ToBytes(gameOptionsFactory, iGameOptions, false, NULL); for (auto p : GetAllPlayerControl()) PlayerControl_RpcSyncSettings(p, arr, NULL); -} \ No newline at end of file +}*/ \ No newline at end of file diff --git a/rpc/_rpc.h b/rpc/_rpc.h index 71fcda6..1879b9c 100644 --- a/rpc/_rpc.h +++ b/rpc/_rpc.h @@ -171,6 +171,16 @@ class RpcMurderPlayer : public RPCInterface { virtual void Process() override; }; +class RpcMurderLoop : public RPCInterface { + PlayerControl* Player; + PlayerControl* target; + int count; + bool onlyOnTarget; +public: + RpcMurderLoop(PlayerControl* Player, PlayerControl* target, int count = 30, bool onlyOnTarget = true); + virtual void Process() override; +}; + class RpcShapeshift : public RPCInterface { PlayerControl* Player; PlayerSelection target; @@ -395,8 +405,8 @@ class RpcForceAumChat : public RPCInterface { virtual void Process() override; }; -class RpcSyncSettings : public RPCInterface { +/*class RpcSyncSettings : public RPCInterface { public: RpcSyncSettings(); virtual void Process() override; -}; \ No newline at end of file +};*/ \ No newline at end of file diff --git a/user/main.cpp b/user/main.cpp index 0c13bc6..0d0efb6 100644 --- a/user/main.cpp +++ b/user/main.cpp @@ -12,7 +12,7 @@ #include "version.h" #include #include -#include "gitparams.h" +//#include "gitparams.h" // test autoRelease main ver increment diff --git a/user/state.cpp b/user/state.cpp index bc51640..759654a 100644 --- a/user/state.cpp +++ b/user/state.cpp @@ -120,6 +120,7 @@ void Settings::Load() { JSON_TRYGET("FreeCamSpeed", this->FreeCamSpeed); JSON_TRYGET("ZoomLevel", this->CameraHeight); JSON_TRYGET("UnlockVents", this->UnlockVents); + JSON_TRYGET("UnlockKillButton", this->UnlockKillButton); JSON_TRYGET("ChatPaste", this->ChatPaste); JSON_TRYGET("RevealRoles", this->RevealRoles); JSON_TRYGET("AbbreviatedRoleNames", this->AbbreviatedRoleNames); @@ -301,6 +302,7 @@ void Settings::Save() { { "FreeCamSpeed", this->FreeCamSpeed }, { "ZoomLevel", this->CameraHeight }, { "UnlockVents", this->UnlockVents }, + { "UnlockKillButton", this->UnlockKillButton }, { "ChatPaste", this->ChatPaste }, { "RevealRoles", this->RevealRoles }, { "AbbreviatedRoleNames", this->AbbreviatedRoleNames }, diff --git a/user/state.hpp b/user/state.hpp index b05bb71..e079444 100644 --- a/user/state.hpp +++ b/user/state.hpp @@ -72,6 +72,7 @@ class Settings { float PrevCycleTimer = 0.5f; float CycleDuration = CycleTimer * 50; bool UnlockVents = false; + bool UnlockKillButton = false; bool ShowGhosts = false; int FakeRole = 0; bool AutoFakeRole = false; @@ -350,7 +351,7 @@ class Settings { Replay::Reset(); } - std::string SickoVersion = "v3.3.1"; + std::string SickoVersion = "v3.4"; void Load(); void Save(); diff --git a/user/utility.cpp b/user/utility.cpp index 5648e69..965011d 100644 --- a/user/utility.cpp +++ b/user/utility.cpp @@ -2,7 +2,7 @@ #include "utility.h" #include "state.hpp" #include "game.h" -#include "gitparams.h" +//#include "gitparams.h" #include "logger.h" #include "profiler.h" #include @@ -105,11 +105,12 @@ int GetMaxImpostorAmount(int playerAmount) if (State.CustomImpostorAmount) return State.ImpostorCount; if (options.GetGameMode() == GameModes__Enum::HideNSeek) - return 1; + return 1; //pointless to use min here if (playerAmount >= 9) - return 3; + return min(options.GetNumImpostors(), 3); if (playerAmount >= 7) - return 2; + return min(options.GetNumImpostors(), 2); + //fix issue #9 return 1; } @@ -697,7 +698,7 @@ std::string ToString(__maybenull GameData_PlayerInfo* data) { #define ADD_QUOTES_HELPER(s) #s #define ADD_QUOTES(s) ADD_QUOTES_HELPER(s) - +/* std::string GetGitCommit() { #ifdef GIT_CUR_COMMIT @@ -712,7 +713,7 @@ std::string GetGitBranch() return ADD_QUOTES(GIT_BRANCH); #endif return "unavailable"; -} +}*/ std::string operator*(std::string const& in, size_t m) { //python style string multiplication std::string ret; @@ -1148,6 +1149,11 @@ float GetDistanceBetweenPoints_ImGui(const ImVec2& p1, const ImVec2& p2) return sqrtf(dx * dx + dy * dy); } +void ShowHudNotification(std::string text) { + std::string notificationText = "<#fb0>[<#0f0>Sicko<#f00>Menu] " + text; + if (IsInGame() || IsInLobby()) NotificationPopper_AddItem(Game::HudManager.GetInstance()->fields.Notifier, convert_to_string(notificationText), NULL); +} + void DoPolylineSimplification(std::vector& inPoints, std::vector& inTimeStamps, std::vector& outPoints, std::vector& outTimeStamps, float sqDistanceThreshold, bool clearInputs) { sqDistanceThreshold = sqDistanceThreshold - FLT_EPSILON; diff --git a/user/utility.h b/user/utility.h index f106d60..f961e31 100644 --- a/user/utility.h +++ b/user/utility.h @@ -218,6 +218,7 @@ std::string GetRoleName(RoleBehaviour* roleBehaviour, bool abbreviated = false); RoleTypes__Enum GetRoleTypesEnum(RoleType role); float GetDistanceBetweenPoints_Unity(const Vector2& p1, const Vector2& p2); float GetDistanceBetweenPoints_ImGui(const ImVec2& p1, const ImVec2& p2); +void ShowHudNotification(std::string text); /// /// Simplifies a list of points by ensuring the distance between consecutive points is greater than the squared distance threshold; all other points are discarded.