Skip to content
This repository has been archived by the owner on Oct 10, 2024. It is now read-only.

Commit

Permalink
#302: Fix getting banned on shapeshifting / killing (#303)
Browse files Browse the repository at this point in the history
  • Loading branch information
DarkPenguin24 authored Feb 27, 2022
1 parent e346b59 commit aeb0563
Show file tree
Hide file tree
Showing 12 changed files with 158 additions and 25 deletions.
1 change: 1 addition & 0 deletions AmongUsMenu.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,7 @@
<ClInclude Include="gui\tabs\settings_tab.h" />
<ClInclude Include="gui\tabs\tasks_tab.h" />
<ClInclude Include="hooks\DirectX.h" />
<ClInclude Include="hooks\RoleManager.hpp" />
<ClInclude Include="hooks\SignatureScan.hpp" />
<ClInclude Include="hooks\_hooks.h" />
<ClInclude Include="includes\crc32.h" />
Expand Down
3 changes: 3 additions & 0 deletions AmongUsMenu.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,9 @@
<ClCompile Include="events\ProtectPlayerEvent.cpp">
<Filter>events</Filter>
</ClCompile>
<ClInclude Include="hooks\RoleManager.hpp">
<Filter>hooks</Filter>
</ClInclude>
<ClCompile Include="hooks\RoleManager.cpp">
<Filter>hooks</Filter>
</ClCompile>
Expand Down
1 change: 1 addition & 0 deletions appdata/il2cpp-functions.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ DO_APP_FUNC(void, TextMeshPro_SetOutlineColor, (TextMeshPro* __this, Color32 col
DO_APP_FUNC(void, TMP_Text_set_text, (TMP_Text* __this, String* value, MethodInfo* method), "Unity.TextMeshPro, System.Void TMPro.TMP_Text::set_text(System.String)");
DO_APP_FUNC(Color32, Color32_op_Implicit, (Color c, MethodInfo* method), "UnityEngine.CoreModule, UnityEngine.Color32 UnityEngine.Color32::op_Implicit(UnityEngine.Color)");

DO_APP_FUNC(void, RoleManager_SelectRoles, (RoleManager* __this, MethodInfo* method), "Assembly-CSharp, System.Void RoleManager::SelectRoles()");
DO_APP_FUNC(void, RoleManager_AssignRolesForTeam, (List_1_GameData_PlayerInfo_* players, RoleOptionsData* opts, RoleTeamTypes__Enum team, int32_t teamMax, Nullable_1_RoleTypes_ defaultRole, MethodInfo* method), "Assembly-CSharp, System.Void RoleManager::AssignRolesForTeam(System.Collections.Generic.List<GameData.PlayerInfo>, RoleOptionsData, RoleTeamTypes, System.Int32, System.Nullable<RoleTypes>)");
DO_APP_FUNC(void, RoleManager_AssignRolesFromList, (List_1_GameData_PlayerInfo_* players, int32_t teamMax, List_1_RoleTypes_* roleList, int32_t* rolesAssigned, MethodInfo* method), "Assembly-CSharp, System.Void RoleManager::AssignRolesFromList(System.Collections.Generic.List<GameData.PlayerInfo>, System.Int32, System.Collections.Generic.List<RoleTypes>, System.Int32&)");
DO_APP_FUNC(void, InnerNetClient_EnqueueDisconnect, (InnerNetClient* __this, DisconnectReasons__Enum reason, String* stringReason, MethodInfo* method), "Assembly-CSharp, System.Void InnerNet.InnerNetClient::EnqueueDisconnect(DisconnectReasons, System.String)");
Expand Down
40 changes: 27 additions & 13 deletions gui/tabs/host_tab.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,13 @@ namespace HostTab {
State.impostors_amount = GetRoleCount((int)RoleType::Impostor);
if (State.impostors_amount + State.shapeshifters_amount > maxImposterAmount)
{
State.assignedRoles[index] = (int)RoleType::Crewmate;
State.impostors_amount--;
}
else if (State.shapeshifters_amount + State.impostors_amount > maxImposterAmount)
{
State.assignedRoles[index] = (int)RoleType::Engineer;
State.shapeshifters_amount--;
if(State.assignedRoles[index] == (int)RoleType::Shapeshifter)
State.assignedRoles[index] = (int)RoleType::Engineer;
else if(State.assignedRoles[index] == (int)RoleType::Impostor)
State.assignedRoles[index] = (int)RoleType::Random;
}
State.shapeshifters_amount = GetRoleCount((int)RoleType::Shapeshifter);
State.impostors_amount = GetRoleCount((int)RoleType::Impostor);

if (!IsInGame())
{
Expand All @@ -49,12 +48,27 @@ namespace HostTab {
auto vectors = roleRates->fields.entries[0].vector;
for (auto iVector = 0; iVector < 32; iVector++)
{
if (vectors[iVector].key == RoleTypes__Enum::Engineer && State.engineers_amount > vectors[iVector].value.MaxCount)
vectors[iVector].value.MaxCount = State.engineers_amount;
else if (vectors[iVector].key == RoleTypes__Enum::Scientist && State.scientists_amount > vectors[iVector].value.MaxCount)
vectors[iVector].value.MaxCount = State.scientists_amount;
else if (vectors[iVector].key == RoleTypes__Enum::Shapeshifter && State.shapeshifters_amount > vectors[iVector].value.MaxCount)
vectors[iVector].value.MaxCount = State.shapeshifters_amount;
if (vectors[iVector].key == RoleTypes__Enum::Engineer)
{
if(State.engineers_amount > 0)
vectors[iVector].value.Chance = 100;
if(State.engineers_amount > vectors[iVector].value.MaxCount)
vectors[iVector].value.MaxCount = State.engineers_amount;
}
else if (vectors[iVector].key == RoleTypes__Enum::Scientist)
{
if(State.scientists_amount > 0)
vectors[iVector].value.Chance = 100;
if(State.scientists_amount > vectors[iVector].value.MaxCount)
vectors[iVector].value.MaxCount = State.scientists_amount;
}
else if (vectors[iVector].key == RoleTypes__Enum::Shapeshifter)
{
if(State.shapeshifters_amount > 0)
vectors[iVector].value.Chance = 100;
if(State.shapeshifters_amount > vectors[iVector].value.MaxCount)
vectors[iVector].value.MaxCount = State.shapeshifters_amount;
}
}
}

Expand Down
2 changes: 0 additions & 2 deletions hooks/GameOptionsData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ GameOptionsData* dGameOptionsData_Deserialize(BinaryReader* reader, MethodInfo*
State.TaskBarUpdates = (int)gameOptions->fields.TaskBarMode;
State.mapHostChoice = gameOptions->fields.MapId;
State.impostors_amount = gameOptions->fields.NumImpostors;
State.RoleOptions = gameOptions->fields.RoleOptions;

return gameOptions;
}
Expand All @@ -29,7 +28,6 @@ GameOptionsData* dGameOptionsData_Deserialize_1(MessageReader* reader, MethodInf
State.TaskBarUpdates = (int)gameOptions->fields.TaskBarMode;
State.mapHostChoice = gameOptions->fields.MapId;
State.impostors_amount = gameOptions->fields.NumImpostors;
State.RoleOptions = gameOptions->fields.RoleOptions;

return gameOptions;
}
77 changes: 74 additions & 3 deletions hooks/RoleManager.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "pch-il2cpp.h"
#include "RoleManager.hpp"
#include "_hooks.h"
#include "state.hpp"
#include "logger.h"
Expand All @@ -7,25 +8,95 @@
#include <random>
#include <algorithm>

void dRoleManager_SelectRoles(RoleManager* __this, MethodInfo* method) {
std::vector<uint8_t> assignedPlayers;
auto allPlayers = GetAllPlayerControl();
auto roleRates = RoleRates((*Game::pGameOptionsData)->fields.RoleOptions);

AssignPreChosenRoles(roleRates, assignedPlayers);
AssignRoles(roleRates.ShapeshifterCount, roleRates.ShapeshifterChance, RoleTypes__Enum::Shapeshifter, allPlayers, assignedPlayers);
AssignRoles(roleRates.ImposterCount, 100, RoleTypes__Enum::Impostor, allPlayers, assignedPlayers);
AssignRoles(roleRates.ScientistCount, roleRates.ScientistChance, RoleTypes__Enum::Scientist, allPlayers, assignedPlayers);
AssignRoles(roleRates.EngineerCount, roleRates.EngineerChance, RoleTypes__Enum::Engineer, allPlayers, assignedPlayers);
AssignRoles(roleRates.MaxCrewmates, 100, RoleTypes__Enum::Crewmate, allPlayers, assignedPlayers);
}

void dRoleManager_AssignRolesForTeam(List_1_GameData_PlayerInfo_* players, RoleOptionsData* opts, RoleTeamTypes__Enum team, int32_t teamMax, Nullable_1_RoleTypes_ defaultRole, MethodInfo* method) {
return RoleManager_AssignRolesForTeam(players, opts, team, teamMax, defaultRole, method);
}

void dRoleManager_AssignRolesFromList(List_1_GameData_PlayerInfo_* players, int32_t teamMax, List_1_RoleTypes_* roleList, int32_t* rolesAssigned, MethodInfo* method) {
dRoleManager_AssignPreChosenRoles(rolesAssigned);
return RoleManager_AssignRolesFromList(players, teamMax, roleList, rolesAssigned, method);
}

void dRoleManager_AssignPreChosenRoles(int32_t*& rolesAssigned)
void AssignPreChosenRoles(RoleRates& roleRates, std::vector<uint8_t>& assignedPlayers)
{
for (int i = 0; i < State.assignedRolesPlayer.size(); i++) {
auto role = State.assignedRoles[i];
auto player = State.assignedRolesPlayer[i];
if (player == nullptr)
break;
if (role == (int)RoleType::Random)
continue;

auto trueRole = GetRoleTypesEnum((RoleType)role);
if (trueRole == RoleTypes__Enum::Shapeshifter)
{
if (roleRates.ShapeshifterCount == 0)
continue;
roleRates.ShapeshifterCount--;
}
else if (trueRole == RoleTypes__Enum::Impostor)
{
if (roleRates.ImposterCount == 0)
continue;
roleRates.ImposterCount--;
}
else if (trueRole == RoleTypes__Enum::Scientist)
{
if (roleRates.ScientistCount == 0)
continue;
roleRates.ScientistCount--;
}
else if (trueRole == RoleTypes__Enum::Engineer)
{
if (roleRates.EngineerCount == 0)
continue;
roleRates.EngineerCount--;
}

PlayerControl_RpcSetRole(player, trueRole, NULL);
(*rolesAssigned)++;
assignedPlayers.push_back(player->fields.PlayerId);
}
}

void AssignRoles(int& roleCount, int roleChance, RoleTypes__Enum role, std::vector<app::PlayerControl*>& allPlayers, std::vector<uint8_t>& assignedPlayers)
{
if (roleCount == 0)
return;

std::vector<PlayerControl*> randomEngineers;
std::sample(allPlayers.begin(), allPlayers.end(), std::back_inserter(randomEngineers), roleCount, std::mt19937{ std::random_device{}() });
for (auto player : randomEngineers) {
if (player == nullptr) {
break;
}
if (std::find(assignedPlayers.begin(), assignedPlayers.end(), player->fields.PlayerId) != assignedPlayers.end()) {
continue;
}

if (roleChance < 100)
{
std::random_device dev;
std::mt19937 rng(dev());
std::uniform_int_distribution<std::mt19937::result_type> dist100(1, 100);
auto chance = 100 - dist100(rng);

if (chance <= roleChance)
continue;
}

PlayerControl_RpcSetRole(player, role, NULL);
assignedPlayers.push_back(player->fields.PlayerId);
}
}
5 changes: 5 additions & 0 deletions hooks/RoleManager.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#pragma once
#include "utility.h"

void AssignPreChosenRoles(RoleRates& roleRates, std::vector<uint8_t>& assignedPlayers);
void AssignRoles(int& roleCount, int roleChance, RoleTypes__Enum role, std::vector<app::PlayerControl*>& allPlayers, std::vector<uint8_t>& assignedPlayers);
4 changes: 4 additions & 0 deletions hooks/_hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ void DetourInitilization() {
HOOKFUNC(PlayerControl_CompleteTask);
HOOKFUNC(PlayerControl_CmdReportDeadBody);
HOOKFUNC(PlayerControl_ReportDeadBody);
HOOKFUNC(RoleManager_SelectRoles);
HOOKFUNC(RoleManager_AssignRolesForTeam);
HOOKFUNC(RoleManager_AssignRolesFromList);
HOOKFUNC(PlayerControl_HandleRpc);
HOOKFUNC(Renderer_set_enabled);
Expand Down Expand Up @@ -176,6 +178,8 @@ void DetourUninitialization()
UNHOOKFUNC(PlayerControl_CompleteTask);
UNHOOKFUNC(PlayerControl_CmdReportDeadBody);
UNHOOKFUNC(PlayerControl_ReportDeadBody);
UNHOOKFUNC(RoleManager_SelectRoles);
UNHOOKFUNC(RoleManager_AssignRolesForTeam);
UNHOOKFUNC(RoleManager_AssignRolesFromList);
UNHOOKFUNC(PlayerControl_HandleRpc);
UNHOOKFUNC(Renderer_set_enabled);
Expand Down
5 changes: 2 additions & 3 deletions hooks/_hooks.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@ void dPlayerControl_FixedUpdate(PlayerControl* __this, MethodInfo* method);
void dPlayerControl_MurderPlayer(PlayerControl* __this, PlayerControl* target, MethodInfo* method);
void dPlayerControl_CmdReportDeadBody(PlayerControl* __this, GameData_PlayerInfo* target, MethodInfo* method);
void dPlayerControl_ReportDeadBody(PlayerControl*__this, GameData_PlayerInfo* target, MethodInfo *method);
//void dPlayerControl_RpcSetRole(PlayerControl* __this, RoleTypes__Enum roleType, MethodInfo* method);
void dRoleManager_AssignRolesForTeam(List_1_GameData_PlayerInfo_* players, RoleOptionsData* opts, RoleTeamTypes__Enum team, int32_t teamMax, Nullable_1_RoleTypes_ defaultRole, MethodInfo* method);
void dPlayerControl_RpcSyncSettings(PlayerControl* __this, GameOptionsData* gameOptions, MethodInfo* method);
void dPlayerControl_HandleRpc(PlayerControl* __this, uint8_t callId, MessageReader* reader, MethodInfo* method);
void dPlayerControl_Shapeshift(PlayerControl* __this, PlayerControl* target, bool animate, MethodInfo* method);
Expand Down Expand Up @@ -69,8 +67,9 @@ void dEOSManager_ReallyBeginFlow(EOSManager* __this, MethodInfo* method);
bool dEOSManager_IsFreechatAllowed(EOSManager* __this, MethodInfo* method);
void dChatController_Update(ChatController* __this, MethodInfo* method);
void dInnerNetClient_EnqueueDisconnect(InnerNetClient* __this, DisconnectReasons__Enum reason, String* stringReason, MethodInfo* method);
void dRoleManager_SelectRoles(RoleManager* __this, MethodInfo * method);
void dRoleManager_AssignRolesForTeam(List_1_GameData_PlayerInfo_* players, RoleOptionsData* opts, RoleTeamTypes__Enum team, int32_t teamMax, Nullable_1_RoleTypes_ defaultRole, MethodInfo* method);
void dRoleManager_AssignRolesFromList(List_1_GameData_PlayerInfo_* players, int32_t teamMax, List_1_RoleTypes_* roleList, int32_t* rolesAssigned, MethodInfo* method);
void dRoleManager_AssignPreChosenRoles(int32_t*& rolesAssigned);
void dPlayerPhysics_FixedUpdate (PlayerPhysics* __this, MethodInfo* method);

// 55 8B EC 80 3D ? ? ? ? ? 75 14 68 ? ? ? ? E8 ? ? ? ? 83 C4 04 C6 05 ? ? ? ? ? 8B 45 0C 85 C0 74 3F 80 78 50 00
Expand Down
3 changes: 1 addition & 2 deletions user/state.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,6 @@ class Settings {
int shapeshifters_amount = 0;
int engineers_amount = 0;
int scientists_amount = 0;
RoleOptionsData* RoleOptions = nullptr;

bool Wallhack = false;
bool FreeCam = false;
Expand Down Expand Up @@ -150,7 +149,7 @@ class Settings {
bool ShowUnityLogs = true;

int LobbyTimer = -1;

std::string userName = "";

enum MapType : uint8_t
Expand Down
29 changes: 27 additions & 2 deletions user/utility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,31 @@ int randi(int lo, int hi) {
return lo + i;
}

RoleRates::RoleRates(RoleOptionsData* roleOptions) {
auto roleRates = roleOptions->fields.roleRates;
if (roleRates->fields.count != 0) {
auto vectors = roleRates->fields.entries[0].vector;
for (auto iVector = 0; iVector < 32; iVector++)
{
if (vectors[iVector].key == RoleTypes__Enum::Engineer)
{
this->EngineerChance = vectors[iVector].value.Chance;
this->EngineerCount = vectors[iVector].value.MaxCount;
}
else if (vectors[iVector].key == RoleTypes__Enum::Scientist)
{
this->ScientistChance = vectors[iVector].value.Chance;
this->ScientistCount = vectors[iVector].value.MaxCount;
}
else if (vectors[iVector].key == RoleTypes__Enum::Shapeshifter)
{
this->ShapeshifterChance = vectors[iVector].value.Chance;
this->ShapeshifterCount = vectors[iVector].value.MaxCount;
}
}
}
}

PlayerSelection::PlayerSelection()
{
this->hasValue = false;
Expand Down Expand Up @@ -377,7 +402,7 @@ const char* TranslateTaskTypes(TaskTypes__Enum taskType) {
"Inspect Sample", "Empty Chute", "Empty Garbage", "Align Engine Output", "Fix Wiring", "Calibrate Distributor", "Divert Power", "Unlock Manifolds", "Reset Reactor",
"Fix Lights", "Clean O2 Filter", "Fix Communications", "Restore Oxygen", "Stabilize Steering", "Assemble Artifact", "Sort Samples", "Measure Weather", "Enter ID Code",
"Buy Beverage", "Process Data", "Run Diagnostics", "Water Plants", "Monitor Oxygen", "Store Artifacts", "Fill Canisters", "Activate Weather Nodes", "Insert Keys",
"Reset Seismic Stabilizers", "Scan Boarding Pass", "Open Waterways", "Replace Water Jug", "Repair Drill", "Align Telecopse", "Record Temperature", "Reboot Wifi",
"Reset Seismic Stabilizers", "Scan Boarding Pass", "Open Waterways", "Replace Water Jug", "Repair Drill", "Align Telecopse", "Record Temperature", "Reboot Wifi",
"Polish Ruby", "Reset Breakers", "Decontaminate", "Make Burger", "Unlock Safe", "Sort Records", "Put Away Pistols", "Fix Shower", "Clean Toilet", "Dress Mannequin",
"Pick Up Towels", "Rewind Tapes", "Start Fans", "Develop Photos", "Get Biggol Sword", "Put Away Rifles", "Stop Charles", "Vent Cleaning"};
return TASK_TRANSLATIONS[(uint8_t)taskType];
Expand All @@ -387,7 +412,7 @@ const char* TranslateTaskTypes(TaskTypes__Enum taskType) {
const char* TranslateSystemTypes(SystemTypes__Enum systemType) {
static const char* const SYSTEM_TRANSLATIONS[] = { "Hallway", "Storage", "Cafeteria", "Reactor", "Upper Engine", "Navigation", "Admin", "Electrical", "Oxygen", "Shields",
"MedBay", "Security", "Weapons", "Lower Engine", "Communications", "Ship Tasks", "Doors", "Sabotage", "Decontamination", "Launchpad", "Locker Room", "Laboratory",
"Balcony", "Office", "Greenhouse", "Dropship", "Decontamination", "Outside", "Specimen Room", "Boiler Room", "Vault Room", "Cockpit", "Armory", "Kitchen", "Viewing Deck",
"Balcony", "Office", "Greenhouse", "Dropship", "Decontamination", "Outside", "Specimen Room", "Boiler Room", "Vault Room", "Cockpit", "Armory", "Kitchen", "Viewing Deck",
"Hall Of Portraits", "Cargo Bay", "Ventilation", "Showers", "Engine Room", "The Brig", "Meeting Room", "Records Room", "Lounge Room", "Gap Room", "Main Hall", "Medical" };
return SYSTEM_TRANSLATIONS[(uint8_t)systemType];
}
Expand Down
13 changes: 13 additions & 0 deletions user/utility.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,19 @@ enum RoleType
Shapeshifter = 5,
};

class RoleRates {
public:
int ImposterCount = 0;
int ShapeshifterCount = 0;
int ShapeshifterChance = 0;
int ScientistCount = 0;
int ScientistChance = 0;
int EngineerCount = 0;
int EngineerChance = 0;
int MaxCrewmates = 15;
RoleRates(RoleOptionsData* roleOptions);
};

class PlayerSelection {
bool hasValue;
int32_t clientId;
Expand Down

0 comments on commit aeb0563

Please sign in to comment.