diff --git a/OverRay.Hook/Detour.cs b/OverRay.Hook/Detour.cs index a272ee9..f1302d0 100644 --- a/OverRay.Hook/Detour.cs +++ b/OverRay.Hook/Detour.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Runtime.InteropServices; using System.Threading; using EasyHook; using OverRay.Hook.Mod; @@ -21,12 +22,18 @@ public Detour(RemoteHooking.IContext context, string channelName) private GameManager Game; - public static Detour Instance; - public void Run(RemoteHooking.IContext inContext, string inChannelName) { try { + // Make sure the game is fully loaded before initializing hooks + while (true) + { + // Engine state: 1 - loading game, 5 - loading level, 9 - loaded + if (Marshal.ReadByte((IntPtr)0x500380) > 8) + break; + } + Game = new GameManager(); RemoteHooking.WakeUpProcess(); @@ -43,33 +50,5 @@ public void Run(RemoteHooking.IContext inContext, string inChannelName) { Interface.GameClosed(); } - - public void GetTextures() - { - IntPtr tPtr = (IntPtr)0x502680; - IntPtr tMemChannelsPtr = (IntPtr)0x501660; - - - uint[] tMemChannels = new uint[1024]; - for (int i = 0; i < tMemChannels.Length; i++) - { - tMemChannels[i] = (uint) Marshal.ReadInt32(tMemChannelsPtr + 4 * i); - } - - List textures = new List(); - for (int i = 0; i < tMemChannels.Length; i++) - { - IntPtr textureStructPtr = Marshal.ReadIntPtr(tPtr + 4 * i); - if (textureStructPtr != IntPtr.Zero && tMemChannels[i] != 0xC0DE0005) - { - Texture texture = new Texture(textureStructPtr); - Game.textures.Add(texture); - if (texture.Name == @"textures_personnages\divers\gra03_lum_my_ad.tga") - { - Interface.WriteLog(Convert.ToString((int)texture.Pointer, 16)); - } - } - } - } } } diff --git a/OverRay.Hook/Mod/GameManager.cs b/OverRay.Hook/Mod/GameManager.cs index d9f7757..4335d77 100644 --- a/OverRay.Hook/Mod/GameManager.cs +++ b/OverRay.Hook/Mod/GameManager.cs @@ -1,6 +1,8 @@ using System; +using System.Collections.Generic; using System.Runtime.InteropServices; using OverRay.Hook.GameFunctions; +using OverRay.Hook.Types; using OverRay.Hook.Utils; namespace OverRay.Hook.Mod @@ -28,10 +30,15 @@ public GameManager() new MenuItem("glowfist power", new Menu(this, new MenuItem("on", () => Marshal.WriteInt32(glowFistPtr, 0x400000)), new MenuItem("off", () => Marshal.WriteInt32(glowFistPtr, 0)) - )) + )), + new MenuItem("texture viewer", () => + { + TextureViewer viewer = new TextureViewer(this); + viewer.Show(); + }) ); - Input.InputActions.Add('m', () => TestMenu.Show()); + Input.InputActions['m'] = () => TestMenu.Show(); } public EngineFunctions Engine { get; } = new EngineFunctions(); diff --git a/OverRay.Hook/Mod/TextureViewer.cs b/OverRay.Hook/Mod/TextureViewer.cs new file mode 100644 index 0000000..61b094d --- /dev/null +++ b/OverRay.Hook/Mod/TextureViewer.cs @@ -0,0 +1,139 @@ +using System; +using System.Collections.Generic; +using OverRay.Hook.Structs; +using OverRay.Hook.Types; +using OverRay.Hook.Utils; + +namespace OverRay.Hook.Mod +{ + public class TextureViewer + { + public TextureViewer(GameManager manager) + { + Manager = manager; + Items = TextureLoader.GetTextures(); //.Where(texture => (int) texture.Pointer > 0x00500000 && (int) texture.Pointer < 0x20000000).ToList(); + } + + private string Id { get; } = Guid.NewGuid().ToString(); + private GameManager Manager { get; } + private Vector3 Pos1 { get; } = new Vector3(5, 8, 0); + private Vector3 Pos2 { get; } = new Vector3(95, 92, 0); + private List Items { get; set; } + + private int _selected; + private int Selected + { + get => _selected; + set + { + if (value >= 0 && value < Items.Count) + _selected = value; + } + } + + private int Pointer => (int)Items[Selected].Pointer; + + public void Show() + { + Selected = 0; + + Manager.Input.DisableGameInput(); + Manager.Input.ExclusiveInput = ProcessInput; + + Manager.Engine.EngineActions[Id] = DrawGraphics; + Manager.Text.TextActions[Id] = DrawText; + } + + public void Hide() + { + Manager.Engine.EngineActions[Id] = () => + { + DrawEmptyParticle(); + Manager.Engine.EngineActions.Remove(Id); + }; + Manager.Text.TextActions.Remove(Id); + + Manager.Input.ExclusiveInput = null; + Manager.Input.EnableGameInput(); + } + + private void ProcessInput(char ch, KeyCode code) + { + if (code == KeyCode.Backspace) + { + Hide(); + } + else if (code == KeyCode.Left) + { + Selected--; + } + else if (code == KeyCode.Right) + { + Selected++; + } + else if (code == KeyCode.Up) + { + Selected += 10; + } + else if (code == KeyCode.Down) + { + Selected -= 10; + } + else if (ch == 'c') + { + Detour.Interface.WriteLog(Items[Selected].Name); + } + else if (ch == 'r') + { + Items = TextureLoader.GetTextures(); + Selected = 0; + } + } + + private void DrawGraphics() + { + using (StructPtr pos1 = new StructPtr(Pos1), pos2 = new StructPtr(Pos2)) + { + Manager.Graphics.VAddParticle.Call(110, pos1, pos2, TexturePointers.blueSparkTexture, 190); + } + + Vector3 rpos1 = new Vector3(Pos1.X + 15, Pos1.Y + 6, 0); + Vector3 rpos2 = new Vector3(rpos1.X + 60, rpos1.Y + 65, 255); + + if (Pointer > 0x00500000 && Pointer < 0x20000000) + { + using (StructPtr pos1 = new StructPtr(rpos1), pos2 = new StructPtr(rpos2)) + { + Manager.Graphics.VAddParticle.Call(125, pos1, pos2, Pointer, 12); + } + } + else DrawEmptyParticle(); + } + + private void DrawText() + { + Manager.Text.CustomText("TEXTURE VIEWER".Red(), 11, (Pos1.X + 2) * 10, (Pos1.Y + 1) * 10); + Manager.Text.CustomText($"{Selected + 1} of {Items.Count}", 11, (Pos1.X + 50) * 10, (Pos1.Y + 1) * 10); + Manager.Text.CustomText(Items[Selected].Name.Replace("_", " "), 6, (Pos1.X + 2) * 10, (Pos2.Y - 11) * 10); + Manager.Text.CustomText("Arrows".Yellow() + " - browse", 9, (Pos1.X + 2) * 10, (Pos2.Y - 7) * 10); + Manager.Text.CustomText("Backspace".Yellow() + " - exit", 9, (Pos1.X + 42) * 10, (Pos2.Y - 7) * 10); + Manager.Text.CustomText("C".Yellow() + " - log texture name", 9, (Pos1.X + 2) * 10, (Pos2.Y - 4) * 10); + Manager.Text.CustomText("R".Yellow() + " - reload textures", 9, (Pos1.X + 42) * 10, (Pos2.Y - 4) * 10); + + Manager.Text.CustomText("", 11, (Pos1.X + 2) * 10, (Pos1.Y + 5) * 10); + + if (Pointer < 0x00500000 || Pointer > 0x20000000) + { + Manager.Text.CustomText($"invalid pointer 0x{Convert.ToString(Pointer, 16)}".Red(), 9, (Pos1.X + 15) * 10, (Pos1.Y + 6) * 10); + } + } + + private void DrawEmptyParticle() + { + using (StructPtr zero = new StructPtr(Vector3.Zero)) + { + Manager.Graphics.VAddParticle.Call(125, zero, zero, 0, 12); + } + } + } +} \ No newline at end of file diff --git a/OverRay.Hook/OverRay.Hook.csproj b/OverRay.Hook/OverRay.Hook.csproj index a845c1e..e37f92d 100644 --- a/OverRay.Hook/OverRay.Hook.csproj +++ b/OverRay.Hook/OverRay.Hook.csproj @@ -57,6 +57,7 @@ + @@ -67,7 +68,7 @@ - + @@ -76,6 +77,7 @@ + diff --git a/OverRay.Hook/Structs/Vector3.cs b/OverRay.Hook/Structs/Vector3.cs index f84cd39..b2dfa0e 100644 --- a/OverRay.Hook/Structs/Vector3.cs +++ b/OverRay.Hook/Structs/Vector3.cs @@ -15,5 +15,7 @@ public Vector3(float x, float y, float z) public float X; public float Y; public float Z; + + public static Vector3 Zero = new Vector3(0, 0, 0); } } \ No newline at end of file diff --git a/OverRay.Hook/Types/KeyCode.cs b/OverRay.Hook/Types/KeyCode.cs index 8ab9ff2..570e7eb 100644 --- a/OverRay.Hook/Types/KeyCode.cs +++ b/OverRay.Hook/Types/KeyCode.cs @@ -1,4 +1,4 @@ -namespace OverRay.Hook.Structs +namespace OverRay.Hook.Types { public enum KeyCode { diff --git a/OverRay.Hook/Texture.cs b/OverRay.Hook/Types/Texture.cs similarity index 94% rename from OverRay.Hook/Texture.cs rename to OverRay.Hook/Types/Texture.cs index aaa0931..5aab2a6 100644 --- a/OverRay.Hook/Texture.cs +++ b/OverRay.Hook/Types/Texture.cs @@ -2,7 +2,7 @@ using System.Runtime.InteropServices; using OverRay.Hook.Structs; -namespace OverRay.Hook +namespace OverRay.Hook.Types { public class Texture { diff --git a/OverRay.Hook/Utils/TextureLoader.cs b/OverRay.Hook/Utils/TextureLoader.cs new file mode 100644 index 0000000..1c034aa --- /dev/null +++ b/OverRay.Hook/Utils/TextureLoader.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using OverRay.Hook.Types; + +namespace OverRay.Hook.Utils +{ + public static class TextureLoader + { + public static List GetTextures() + { + IntPtr tPtr = (IntPtr)0x502680; + IntPtr tMemChannelsPtr = (IntPtr)0x501660; + + uint[] tMemChannels = new uint[1024]; + for (int i = 0; i < tMemChannels.Length; i++) + { + tMemChannels[i] = (uint) Marshal.ReadInt32(tMemChannelsPtr + 4 * i); + } + + List textures = new List(); + for (int i = 0; i < tMemChannels.Length; i++) + { + IntPtr textureStructPtr = Marshal.ReadIntPtr(tPtr + 4 * i); + if (textureStructPtr != IntPtr.Zero && tMemChannels[i] != 0xC0DE0005) + { + Texture texture = new Texture(textureStructPtr); + textures.Add(texture); + } + } + + return textures; + } + } +} \ No newline at end of file