Ejemplo n.º 1
0
        public static void OnLoad()
        {
            if (!(GameFunctions.Init() && GameMemory.Init() && GameOffsets.Init()))
            {
                Game.DisplayNotification($"~r~[ERROR] Spotlight: ~s~Failed to initialize, unloading...");
                Game.LogTrivial($"[ERROR] Failed to initialize, unloading...");
                Game.UnloadActivePlugin();
            }
            WinFunctions.CopyTlsValues(WinFunctions.GetProcessMainThreadId(), WinFunctions.GetCurrentThreadId(), GameOffsets.TlsAllocator0, GameOffsets.TlsAllocator1, GameOffsets.TlsAllocator2);

            bool  on       = false;
            Ped   p        = Game.LocalPlayer.Character;
            ulong shadowId = Render.GenerateShadowId();

            while (true)
            {
                GameFiber.Yield();
                if (Game.IsKeyDown(System.Windows.Forms.Keys.NumPad0))
                {
                    on = !on;
                }
                if (p && on)
                {
                    Game.DisplayHelp("Light: ~g~On");
                    Render.SpotLight(p.GetOffsetPositionFront(1), p.Direction,
                                     eLightFlags.CanRenderUnderground | eLightFlags.EnableVolume | eLightFlags.DisableSpecular,
                                     30, 45, 0.06f, 0.175f, 45, 5, 8.25f, System.Drawing.Color.Red, shadowId);
                }
            }
        }
Ejemplo n.º 2
0
        public IntPtr _object; //Assume this always has largest offset
        public PlayerInfo(IntPtr baseAddr, ProcessMemory MemInstance, GameOffsets CurrentOffsets)
        {
            unsafe {
                var    baseAddrCopy         = baseAddr;
                int    last                 = MemInstance.OffsetAddress(ref baseAddrCopy, 0, 0);
                var    intPtrSize           = MemInstance.is64Bit ? 8 : 4;
                int    size                 = ((int)Math.Ceiling((decimal)((intPtrSize + CurrentOffsets.PlayerInfoStructOffsets.ObjectOffset) / 8))) * 8; //Find the nearest multiple of 8
                byte[] buffer               = MemInstance.Read(baseAddrCopy + last, size);
                PlayerInfoStructOffsets pOf = CurrentOffsets.PlayerInfoStructOffsets;
                fixed(byte *ptr = buffer)
                {
                    var buffptr = (IntPtr)ptr;

                    PlayerId = Marshal.ReadByte(buffptr, pOf.PlayerIDOffset);
                    var NamePTR = MemInstance.is64Bit ? (IntPtr)Marshal.ReadInt64(buffptr, pOf.PlayerNameOffset) : (IntPtr)Marshal.ReadInt32(buffptr, pOf.PlayerNameOffset);

                    PlayerName   = NamePTR == IntPtr.Zero ? "" : MemInstance.ReadString(NamePTR, CurrentOffsets.StringOffsets[0], CurrentOffsets.StringOffsets[1]);
                    ColorId      = (PlayerColor)(uint)Marshal.ReadInt32(buffptr, pOf.ColorIDOffset);
                    HatId        = (uint)Marshal.ReadInt32(buffptr, pOf.HatIDOffset);
                    PetId        = (uint)Marshal.ReadInt32(buffptr, pOf.PetIDOffset);
                    SkinId       = (uint)Marshal.ReadInt32(buffptr, pOf.SkinIDOffset);
                    Disconnected = Marshal.ReadByte(buffptr, pOf.DisconnectedOffset) > 0;
                    Tasks        = Marshal.ReadIntPtr(buffptr, pOf.TasksOffset);
                    IsImpostor   = Marshal.ReadByte(buffptr, pOf.ImposterOffset) == 1;
                    IsDead       = Marshal.ReadByte(buffptr, pOf.DeadOffset) > 0;
                    _object      = Marshal.ReadIntPtr(buffptr, pOf.ObjectOffset);
                }
            }
        }
Ejemplo n.º 3
0
        public WinningPlayerData(IntPtr baseAddr, ProcessMemory MemInstance, GameOffsets CurrentOffsets)
        {
            unsafe {
                var    baseAddrCopy = baseAddr;
                int    last         = MemInstance.OffsetAddress(ref baseAddrCopy, 0, 0);
                int    size         = ((int)Math.Ceiling((decimal)((8 + CurrentOffsets.WinningPlayerDataStructOffsets.IsDeadOffset) / 8))) * 8; //Find the nearest multiple of 8
                byte[] buffer       = MemInstance.Read(baseAddrCopy + last, size);
                PlayerOutfitStructOffsets      oOf = CurrentOffsets.PlayerOutfitStructOffsets;
                WinningPlayerDataStructOffsets pOf = CurrentOffsets.WinningPlayerDataStructOffsets;
                fixed(byte *ptr = buffer)
                {
                    var buffptr = (IntPtr)ptr;

                    Name    = MemInstance.ReadString(MemInstance.Read <IntPtr>(baseAddrCopy, oOf.PlayerNameOffset), CurrentOffsets.StringOffsets[0], CurrentOffsets.StringOffsets[1]);
                    ColorId = (int)Marshal.ReadInt32(buffptr, oOf.ColorIDOffset);
                    // TODO: Since IDs are changed from enum to string like "hat_police", renaming or mapping existing svgs to string is required
                    // TODO: As a workaround just fill with 0 as IDs
                    HatId      = 0;
                    PetId      = 0;
                    SkinId     = 0;
                    IsImpostor = Marshal.ReadByte(buffptr, pOf.IsImposterOffset) == 1;
                    IsDead     = Marshal.ReadByte(buffptr, pOf.IsDeadOffset) > 0;
                    IsYou      = Marshal.ReadByte(buffptr, pOf.IsYouOffset) == 1;
                }
            }
        }
Ejemplo n.º 4
0
        static APISpotlightMgr()
        {
            if (!(GameFunctions.Init() && GameMemory.Init() && GameOffsets.Init()))
            {
                Game.LogTrivial($"[ERROR] Failed to initialize spotlight API");
                return;
            }

            spotlights = new List <APISpotlight>();
            fiber      = GameFiber.StartNew(UpdateSpotlights, "Spotlight API Manager");

            finalizer = new StaticFinalizer(Dispose);
        }
Ejemplo n.º 5
0
        public static GameOffsets FromDefault(string GameHash, string description, int AmongUsClientOffset, int GameDataOffset, int MeetingHudOffset, int GameStartManagerOffset, int HudManagerOffset, int ServerManagerOffset, int WinDataOffset)
        {
            var a = new GameOffsets {
                Description = description
            };

            a.AmongUsClientOffset    = AmongUsClientOffset;
            a.GameDataOffset         = GameDataOffset;
            a.MeetingHudOffset       = MeetingHudOffset;
            a.GameStartManagerOffset = GameStartManagerOffset;
            a.HudManagerOffset       = HudManagerOffset;
            a.ServerManagerOffset    = ServerManagerOffset;
            a.TempDataOffset         = WinDataOffset;

            return(a);
        }
Ejemplo n.º 6
0
        static void Main(string[] args)
        {
            var a = new GameOffsets
            {
                Description            = description,
                AmongUsClientOffset    = AmongUsClientOffset,
                GameDataOffset         = GameDataOffset,
                MeetingHudOffset       = MeetingHudOffset,
                GameStartManagerOffset = GameStartManagerOffset,
                HudManagerOffset       = HudManagerOffset,
                ServerManagerOffset    = ServerManagerOffset,
                TempDataOffset         = TempDataOffset
            };

            Console.Write(JsonConvert.SerializeObject(a, Formatting.Indented));
            var b = new OffsetManager("");

            b.AddToLocalIndex(hash, a);
            Console.ReadLine();
        }
Ejemplo n.º 7
0
        static void Main(string[] args)
        {
            var a = new GameOffsets
            {
                Description            = description,
                AmongUsClientOffset    = AmongUsClientOffset,
                GameDataOffset         = GameDataOffset,
                MeetingHudOffset       = MeetingHudOffset,
                GameStartManagerOffset = GameStartManagerOffset,
                HudManagerOffset       = HudManagerOffset,
                ServerManagerOffset    = ServerManagerOffset,
                TempDataOffset         = TempDataOffset,
                GameOptionsOffset      = GameOptionsOffset,

                MeetingHudPtr             = new [] { MeetingHudOffset, 0x5C, 0 },
                MeetingHudCachePtrOffsets = new [] { 0x8 },
                MeetingHudStateOffsets    = new [] { 0x84 },
                GameStateOffsets          = new [] { AmongUsClientOffset, 0x5C, 0, 0x64 },
                AllPlayerPtrOffsets       = new [] { GameDataOffset, 0x5C, 0, 0x24 },
                AllPlayersOffsets         = new [] { 0x08 },
                PlayerCountOffsets        = new [] { 0x0C },
                ExiledPlayerIdOffsets     = new [] { MeetingHudOffset, 0x5C, 0, 0x94, 0x08 },
                RawGameOverReasonOffsets  = new [] { TempDataOffset, 0x5c, 0x4 },
                WinningPlayersPtrOffsets  = new [] { TempDataOffset, 0x5C, 0xC },
                WinningPlayersOffsets     = new [] { 0x08 },
                WinningPlayerCountOffsets = new [] { 0x0C },
                GameCodeOffsets           = new [] { GameStartManagerOffset, 0x5c, 0, 0x20, 0x28 },
                PlayRegionOffsets         = new [] { ServerManagerOffset, 0x5c, 0, 0x10, 0x8, 0x8 },
                PlayMapOffsets            = new [] { GameOptionsOffset, 0x5c, 0x4, 0x10 },
                StringOffsets             = new [] { 0x8, 0xC },
                isEpic        = false,
                AddPlayerPtr  = 4,
                PlayerListPtr = 0x10
            };

            Console.Write(JsonConvert.SerializeObject(a, Formatting.Indented));
            var b = new OffsetManager("");

            b.AddToLocalIndex(hash, a);
            Console.ReadLine();
        }
Ejemplo n.º 8
0
        public IntPtr _object; //Assume this always has largest offset

        public PlayerInfo(IntPtr baseAddr, ProcessMemory MemInstance, GameOffsets CurrentOffsets)
        {
            unsafe {
                var    baseAddrCopy           = baseAddr;
                int    last                   = MemInstance.OffsetAddress(ref baseAddrCopy, 0, 0);
                var    intPtrSize             = MemInstance.is64Bit ? 8 : 4;
                int    size                   = ((int)Math.Ceiling((decimal)((intPtrSize + CurrentOffsets.PlayerInfoStructOffsets.ObjectOffset) / 8))) * 8; //Find the nearest multiple of 8
                byte[] buffer                 = MemInstance.Read(baseAddrCopy + last, size);
                PlayerInfoStructOffsets   pOf = CurrentOffsets.PlayerInfoStructOffsets;
                PlayerOutfitStructOffsets oOf = CurrentOffsets.PlayerOutfitStructOffsets;
                var outfit = MemInstance.Read <IntPtr>(baseAddrCopy, pOf.OutfitsOffset);
                fixed(byte *ptr = buffer)
                {
                    var buffptr = (IntPtr)ptr;

                    PlayerId     = Marshal.ReadByte(buffptr, pOf.PlayerIDOffset);
                    Disconnected = Marshal.ReadByte(buffptr, pOf.DisconnectedOffset) > 0;
                    Tasks        = Marshal.ReadIntPtr(buffptr, pOf.TasksOffset);
                    IsDead       = Marshal.ReadByte(buffptr, pOf.IsDeadOffset) > 0;
                    _object      = Marshal.ReadIntPtr(buffptr, pOf.ObjectOffset);

                    // Read from Role
                    RoleType     = (uint)MemInstance.Read <int>(baseAddrCopy, pOf.RoleTypeOffset);
                    RoleTeamType = (uint)MemInstance.Read <int>(baseAddrCopy, pOf.RoleTeamTypeOffset);
                    IsImpostor   = RoleTeamType == 1;

                    // Read from PlayerOutfit
                    PlayerName = MemInstance.ReadString(MemInstance.Read <IntPtr>(outfit, oOf.PlayerNameOffset), CurrentOffsets.StringOffsets[0], CurrentOffsets.StringOffsets[1]);
                    ColorId    = (PlayerColor)(uint)MemInstance.Read <int>(outfit, oOf.ColorIDOffset);
                    // TODO: Since IDs are changed from enum to string like "hat_police", renaming or mapping existing svgs to string is required
                    // TODO: As a workaround just fill with 0 as IDs
                    //HatId = MemInstance.ReadString(MemInstance.Read<IntPtr>(outfit, oOf.HatIDOffset), CurrentOffsets.StringOffsets[0], CurrentOffsets.StringOffsets[1]);
                    //PetId = MemInstance.ReadString(MemInstance.Read<IntPtr>(outfit, oOf.PetIDOffset), CurrentOffsets.StringOffsets[0], CurrentOffsets.StringOffsets[1]);
                    //SkinId = MemInstance.ReadString(MemInstance.Read<IntPtr>(outfit, oOf.SkinIDOffset), CurrentOffsets.StringOffsets[0], CurrentOffsets.StringOffsets[1]);
                    HatId  = 0;
                    PetId  = 0;
                    SkinId = 0;
                }
            }
        }
Ejemplo n.º 9
0
        public WinningPlayerData(IntPtr baseAddr, ProcessMemory MemInstance, GameOffsets CurrentOffsets)
        {
            unsafe {
                var    baseAddrCopy = baseAddr;
                int    last         = MemInstance.OffsetAddress(ref baseAddrCopy, 0, 0);
                int    size         = ((int)Math.Ceiling((decimal)((1 + CurrentOffsets.WinningPlayerDataStructOffsets.IsYouOffset) / 8))) * 8; //Find the nearest multiple of 8
                byte[] buffer       = MemInstance.Read(baseAddrCopy + last, size);
                WinningPlayerDataStructOffsets pOf = CurrentOffsets.WinningPlayerDataStructOffsets;
                fixed(byte *ptr = buffer)
                {
                    var buffptr = (IntPtr)ptr;
                    var NamePTR = MemInstance.is64Bit ? (IntPtr)Marshal.ReadInt64(buffptr, pOf.NameOffset) : (IntPtr)Marshal.ReadInt32(buffptr, pOf.NameOffset);

                    Name       = NamePTR == IntPtr.Zero ? "" : MemInstance.ReadString(NamePTR, CurrentOffsets.StringOffsets[0], CurrentOffsets.StringOffsets[1]);
                    ColorId    = (int)Marshal.ReadInt32(buffptr, pOf.ColorOffset);
                    HatId      = (uint)Marshal.ReadInt32(buffptr, pOf.HatOffset);
                    PetId      = (uint)Marshal.ReadInt32(buffptr, pOf.PetOffset);
                    SkinId     = (uint)Marshal.ReadInt32(buffptr, pOf.SkinOffset);
                    IsImpostor = Marshal.ReadByte(buffptr, pOf.ImposterOffset) == 1;
                    IsDead     = Marshal.ReadByte(buffptr, pOf.DeadOffset) > 0;
                    IsYou      = Marshal.ReadByte(buffptr, pOf.IsYouOffset) == 1;
                }
            }
        }
Ejemplo n.º 10
0
        public void RunLoop()
        {
            while (true)
            {
                if (!ProcessMemory.getInstance().IsHooked || ProcessMemory.getInstance().process is null || ProcessMemory.getInstance().process.HasExited)
                {
                    if (!ProcessMemory.getInstance().HookProcess("Among Us"))
                    {
                        Thread.Sleep(1000);
                        continue;
                    }

                    Settings.conInterface.WriteModuleTextColored("GameMemReader", Color.Lime, $"Connected to Among Us process ({Color.Red.ToTextColor()}{ProcessMemory.getInstance().process.Id}{Settings.conInterface.getNormalColor().ToTextColor()})");


                    var foundModule = false;

                    while (true)
                    {
                        foreach (var module in ProcessMemory.getInstance().modules)
                        {
                            if (module.Name.Equals("GameAssembly.dll", StringComparison.OrdinalIgnoreCase))
                            {
                                GameAssemblyPtr = module.BaseAddress;
                                if (!GameVerifier.VerifySteamHash(module.FileName))
                                {
                                    cracked = true;
                                    Settings.conInterface.WriteModuleTextColored("GameVerifier", Color.Red,
                                                                                 $"Client verification: {Color.Red.ToTextColor()}FAIL{Settings.conInterface.getNormalColor().ToTextColor()}.");
                                }
                                else
                                {
                                    cracked = false;
                                    Settings.conInterface.WriteModuleTextColored("GameVerifier", Color.Red, $"Client verification: {Color.Lime.ToTextColor()}PASS{Settings.conInterface.getNormalColor().ToTextColor()}.");
                                }
                                using (SHA256Managed sha256 = new SHA256Managed())
                                {
                                    using (FileStream fs = new FileStream(module.FileName, FileMode.Open, FileAccess.Read))
                                    {
                                        using (var bs = new BufferedStream(fs))
                                        {
                                            var           hash = sha256.ComputeHash(bs);
                                            StringBuilder GameAssemblyhashSb = new StringBuilder(2 * hash.Length);
                                            foreach (byte byt in hash)
                                            {
                                                GameAssemblyhashSb.AppendFormat("{0:X2}", byt);
                                            }

                                            Console.WriteLine($"GameAssembly Hash: {GameAssemblyhashSb.ToString()}");
                                            GameHash       = GameAssemblyhashSb.ToString();
                                            CurrentOffsets = offMan.FetchForHash(GameAssemblyhashSb.ToString());
                                            if (CurrentOffsets is not null)
                                            {
                                                Settings.conInterface.WriteModuleTextColored("GameMemReader", Color.Lime, $"Loaded offsets: {CurrentOffsets.Description}");
                                            }
                                            else
                                            {
                                                Settings.conInterface.WriteModuleTextColored("GameMemReader", Color.Lime, $"No offsets found for: {Color.Aqua.ToTextColor()}{GameAssemblyhashSb.ToString()}.");
                                            }
                                        }
                                    }
                                }

                                foundModule = true;
                                break;
                            }
                        }

                        if (!foundModule)
                        {
                            Settings.conInterface.WriteModuleTextColored("GameMemReader", Color.Lime,
                                                                         "Still looking for modules...");
                            //Program.conInterface.WriteModuleTextColored("GameMemReader", Color.Green, "Still looking for modules..."); // TODO: This still isn't functional, we need to re-hook to reload module addresses
                            Thread.Sleep(500); // delay and try again
                            ProcessMemory.getInstance().LoadModules();
                        }
                        else
                        {
                            break; // we have found all modules
                        }
                    }

                    try
                    {
                        prevChatBubsVersion = ProcessMemory.getInstance().Read <int>(GameAssemblyPtr,
                                                                                     CurrentOffsets.HudManagerOffset, 0x5C,
                                                                                     0, 0x28, 0xC, 0x14, 0x10);
                        // prevGameOverReason = ProcessMemory.getInstance().Read<GameOverReason>(GameAssemblyPtr, _gameOffsets.TempDataOffset, 0x5c, 4);
                    }
                    catch
                    {
                        Settings.conInterface.WriteModuleTextColored("ERROR", Color.Red, "Outdated version of the game.");
                    }
                }
                if (cracked && ProcessMemory.getInstance().IsHooked)
                {
                    var result = Settings.conInterface.CrackDetected();
                    if (!result)
                    {
                        Environment.Exit(0);
                    }
                    else
                    {
                        cracked = false;
                    }
                    continue;
                }

                GameState state;
                //int meetingHudState = /*meetingHud_cachePtr == 0 ? 4 : */ProcessMemory.ReadWithDefault<int>(GameAssemblyPtr, 4, 0xDA58D0, 0x5C, 0, 0x84); // 0 = Discussion, 1 = NotVoted, 2 = Voted, 3 = Results, 4 = Proceeding
                var meetingHud          = ProcessMemory.getInstance().Read <IntPtr>(GameAssemblyPtr, CurrentOffsets.MeetingHudOffset, 0x5C, 0);
                var meetingHud_cachePtr = meetingHud == IntPtr.Zero ? 0 : ProcessMemory.getInstance().Read <uint>(meetingHud, 0x8);
                var meetingHudState     =
                    meetingHud_cachePtr == 0
                        ? 4
                        : ProcessMemory.getInstance().ReadWithDefault(meetingHud, 4,
                                                                      0x84); // 0 = Discussion, 1 = NotVoted, 2 = Voted, 3 = Results, 4 = Proceeding
                var gameState =
                    ProcessMemory.getInstance().Read <int>(GameAssemblyPtr, CurrentOffsets.AmongUsClientOffset, 0x5C, 0,
                                                           0x64); // 0 = NotJoined, 1 = Joined, 2 = Started, 3 = Ended (during "defeat" or "victory" screen only)

                switch (gameState)
                {
                case 0:
                    state          = GameState.MENU;
                    exileCausesEnd = false;
                    break;

                case 1:
                case 3:
                    state          = GameState.LOBBY;
                    exileCausesEnd = false;
                    break;

                default:
                {
                    if (exileCausesEnd)
                    {
                        state = GameState.LOBBY;
                    }
                    else if (meetingHudState < 4)
                    {
                        state = GameState.DISCUSSION;
                    }
                    else
                    {
                        state = GameState.TASKS;
                    }

                    break;
                }
                }
                //Console.WriteLine($"Got state: {state}");


                var allPlayersPtr =
                    ProcessMemory.getInstance().Read <IntPtr>(GameAssemblyPtr, CurrentOffsets.GameDataOffset, 0x5C, 0, 0x24);
                var allPlayers  = ProcessMemory.getInstance().Read <IntPtr>(allPlayersPtr, 0x08);
                var playerCount = ProcessMemory.getInstance().Read <int>(allPlayersPtr, 0x0C);

                var playerAddrPtr = allPlayers + 0x10;

                // check if exile causes end
                if (oldState == GameState.DISCUSSION && state == GameState.TASKS)
                {
                    var exiledPlayerId = ProcessMemory.getInstance().ReadWithDefault <byte>(GameAssemblyPtr, 255,
                                                                                            CurrentOffsets.MeetingHudOffset, 0x5C, 0, 0x94, 0x08);
                    int impostorCount = 0, innocentCount = 0;

                    for (var i = 0; i < playerCount; i++)
                    {
                        var pi = ProcessMemory.getInstance().Read <PlayerInfo>(playerAddrPtr, 0, 0);
                        playerAddrPtr += 4;

                        if (pi.PlayerId == exiledPlayerId)
                        {
                            PlayerChanged?.Invoke(this, new PlayerChangedEventArgs
                            {
                                Action       = PlayerAction.Exiled,
                                Name         = pi.GetPlayerName(),
                                IsDead       = pi.GetIsDead(),
                                Disconnected = pi.GetIsDisconnected(),
                                Color        = pi.GetPlayerColor()
                            });
                        }

                        // skip invalid, dead and exiled players
                        if (pi.PlayerName == 0 || pi.PlayerId == exiledPlayerId || pi.IsDead == 1 ||
                            pi.Disconnected == 1)
                        {
                            continue;
                        }

                        if (pi.IsImpostor == 1)
                        {
                            impostorCount++;
                        }
                        else
                        {
                            innocentCount++;
                        }
                    }

                    if (impostorCount == 0 || impostorCount >= innocentCount)
                    {
                        exileCausesEnd = true;
                        state          = GameState.LOBBY;
                    }
                }

                if (state != oldState || shouldForceTransmitState)
                {
                    GameStateChanged?.Invoke(this, new GameStateChangedEventArgs {
                        NewState = state
                    });
                    shouldForceTransmitState = false;
                }

                if (state != oldState && state == GameState.LOBBY)
                {
                    shouldReadLobby = true; // will eventually transmit
                }


                if ((oldState == GameState.DISCUSSION || oldState == GameState.TASKS) && (state == GameState.LOBBY || state == GameState.MENU)) // game ended
                {
                    int            rawGameOverReason = ProcessMemory.getInstance().Read <int>(GameAssemblyPtr, CurrentOffsets.TempDataOffset, 0x5c, 0x4);
                    GameOverReason gameOverReason    = (GameOverReason)rawGameOverReason;

                    bool humansWon = rawGameOverReason <= 1 || rawGameOverReason == 5;

                    if (humansWon) // we will be reading humans data, so set all to imps
                    {
                        foreach (string playerName in CachedPlayerInfos.Keys)
                        {
                            CachedPlayerInfos[playerName].IsImpostor = true;
                        }
                    }

                    var winningPlayersPtr  = ProcessMemory.getInstance().Read <IntPtr>(GameAssemblyPtr, CurrentOffsets.TempDataOffset, 0x5C, 0xC);
                    var winningPlayers     = ProcessMemory.getInstance().Read <IntPtr>(winningPlayersPtr, 0x08);
                    var winningPlayerCount = ProcessMemory.getInstance().Read <int>(winningPlayersPtr, 0x0C);

                    var winnerAddrPtr = winningPlayers + 0x10;

                    for (var i = 0; i < winningPlayerCount; i++)
                    {
                        WinningPlayerData wpi = ProcessMemory.getInstance().Read <WinningPlayerData>(winnerAddrPtr, 0, 0);
                        winnerAddrPtr += 4;
                        CachedPlayerInfos[wpi.GetPlayerName()].IsImpostor = wpi.IsImpostor;
                    }

                    ImmutablePlayer[] endingPlayerInfos = new ImmutablePlayer[CachedPlayerInfos.Count];
                    CachedPlayerInfos.Values.CopyTo(endingPlayerInfos, 0);

                    GameOver?.Invoke(this, new GameOverEventArgs
                    {
                        GameOverReason = gameOverReason,
                        PlayerInfos    = endingPlayerInfos
                    });
                }

                GameState cachedOldState = oldState;

                oldState = state;


                newPlayerInfos.Clear();

                playerAddrPtr = allPlayers + 0x10;

                for (var i = 0; i < playerCount; i++)
                {
                    var pi = ProcessMemory.getInstance().Read <PlayerInfo>(playerAddrPtr, 0, 0);
                    playerAddrPtr += 4;
                    if (pi.PlayerName == 0)
                    {
                        continue;
                    }
                    var playerName = pi.GetPlayerName();
                    if (playerName.Length == 0)
                    {
                        continue;
                    }

                    newPlayerInfos[playerName] = pi;             // add to new playerinfos for comparison later

                    if (!oldPlayerInfos.ContainsKey(playerName)) // player wasn't here before, they just joined
                    {
                        PlayerChanged?.Invoke(this, new PlayerChangedEventArgs
                        {
                            Action       = PlayerAction.Joined,
                            Name         = playerName,
                            IsDead       = pi.GetIsDead(),
                            Disconnected = pi.GetIsDisconnected(),
                            Color        = pi.GetPlayerColor()
                        });
                    }
                    else
                    {
                        // player was here before, we have an old playerInfo to compare against
                        var oldPlayerInfo = oldPlayerInfos[playerName];
                        if (!oldPlayerInfo.GetIsDead() && pi.GetIsDead()) // player just died
                        {
                            PlayerChanged?.Invoke(this, new PlayerChangedEventArgs
                            {
                                Action       = PlayerAction.Died,
                                Name         = playerName,
                                IsDead       = pi.GetIsDead(),
                                Disconnected = pi.GetIsDisconnected(),
                                Color        = pi.GetPlayerColor()
                            });
                        }

                        if (oldPlayerInfo.ColorId != pi.ColorId)
                        {
                            PlayerChanged?.Invoke(this, new PlayerChangedEventArgs
                            {
                                Action       = PlayerAction.ChangedColor,
                                Name         = playerName,
                                IsDead       = pi.GetIsDead(),
                                Disconnected = pi.GetIsDisconnected(),
                                Color        = pi.GetPlayerColor()
                            });
                        }

                        if (!oldPlayerInfo.GetIsDisconnected() && pi.GetIsDisconnected())
                        {
                            PlayerChanged?.Invoke(this, new PlayerChangedEventArgs
                            {
                                Action       = PlayerAction.Disconnected,
                                Name         = playerName,
                                IsDead       = pi.GetIsDead(),
                                Disconnected = pi.GetIsDisconnected(),
                                Color        = pi.GetPlayerColor()
                            });
                        }
                    }
                }

                foreach (var kvp in oldPlayerInfos)
                {
                    var pi         = kvp.Value;
                    var playerName = kvp.Key;
                    if (!newPlayerInfos.ContainsKey(playerName)) // player was here before, isn't now, so they left
                    {
                        PlayerChanged?.Invoke(this, new PlayerChangedEventArgs
                        {
                            Action       = PlayerAction.Left,
                            Name         = playerName,
                            IsDead       = pi.GetIsDead(),
                            Disconnected = pi.GetIsDisconnected(),
                            Color        = pi.GetPlayerColor()
                        });
                    }
                }

                oldPlayerInfos.Clear();

                var emitAll = false;
                if (shouldForceUpdatePlayers)
                {
                    shouldForceUpdatePlayers = false;
                    emitAll = true;
                }


                if (state != cachedOldState && (state == GameState.DISCUSSION || state == GameState.TASKS)) // game started, or at least we're still in game
                {
                    CachedPlayerInfos.Clear();
                    foreach (var kvp in newPlayerInfos) // do this instead of assignment so they don't point to the same object
                    {
                        var    pi         = kvp.Value;
                        string playerName = pi.GetPlayerName();
                        CachedPlayerInfos[playerName] = new ImmutablePlayer()
                        {
                            Name       = playerName,
                            IsImpostor = false
                        };
                    }
                }

                foreach (var kvp in newPlayerInfos
                         ) // do this instead of assignment so they don't point to the same object
                {
                    var pi = kvp.Value;
                    oldPlayerInfos[kvp.Key] = pi;
                    if (emitAll)
                    {
                        PlayerChanged?.Invoke(this, new PlayerChangedEventArgs
                        {
                            Action       = PlayerAction.ForceUpdated,
                            Name         = kvp.Key,
                            IsDead       = pi.GetIsDead(),
                            Disconnected = pi.GetIsDisconnected(),
                            Color        = pi.GetPlayerColor()
                        });
                    }
                }

                var chatBubblesPtr = ProcessMemory.getInstance().Read <IntPtr>(GameAssemblyPtr, CurrentOffsets.HudManagerOffset, 0x5C, 0,
                                                                               0x28, 0xC, 0x14);

                var poolSize = 20; // = ProcessMemory.Read<int>(GameAssemblyPtr, 0xD0B25C, 0x5C, 0, 0x28, 0xC, 0xC)

                var numChatBubbles  = ProcessMemory.getInstance().Read <int>(chatBubblesPtr, 0xC);
                var chatBubsVersion = ProcessMemory.getInstance().Read <int>(chatBubblesPtr, 0x10);
                var chatBubblesAddr = ProcessMemory.getInstance().Read <IntPtr>(chatBubblesPtr, 0x8) + 0x10;
                var chatBubblePtrs  = ProcessMemory.getInstance().ReadArray(chatBubblesAddr, numChatBubbles);

                var newMsgs = 0;

                if (chatBubsVersion > prevChatBubsVersion) // new message has been sent
                {
                    if (chatBubsVersion > poolSize)        // increments are twofold (push to and pop from pool)
                    {
                        if (prevChatBubsVersion > poolSize)
                        {
                            newMsgs = (chatBubsVersion - prevChatBubsVersion) >> 1;
                        }
                        else
                        {
                            newMsgs = poolSize - prevChatBubsVersion + ((chatBubsVersion - poolSize) >> 1);
                        }
                    }
                    else // single increments
                    {
                        newMsgs = chatBubsVersion - prevChatBubsVersion;
                    }
                }
                else if (chatBubsVersion < prevChatBubsVersion) // reset
                {
                    if (chatBubsVersion > poolSize)             // increments are twofold (push to and pop from pool)
                    {
                        newMsgs = poolSize + ((chatBubsVersion - poolSize) >> 1);
                    }
                    else // single increments
                    {
                        newMsgs = chatBubsVersion;
                    }
                }

                prevChatBubsVersion = chatBubsVersion;

                for (var i = numChatBubbles - newMsgs; i < numChatBubbles; i++)
                {
                    var msgText = ProcessMemory.getInstance().ReadString(ProcessMemory.getInstance().Read <IntPtr>(chatBubblePtrs[i], 0x20, 0x28));
                    if (msgText.Length == 0)
                    {
                        continue;
                    }
                    var msgSender     = ProcessMemory.getInstance().ReadString(ProcessMemory.getInstance().Read <IntPtr>(chatBubblePtrs[i], 0x1C, 0x28));
                    var oldPlayerInfo = oldPlayerInfos[msgSender];
                    ChatMessageAdded?.Invoke(this, new ChatMessageEventArgs
                    {
                        Sender  = msgSender,
                        Message = msgText,
                        Color   = oldPlayerInfo.GetPlayerColor()
                    });
                }

                if (shouldReadLobby)
                {
                    var gameCode = ProcessMemory.getInstance().ReadString(ProcessMemory.getInstance().Read <IntPtr>(GameAssemblyPtr,
                                                                                                                    CurrentOffsets.GameStartManagerOffset, 0x5c, 0, 0x20, 0x28));
                    string[] split;
                    if (gameCode != null && gameCode.Length > 0 && (split = gameCode.Split('\n')).Length == 2)
                    {
                        PlayRegion region = (PlayRegion)((4 - (ProcessMemory.getInstance().Read <int>(GameAssemblyPtr, CurrentOffsets.ServerManagerOffset, 0x5c, 0, 0x10, 0x8, 0x8) & 0b11)) % 3); // do NOT ask

                        this.latestLobbyEventArgs = new LobbyEventArgs()
                        {
                            LobbyCode = split[1],
                            Region    = region
                        };
                        shouldReadLobby     = false;
                        shouldTransmitLobby = true; // since this is probably new info
                    }
                }

                if (shouldTransmitLobby)
                {
                    if (this.latestLobbyEventArgs != null)
                    {
                        JoinedLobby?.Invoke(this, this.latestLobbyEventArgs);
                    }
                    shouldTransmitLobby = false;
                }

                Thread.Sleep(250);
            }
        }
Ejemplo n.º 11
0
        public void RunLoop()
        {
            while (true)
            {
                try
                {
                    if (!ProcessMemory.getInstance().IsHooked || ProcessMemory.getInstance().process is null ||
                        ProcessMemory.getInstance().process.HasExited)
                    {
                        if (!ProcessMemory.getInstance().HookProcess("Among Us"))
                        {
                            Thread.Sleep(1000);
                            continue;
                        }

                        Settings.conInterface.WriteModuleTextColored("GameMemReader", Color.Lime,
                                                                     $"Connected to Among Us process ({Color.Red.ToTextColor()}{ProcessMemory.getInstance().process.Id}{Settings.conInterface.getNormalColor().ToTextColor()})");


                        var foundModule = false;

                        while (true)
                        {
                            foreach (var module in ProcessMemory.getInstance().modules)
                            {
                                if (module.Name.Equals("GameAssembly.dll", StringComparison.OrdinalIgnoreCase))
                                {
                                    GameAssemblyPtr = module.BaseAddress;
                                    if (!GameVerifier.VerifySteamHash(module.FileName))
                                    {
                                        cracked = true;
                                        Settings.conInterface.WriteModuleTextColored("GameVerifier", Color.Red,
                                                                                     $"Client verification: {Color.Red.ToTextColor()}FAIL{Settings.conInterface.getNormalColor().ToTextColor()}.");
                                    }
                                    else
                                    {
                                        cracked = false;
                                        Settings.conInterface.WriteModuleTextColored("GameVerifier", Color.Red,
                                                                                     $"Client verification: {Color.Lime.ToTextColor()}PASS{Settings.conInterface.getNormalColor().ToTextColor()}.");
                                    }

                                    using (SHA256Managed sha256 = new SHA256Managed())
                                    {
                                        try
                                        {
                                            using FileStream fs = new FileStream(module.FileName, FileMode.Open,
                                                                                 FileAccess.Read);
                                            using var bs = new BufferedStream(fs);
                                            var           hash = sha256.ComputeHash(bs);
                                            StringBuilder GameAssemblyhashSb = new StringBuilder(2 * hash.Length);
                                            foreach (byte byt in hash)
                                            {
                                                GameAssemblyhashSb.AppendFormat("{0:X2}", byt);
                                            }

                                            Console.WriteLine(
                                                $"GameAssembly Hash: {GameAssemblyhashSb.ToString()}");
                                            GameHash       = GameAssemblyhashSb.ToString();
                                            CurrentOffsets = offMan.FetchForHash(GameAssemblyhashSb.ToString());
                                        }
                                        catch (Exception e)
                                        {
                                            foundModule    = true;
                                            cracked        = false;
                                            GameHash       = "windows_store";
                                            CurrentOffsets = offMan.FetchForHash(GameHash);
                                        }
                                        if (CurrentOffsets is not null)
                                        {
                                            Settings.conInterface.WriteModuleTextColored("GameMemReader",
                                                                                         Color.Lime, $"Loaded offsets: {CurrentOffsets.Description}");
                                            ProcessHook?.Invoke(this, new ProcessHookArgs {
                                                PID = ProcessMemory.getInstance().process.Id
                                            });
                                        }
                                        else
                                        {
                                            Settings.conInterface.WriteModuleTextColored("GameMemReader",
                                                                                         Color.Lime,
                                                                                         $"No offsets found for: {Color.Aqua.ToTextColor()}{GameHash}{Settings.conInterface.getNormalColor().ToTextColor()}.");
                                        }
                                    }

                                    foundModule = true;
                                    break;
                                }
                            }

                            if (!foundModule)
                            {
                                Settings.conInterface.WriteModuleTextColored("GameMemReader", Color.Lime,
                                                                             "Still looking for modules...");
                                //Program.conInterface.WriteModuleTextColored("GameMemReader", Color.Green, "Still looking for modules..."); // TODO: This still isn't functional, we need to re-hook to reload module addresses
                                Thread.Sleep(500); // delay and try again
                                ProcessMemory.getInstance().LoadModules();
                            }
                            else
                            {
                                break; // we have found all modules
                            }
                        }

                        try
                        {
                            if (CurrentOffsets is not null)
                            {
                            }

                            // prevGameOverReason = ProcessMemory.getInstance().Read<GameOverReason>(GameAssemblyPtr, _gameOffsets.TempDataOffset, 0x5c, 4);
                        }
                        catch
                        {
                            Settings.conInterface.WriteModuleTextColored("ERROR", Color.Red,
                                                                         "Outdated version of the game.");
                        }
                    }

                    if (cracked && ProcessMemory.getInstance().IsHooked)
                    {
                        var result = Settings.conInterface.CrackDetected();
                        if (!result)
                        {
                            Environment.Exit(0);
                        }
                        else
                        {
                            cracked = false;
                        }
                        continue;
                    }

                    if (CurrentOffsets is null)
                    {
                        continue;
                    }
                    GameState state;
                    //int meetingHudState = /*meetingHud_cachePtr == 0 ? 4 : */ProcessMemory.ReadWithDefault<int>(GameAssemblyPtr, 4, 0xDA58D0, 0x5C, 0, 0x84); // 0 = Discussion, 1 = NotVoted, 2 = Voted, 3 = Results, 4 = Proceeding
                    var meetingHud = ProcessMemory.getInstance()
                                     .Read <IntPtr>(GameAssemblyPtr, CurrentOffsets.MeetingHudPtr);
                    var meetingHud_cachePtr = meetingHud == IntPtr.Zero
                        ? 0
                        : ProcessMemory.getInstance().Read <uint>(meetingHud, CurrentOffsets.MeetingHudCachePtrOffsets);
                    var meetingHudState =
                        meetingHud_cachePtr == 0
                            ? 4
                            : ProcessMemory.getInstance().ReadWithDefault(meetingHud, 4, CurrentOffsets.MeetingHudStateOffsets
                                                                          );                                      // 0 = Discussion, 1 = NotVoted, 2 = Voted, 3 = Results, 4 = Proceeding
                    var gameState =
                        ProcessMemory.getInstance().Read <int>(GameAssemblyPtr, CurrentOffsets.GameStateOffsets); // 0 = NotJoined, 1 = Joined, 2 = Started, 3 = ENDED (during "defeat" or "victory" screen only)

                    switch (gameState)
                    {
                    case 0:
                        state          = GameState.MENU;
                        exileCausesEnd = false;
                        break;

                    case 1:
                        state          = GameState.LOBBY;
                        exileCausesEnd = false;
                        break;

                    case 3:
                        state          = GameState.ENDED;
                        exileCausesEnd = false;
                        break;

                    default:
                    {
                        if (exileCausesEnd)
                        {
                            state = GameState.LOBBY;
                        }
                        else if (meetingHudState < 4)
                        {
                            state = GameState.DISCUSSION;
                        }
                        else
                        {
                            state = GameState.TASKS;
                        }

                        break;
                    }
                    }
                    //Console.WriteLine($"Got state: {state}");


                    var allPlayersPtr =
                        ProcessMemory.getInstance()
                        .Read <IntPtr>(GameAssemblyPtr, CurrentOffsets.AllPlayerPtrOffsets);
                    var allPlayers  = ProcessMemory.getInstance().Read <IntPtr>(allPlayersPtr, CurrentOffsets.AllPlayersOffsets);
                    var playerCount = ProcessMemory.getInstance().Read <int>(allPlayersPtr, CurrentOffsets.PlayerCountOffsets);

                    var playerAddrPtr = allPlayers + CurrentOffsets.PlayerListPtr;
                    // check if exile causes end
                    if (oldState == GameState.DISCUSSION && state == GameState.TASKS)
                    {
                        var exiledPlayerId = ProcessMemory.getInstance().ReadWithDefault <byte>(GameAssemblyPtr, 255,
                                                                                                CurrentOffsets.ExiledPlayerIdOffsets);
                        int impostorCount = 0, innocentCount = 0;

                        for (var i = 0; i < playerCount; i++)
                        {
                            var pi = CurrentOffsets.isEpic
                                ? (PlayerInfo)ProcessMemory.getInstance().Read <EpicPlayerInfo>(playerAddrPtr, 0, 0)
                                : ProcessMemory.getInstance().Read <SteamPlayerInfo>(playerAddrPtr, 0, 0);

                            playerAddrPtr += CurrentOffsets.AddPlayerPtr;

                            if (pi.PlayerId == exiledPlayerId)
                            {
                                PlayerChanged?.Invoke(this, new PlayerChangedEventArgs
                                {
                                    Action       = PlayerAction.Exiled,
                                    Name         = pi.GetPlayerName(),
                                    IsDead       = pi.GetIsDead(),
                                    Disconnected = pi.GetIsDisconnected(),
                                    Color        = pi.GetPlayerColor()
                                });
                            }

                            // skip invalid, dead and exiled players
                            if (pi.PlayerName == IntPtr.Zero || pi.PlayerId == exiledPlayerId || pi.IsDead == 1 ||
                                pi.Disconnected == 1)
                            {
                                continue;
                            }

                            if (pi.IsImpostor == 1)
                            {
                                impostorCount++;
                            }
                            else
                            {
                                innocentCount++;
                            }
                        }

                        if (impostorCount == 0 || impostorCount >= innocentCount)
                        {
                            exileCausesEnd = true;
                            state          = GameState.LOBBY;
                        }
                    }

                    if (state != oldState || shouldForceTransmitState)
                    {
                        GameStateChanged?.Invoke(this, new GameStateChangedEventArgs {
                            NewState = state
                        });
                        shouldForceTransmitState = false;
                    }

                    if (state != oldState && state == GameState.LOBBY)
                    {
                        shouldReadLobby = true; // will eventually transmit
                    }


                    if (oldState == GameState.ENDED && (state == GameState.LOBBY || state == GameState.MENU)) // game ended
                    {
                        int rawGameOverReason = ProcessMemory.getInstance()
                                                .Read <int>(GameAssemblyPtr, CurrentOffsets.RawGameOverReasonOffsets);
                        GameOverReason gameOverReason = (GameOverReason)rawGameOverReason;

                        bool humansWon = rawGameOverReason <= 1 || rawGameOverReason == 5;
                        if (humansWon) // we will be reading humans data, so set all to simps
                        {
                            foreach (string playerName in CachedPlayerInfos.Keys)
                            {
                                try
                                {
                                    CachedPlayerInfos[playerName].IsImpostor = true;
                                }
                                catch (KeyNotFoundException e)
                                {
                                    Console.WriteLine($"Could not find User: \"{playerName}\" in CachedPlayerinfos");
                                }
                            }
                        }

                        var winningPlayersPtr = ProcessMemory.getInstance()
                                                .Read <IntPtr>(GameAssemblyPtr, CurrentOffsets.WinningPlayersPtrOffsets);
                        var winningPlayers     = ProcessMemory.getInstance().Read <IntPtr>(winningPlayersPtr, CurrentOffsets.WinningPlayersOffsets);
                        var winningPlayerCount = ProcessMemory.getInstance().Read <int>(winningPlayersPtr, CurrentOffsets.WinningPlayerCountOffsets);

                        var winnerAddrPtr = winningPlayers + CurrentOffsets.PlayerListPtr;

                        for (var i = 0; i < winningPlayerCount; i++)
                        {
                            WinningPlayerData wpi = CurrentOffsets.isEpic ?
                                                    (WinningPlayerData)ProcessMemory.getInstance().Read <EpicWinningPlayerData>(winnerAddrPtr, 0, 0)
                                : ProcessMemory.getInstance().Read <SteamWinningPlayerData>(winnerAddrPtr, 0, 0);
                            winnerAddrPtr += CurrentOffsets.AddPlayerPtr;
                            Console.WriteLine(winnerAddrPtr);
                            Console.WriteLine(JsonConvert.SerializeObject(wpi, Formatting.Indented));
                            try
                            {
                                CachedPlayerInfos[wpi.GetPlayerName()].IsImpostor = wpi.IsImpostor;
                            }
                            catch (KeyNotFoundException e)
                            {
                                Console.WriteLine($"Could not find player with name \"{wpi.GetPlayerName()}\" in CachedPlayerInfos. JSON: {JsonConvert.SerializeObject(CachedPlayerInfos, Formatting.Indented)}");
                            }
                        }

                        ImmutablePlayer[] endingPlayerInfos = new ImmutablePlayer[CachedPlayerInfos.Count];
                        CachedPlayerInfos.Values.CopyTo(endingPlayerInfos, 0);

                        GameOver?.Invoke(this, new GameOverEventArgs
                        {
                            GameOverReason = gameOverReason,
                            PlayerInfos    = endingPlayerInfos
                        });
                    }

                    GameState cachedOldState = oldState;

                    oldState = state;


                    newPlayerInfos.Clear();

                    playerAddrPtr = allPlayers + CurrentOffsets.PlayerListPtr;

                    for (var i = 0; i < playerCount; i++)
                    {
                        PlayerInfo pi;
                        pi = CurrentOffsets.isEpic
                            ? (PlayerInfo)ProcessMemory.getInstance().Read <EpicPlayerInfo>(playerAddrPtr, 0, 0)
                            : ProcessMemory.getInstance().Read <SteamPlayerInfo>(playerAddrPtr, 0, 0);
                        playerAddrPtr += CurrentOffsets.AddPlayerPtr;
                        if (pi.PlayerName == IntPtr.Zero)
                        {
                            continue;
                        }
                        var playerName = pi.GetPlayerName();
                        if (playerName.Length == 0)
                        {
                            continue;
                        }

                        newPlayerInfos[playerName] = pi;             // add to new playerinfos for comparison later

                        if (!oldPlayerInfos.ContainsKey(playerName)) // player wasn't here before, they just joined
                        {
                            PlayerChanged?.Invoke(this, new PlayerChangedEventArgs
                            {
                                Action       = PlayerAction.Joined,
                                Name         = playerName,
                                IsDead       = pi.GetIsDead(),
                                Disconnected = pi.GetIsDisconnected(),
                                Color        = pi.GetPlayerColor()
                            });
                            PlayerCosmeticChanged?.Invoke(this, new PlayerCosmeticChangedEventArgs
                            {
                                Name   = playerName,
                                HatId  = pi.HatId,
                                SkinId = pi.SkinId,
                                PetId  = pi.PetId
                            });
                        }
                        else
                        {
                            // player was here before, we have an old playerInfo to compare against
                            var oldPlayerInfo = oldPlayerInfos[playerName];
                            if (!oldPlayerInfo.GetIsDead() && pi.GetIsDead()) // player just died
                            {
                                PlayerChanged?.Invoke(this, new PlayerChangedEventArgs
                                {
                                    Action       = PlayerAction.Died,
                                    Name         = playerName,
                                    IsDead       = pi.GetIsDead(),
                                    Disconnected = pi.GetIsDisconnected(),
                                    Color        = pi.GetPlayerColor()
                                });
                            }

                            if (oldPlayerInfo.ColorId != pi.ColorId)
                            {
                                PlayerChanged?.Invoke(this, new PlayerChangedEventArgs
                                {
                                    Action       = PlayerAction.ChangedColor,
                                    Name         = playerName,
                                    IsDead       = pi.GetIsDead(),
                                    Disconnected = pi.GetIsDisconnected(),
                                    Color        = pi.GetPlayerColor()
                                });
                            }

                            if (!oldPlayerInfo.GetIsDisconnected() && pi.GetIsDisconnected())
                            {
                                PlayerChanged?.Invoke(this, new PlayerChangedEventArgs
                                {
                                    Action       = PlayerAction.Disconnected,
                                    Name         = playerName,
                                    IsDead       = pi.GetIsDead(),
                                    Disconnected = pi.GetIsDisconnected(),
                                    Color        = pi.GetPlayerColor()
                                });
                            }

                            if (oldPlayerInfo.HatId != pi.HatId || oldPlayerInfo.SkinId != pi.SkinId || oldPlayerInfo.PetId != pi.PetId)
                            {
                                PlayerCosmeticChanged?.Invoke(this, new PlayerCosmeticChangedEventArgs
                                {
                                    Name   = playerName,
                                    HatId  = pi.HatId,
                                    SkinId = pi.SkinId,
                                    PetId  = pi.PetId
                                });
                            }
                        }
                    }

                    foreach (var kvp in oldPlayerInfos)
                    {
                        var pi         = kvp.Value;
                        var playerName = kvp.Key;
                        if (!newPlayerInfos.ContainsKey(playerName)) // player was here before, isn't now, so they left
                        {
                            PlayerChanged?.Invoke(this, new PlayerChangedEventArgs
                            {
                                Action       = PlayerAction.Left,
                                Name         = playerName,
                                IsDead       = pi.GetIsDead(),
                                Disconnected = pi.GetIsDisconnected(),
                                Color        = pi.GetPlayerColor()
                            });
                        }
                    }

                    oldPlayerInfos.Clear();

                    var emitAll = false;
                    if (shouldForceUpdatePlayers)
                    {
                        shouldForceUpdatePlayers = false;
                        emitAll = true;
                    }


                    if (state != cachedOldState && (state == GameState.DISCUSSION || state == GameState.TASKS)
                        ) // game started, or at least we're still in game
                    {
                        CachedPlayerInfos.Clear();
                        foreach (var kvp in newPlayerInfos
                                 ) // do this instead of assignment so they don't point to the same object
                        {
                            var    pi         = kvp.Value;
                            string playerName = pi.GetPlayerName();
                            CachedPlayerInfos[playerName] = new ImmutablePlayer()
                            {
                                Name       = playerName,
                                IsImpostor = false
                            };
                        }
                    }

                    foreach (var kvp in newPlayerInfos
                             ) // do this instead of assignment so they don't point to the same object
                    {
                        var pi = kvp.Value;
                        oldPlayerInfos[kvp.Key] = pi;
                        if (emitAll)
                        {
                            PlayerChanged?.Invoke(this, new PlayerChangedEventArgs
                            {
                                Action       = PlayerAction.ForceUpdated,
                                Name         = kvp.Key,
                                IsDead       = pi.GetIsDead(),
                                Disconnected = pi.GetIsDisconnected(),
                                Color        = pi.GetPlayerColor()
                            });
                        }
                    }

                    if (shouldReadLobby)
                    {
                        var gameCode = ProcessMemory.getInstance().ReadString(ProcessMemory.getInstance().Read <IntPtr>(
                                                                                  GameAssemblyPtr,
                                                                                  CurrentOffsets.GameCodeOffsets), CurrentOffsets.StringOffsets[0], CurrentOffsets.StringOffsets[1]);
                        string[] split;
                        if (!string.IsNullOrEmpty(gameCode) && (split = gameCode.Split('\n')).Length == 2)
                        {
                            PlayRegion region = (PlayRegion)((4 - (ProcessMemory.getInstance()
                                                                   .Read <int>(GameAssemblyPtr, CurrentOffsets.PlayRegionOffsets) & 0b11)) % 3); // do NOT ask

                            //Recheck for GameOptionsOffset
                            PlayMap map = (PlayMap)ProcessMemory.getInstance().Read <int>(GameAssemblyPtr, CurrentOffsets.PlayMapOffsets);

                            this.latestLobbyEventArgs = new LobbyEventArgs()
                            {
                                LobbyCode = split[1],
                                Region    = region,
                                Map       = map,
                            };
                            shouldReadLobby     = false;
                            shouldTransmitLobby = true; // since this is probably new info
                        }
                    }

                    if (shouldTransmitLobby)
                    {
                        if (this.latestLobbyEventArgs != null)
                        {
                            JoinedLobby?.Invoke(this, this.latestLobbyEventArgs);
                        }

                        shouldTransmitLobby = false;
                    }

                    Thread.Sleep(250);
                }
                catch (Exception e)
                {
                    Settings.conInterface.WriteModuleTextColored("ERROR", Color.Red, $"Message: {e.Message} | stack: {e.StackTrace} | Retrying in 1000ms.");
                    Console.WriteLine(e);
                    Thread.Sleep(1000);
                }
            }
        }
Ejemplo n.º 12
0
        static void Main(string[] args)
        {
            var a = new GameOffsets
            {
                Description            = description,
                AmongUsClientOffset    = AmongUsClientOffset,
                GameDataOffset         = GameDataOffset,
                MeetingHudOffset       = MeetingHudOffset,
                GameStartManagerOffset = GameStartManagerOffset,
                HudManagerOffset       = HudManagerOffset,
                ServerManagerOffset    = ServerManagerOffset,
                TempDataOffset         = TempDataOffset,
                GameOptionsOffset      = GameOptionsOffset,

                MeetingHudPtr             = new [] { MeetingHudOffset, 0x5C, 0 },
                MeetingHudCachePtrOffsets = new [] { 0x8 },
                MeetingHudStateOffsets    = new [] { 0x84 },
                GameStateOffsets          = new [] { AmongUsClientOffset, 0x5C, 0, 0x64 },
                AllPlayerPtrOffsets       = new [] { GameDataOffset, 0x5C, 0, 0x24 },
                AllPlayersOffsets         = new [] { 0x08 },
                PlayerCountOffsets        = new [] { 0x0C },
                ExiledPlayerIdOffsets     = new [] { MeetingHudOffset, 0x5C, 0, 0x94, 0x08 },
                RawGameOverReasonOffsets  = new [] { TempDataOffset, 0x5c, 0x4 },
                WinningPlayersPtrOffsets  = new [] { TempDataOffset, 0x5C, 0xC },
                WinningPlayersOffsets     = new [] { 0x08 },
                WinningPlayerCountOffsets = new [] { 0x0C },
                GameCodeOffsets           = new [] { GameStartManagerOffset, 0x5c, 0, 0x20, 0x28 },
                PlayRegionOffsets         = new [] { ServerManagerOffset, 0x5c, 0, 0x10, 0x8, 0x8 },
                PlayMapOffsets            = new [] { GameOptionsOffset, 0x5c, 0x4, 0x10 },
                StringOffsets             = new [] { 0x8, 0xC },
                isEpic                  = false,
                AddPlayerPtr            = 4,
                PlayerListPtr           = 0x10,
                PlayerInfoStructOffsets = new PlayerInfoStructOffsets()
                {
                    PlayerIDOffset     = 16,
                    PlayerNameOffset   = 24,
                    ColorIDOffset      = 36,
                    HatIDOffset        = 40,
                    PetIDOffset        = 44,
                    SkinIDOffset       = 48,
                    DisconnectedOffset = 52,
                    TasksOffset        = 56,
                    ImposterOffset     = 64,
                    DeadOffset         = 65,
                    ObjectOffset       = 72
                },
                WinningPlayerDataStructOffsets = new WinningPlayerDataStructOffsets()
                {
                    NameOffset     = 0x8,
                    DeadOffset     = 0xC,
                    ImposterOffset = 0xD,
                    ColorOffset    = 0x10,
                    SkinOffset     = 0x14,
                    HatOffset      = 0x18,
                    PetOffset      = 0x1C,
                    IsYouOffset    = 0x20
                }
            };

            Console.Write(JsonConvert.SerializeObject(a, Formatting.Indented));
            //var b = new OffsetManager("");
            //b.AddToLocalIndex(hash, a);
            Console.ReadLine();
        }
Ejemplo n.º 13
0
        private static void Main()
        {
            PluginState.Init();
            PluginState.IsLoaded = true;

            while (Game.IsLoading)
            {
                GameFiber.Sleep(500);
            }

            if (!Directory.Exists(@"Plugins\Spotlight Resources\"))
            {
                Directory.CreateDirectory(@"Plugins\Spotlight Resources\");
            }

            // let's keep using the Offsets.ini file for now
            //string vehSettingsFile = @"Plugins\Spotlight Resources\VehiclesSettings.xml";
            //if (!File.Exists(vehSettingsFile) && File.Exists(@"Plugins\Spotlight Resources\Offsets.ini"))
            //{
            //    // legacy
            //    vehSettingsFile = @"Plugins\Spotlight Resources\Offsets.ini";
            //}

            Settings = new Settings(@"Plugins\Spotlight Resources\General.ini",
                                    @"Plugins\Spotlight Resources\Offsets.ini",
                                    @"Plugins\Spotlight Resources\VisualSettings.xml",
                                    true);

            LoadSpotlightControllers();

            if (!(GameFunctions.Init() && GameMemory.Init() && GameOffsets.Init()))
            {
                Game.DisplayNotification($"~r~[ERROR] Spotlight: ~s~Failed to initialize, unloading...");
                Game.LogTrivial($"[ERROR] Failed to initialize, unloading...");
                Game.UnloadActivePlugin();
            }

            if (Settings.EnableLightEmissives)
            {
                VehiclesUpdateHook.Hook();
            }

            // when the queue array that the GetFreeLightDrawDataSlotFromQueue function accesses is full,
            // it uses the TLS to get an allocator to allocate memory for a bigger array,
            // therefore we copy the allocator pointers from the main thread TLS to our current thread TLS.
            WinFunctions.CopyTlsValues(WinFunctions.GetProcessMainThreadId(), WinFunctions.GetCurrentThreadId(), GameOffsets.TlsAllocator);

            if (Settings.EnableLightEmissives)
            {
                // TODO: find something better than this vehicles update hook to override the extralight emissives values
                // This function may execute multiple times per tick, which is not optimal
                VehiclesUpdateHook.VehiclesUpdate += OnVehiclesUpdate;
            }

            Game.LogTrivial("Initialized");

#if DEBUG
            bool f = false;
#endif
            while (true)
            {
                GameFiber.Yield();

#if DEBUG
                if (Game.LocalPlayer.Character.CurrentVehicle)
                {
                    if (Game.IsKeyDown(System.Windows.Forms.Keys.Y))
                    {
                        Game.LocalPlayer.Character.CurrentVehicle.IsPositionFrozen = f = !f;
                    }
                    else if (Game.IsKeyDown(System.Windows.Forms.Keys.D7))
                    {
                        Game.LocalPlayer.Character.CurrentVehicle.Rotation = new Rotator(45.0f, 0.0f, 0.0f);
                    }
                    else if (Game.IsKeyDown(System.Windows.Forms.Keys.D8))
                    {
                        Game.LocalPlayer.Character.CurrentVehicle.Rotation = new Rotator(0.0f, 45.0f, 0.0f);
                    }
                    else if (Game.IsKeyDown(System.Windows.Forms.Keys.D9))
                    {
                        Game.LocalPlayer.Character.CurrentVehicle.Rotation = new Rotator(0.0f, 0.0f, 45.0f);
                    }
                    else if (Game.IsKeyDown(System.Windows.Forms.Keys.D0))
                    {
                        Game.LocalPlayer.Character.CurrentVehicle.Rotation = Rotator.Zero;
                    }
                }
#endif

                Update();
            }
        }