public static void Initialize() { if (Initialized) return; Core.Log(LogSeverity.Minor, "initializing stream hooks.."); _memStreamReadOff = Utility.FindPattern("blue", "55 8b ec 56 8b 75 0c 57 8b f9 85 f6 78 ? 8b 47 18 8d 0c 30 3b 4f 10 76 ? 8b 47 18 8b 77 10"); _memStreamWriteOff = Utility.FindPattern("blue", "55 8b ec 53 8b 5d 0c 56 8b f1 57 8b 7e 18 03 fb 3b 7e 10 76 ? 56 8b c7 e8 ? ? ? ? 84 c0 75 ? 5f 5e"); if (_memStreamReadOff != 0 && _memStreamWriteOff != 0) { Core.Log(LogSeverity.Minor, "stream functions: Read: 0x" + (_memStreamReadOff - BlueOS.Library.ToInt64()).ToString("X") + " Write: 0x" + (_memStreamWriteOff - BlueOS.Library.ToInt64()).ToString("X")); _memStreamReadOrig = Utility.Magic.RegisterDelegate<ReadDelegate>(_memStreamReadOff); _memStreamWriteOrig = Utility.Magic.RegisterDelegate<WriteDelegate>(_memStreamWriteOff); _memStreamReadFake = HandleRead; _memStreamWriteFake = HandleWrite; _memStreamReadDetour = Utility.Magic.Detours.Create(_memStreamReadOrig, _memStreamReadFake, "MemStream::Read"); _memStreamWriteDetour = Utility.Magic.Detours.Create(_memStreamWriteOrig, _memStreamWriteFake, "MemStream::Write"); Core.Log(LogSeverity.Minor, "stream functions hooked"); } else Core.Log(LogSeverity.Minor, "pattern failed to find Read/Write stream functions"); Initialized = true; }
public static void Initialize() { var endScenePointer = IntPtr.Zero; var resetPointer = IntPtr.Zero; using (var d3d = new SlimDX.Direct3D9.Direct3D()) { using ( var tmpDevice = new Device(d3d, 0, DeviceType.Hardware, IntPtr.Zero, CreateFlags.HardwareVertexProcessing, new PresentParameters { BackBufferWidth = 1, BackBufferHeight = 1 })) { endScenePointer = Manager.Memory.GetObjectVtableFunction(tmpDevice.ComPointer, VMT_ENDSCENE); resetPointer = Manager.Memory.GetObjectVtableFunction(tmpDevice.ComPointer, VMT_RESET); } } _endSceneDelegate = Manager.Memory.RegisterDelegate<Direct3D9EndScene>(endScenePointer); _endSceneHook = Manager.Memory.Detours.CreateAndApply(_endSceneDelegate, new Direct3D9EndScene(EndSceneHook), "D9EndScene"); //_resetDelegate = Manager.Memory.RegisterDelegate<Direct3D9Reset>(resetPointer); //_resetHook = Manager.Memory.Detours.CreateAndApply(_resetDelegate, new Direct3D9Reset(ResetHook), "D9Reset"); Log.WriteLine("Direct3D9x:"); Log.WriteLine("\tEndScene: 0x{0:X}", endScenePointer); Log.WriteLine("\tReset: 0x{0:X}", resetPointer); }
public Form1() { InitializeComponent(); dataGridView1.DataSource = Items; _ctmDetour = Helper.Magic.Detours.Create(WoWLocalPlayer.ClickToMoveFunction, new WoWLocalPlayer.ClickToMoveDelegate(HandleClickToMove), "CTMTeleport"); }
public override void Initialize() { using (var fac = new Factory()) { using (var tmpDevice = new Device(fac.GetAdapter(0), DriverType.Hardware, DeviceCreationFlags.None)) { using (var rf = new RenderForm()) { var desc = new SwapChainDescription { BufferCount = 1, Flags = SwapChainFlags.None, IsWindowed = true, ModeDescription = new ModeDescription(100, 100, new Rational(60, 1), Format.R8G8B8A8_UNorm), OutputHandle = rf.Handle, SampleDescription = new SampleDescription(1, 0), SwapEffect = SwapEffect.Discard, Usage = Usage.RenderTargetOutput }; using (var sc = new SwapChain(fac, tmpDevice, desc)) { PresentPointer = Pulse.Magic.GetObjectVtableFunction(sc.ComPointer, VMT_PRESENT); ResetTargetPointer = Pulse.Magic.GetObjectVtableFunction(sc.ComPointer, VMT_RESIZETARGET); } } } } _presentDelegate = Pulse.Magic.RegisterDelegate<Direct3D10Present>(PresentPointer); _presentHook = Pulse.Magic.Detours.CreateAndApply(_presentDelegate, new Direct3D10Present(Callback), "D10Present"); }
public static void Initialize() { var window = new Form(); IntPtr direct3D = Direct3DAPI.Direct3DCreate9(Direct3DAPI.SDKVersion); if (direct3D == IntPtr.Zero) throw new Exception("Direct3DCreate9 failed (SDK Version: " + Direct3DAPI.SDKVersion + ")"); var pp = new Direct3DAPI.PresentParameters { Windowed = true, SwapEffect = 1, BackBufferFormat = 0 }; var createDevice = Helper.Magic.RegisterDelegate<Direct3DAPI.Direct3D9CreateDevice>(Helper.Magic.GetObjectVtableFunction(direct3D, 16)); IntPtr device; if (createDevice(direct3D, 0, 1, window.Handle, 0x20, ref pp, out device) < 0) throw new Exception("Failed to create device"); EndScenePointer = Helper.Magic.GetObjectVtableFunction(device, Direct3DAPI.EndSceneOffset); ResetPointer = Helper.Magic.GetObjectVtableFunction(device, Direct3DAPI.ResetOffset); ResetExPointer = Helper.Magic.GetObjectVtableFunction(device, Direct3DAPI.ResetExOffset); var deviceRelease = Helper.Magic.RegisterDelegate<Direct3DAPI.D3DRelease>(Helper.Magic.GetObjectVtableFunction(device, 2)); var release = Helper.Magic.RegisterDelegate<Direct3DAPI.D3DRelease>(Helper.Magic.GetObjectVtableFunction(direct3D, 2)); deviceRelease(device); release(direct3D); window.Dispose(); // TODO: replace this with a VTable hook _endSceneDelegate = Helper.Magic.RegisterDelegate<Direct3DAPI.Direct3D9EndScene>(EndScenePointer); _endSceneHook = Helper.Magic.Detours.CreateAndApply(_endSceneDelegate, new Direct3DAPI.Direct3D9EndScene(EndSceneHook), "EndScene"); }
public override void Initialize() { Device tmpDevice; SwapChain sc; using (var rf = new RenderForm()) { var desc = new SwapChainDescription { BufferCount = 1, Flags = SwapChainFlags.None, IsWindowed = true, ModeDescription = new ModeDescription(100, 100, new Rational(60, 1), SlimDX.DXGI.Format.R8G8B8A8_UNorm), OutputHandle = rf.Handle, SampleDescription = new SampleDescription(1, 0), SwapEffect = SwapEffect.Discard, Usage = Usage.RenderTargetOutput }; var res = Device.CreateWithSwapChain(DriverType.Hardware, DeviceCreationFlags.None, desc, out tmpDevice, out sc); if (res.IsSuccess) { using (tmpDevice) { using (sc) { PresentPointer = Pulse.Magic.GetObjectVtableFunction(sc.ComPointer, VMT_PRESENT); ResetTargetPointer = Pulse.Magic.GetObjectVtableFunction(sc.ComPointer, VMT_RESIZETARGET); } } } } _presentDelegate = Pulse.Magic.RegisterDelegate<Direct3D11Present>(PresentPointer); _presentHook = Pulse.Magic.Detours.CreateAndApply(_presentDelegate, new Direct3D11Present(Callback), "D11Present"); }
public WoWEvents() { var eventVictim = Manager.Memory.RegisterDelegate<LuaFunctionDelegate>( (IntPtr)Pointers.Events.EventVictim); if (_eventDetour == null || !_eventDetour.IsApplied) _eventDetour = Manager.Memory.Detours.CreateAndApply(eventVictim, new LuaFunctionDelegate(HandleVictimCall), "EventVictim"); }
public override void Initialize() { using (var d3d = new Direct3D()) { using (var tmpDevice = new Device(d3d, 0, DeviceType.Hardware, IntPtr.Zero, CreateFlags.HardwareVertexProcessing, new PresentParameters() { BackBufferWidth = 1, BackBufferHeight = 1 })) { EndScenePointer = Pulse.Magic.GetObjectVtableFunction(tmpDevice.ComPointer, VMT_ENDSCENE); ResetPointer = Pulse.Magic.GetObjectVtableFunction(tmpDevice.ComPointer, VMT_RESET); } } _endSceneDelegate = Pulse.Magic.RegisterDelegate<Direct3D9EndScene>(EndScenePointer); _endSceneHook = Pulse.Magic.Detours.CreateAndApply(_endSceneDelegate, new Direct3D9EndScene(Callback), "D9EndScene"); }
bool GetSteerTarget(float[] startPos, float[] endPos, float minTargetDist, ulong[] path, uint pathSize, out float[] steerPos, out Detour.dtStraightPathFlags steerPosFlag, out ulong steerPosRef) { steerPosRef = 0; steerPos = new float[3]; steerPosFlag = 0; // Find steer target. float[] steerPath = new float[3 * 3]; byte[] steerPathFlags = new byte[3]; ulong[] steerPathPolys = new ulong[3]; int nsteerPath = 0; uint dtResult = _navMeshQuery.findStraightPath(startPos, endPos, path, (int)pathSize, steerPath, steerPathFlags, steerPathPolys, ref nsteerPath, 3, 0); if (nsteerPath == 0 || Detour.dtStatusFailed(dtResult)) { return(false); } // Find vertex far enough to steer to. uint ns = 0; while (ns < nsteerPath) { Span <float> span = steerPath; // Stop at Off-Mesh link or when point is further than slop away. if ((steerPathFlags[ns].HasAnyFlag((byte)Detour.dtStraightPathFlags.DT_STRAIGHTPATH_OFFMESH_CONNECTION) || !InRangeYZX(span.Slice((int)ns * 3).ToArray(), startPos, minTargetDist, 1000.0f))) { break; } ns++; } // Failed to find good point to steer to. if (ns >= nsteerPath) { return(false); } Detour.dtVcopy(steerPos, 0, steerPath, (int)ns * 3); steerPos[1] = startPos[1]; // keep Z value steerPosFlag = (Detour.dtStraightPathFlags)steerPathFlags[ns]; steerPosRef = steerPathPolys[ns]; return(true); }
internal static void Load() { ILEdits = new Dictionary <string, ILEdit>(); Detours = new Dictionary <string, Detour>(); Type[] types = JourneysBeginning.Instance.Code.GetTypes(); foreach (Type type in types) { if (type.IsAbstract || type.GetConstructor(new Type[0]) == null) { continue; } if (type.IsSubclassOf(typeof(ILEdit))) { ILEdit ilEdit = Activator.CreateInstance(type) as ILEdit; ILEdits.Add(ilEdit.DictKey, ilEdit); } if (type.IsSubclassOf(typeof(Detour))) { Detour detour = Activator.CreateInstance(type) as Detour; Detours.Add(detour.DictKey, detour); } } JourneysBeginning.ModLogger.Debug($"Found {ILEdits.Count} IL edits to load!"); foreach (ILEdit ilEdit in ILEdits.Values) { ilEdit.Load(); } JourneysBeginning.ModLogger.Debug($"Found {Detours.Count} detours to load!"); foreach (Detour detour in Detours.Values) { detour.Load(); } HasLoaded = true; }
public LoadMapDetour GetLoadMapHook(Process game, IntPtr setMapPtr, IntPtr statusPtr) { if (LoadMapDetourT == null) { throw new Exception("No LoadMapDetour type defined"); } var originalPtr = Detour.FindExportedFunc(LoadMapDetourT, game); if (originalPtr != IntPtr.Zero) { return((LoadMapDetour)Activator.CreateInstance(LoadMapDetourT, setMapPtr, statusPtr)); } else { return(null); } }
// To add our own keybind actions natively we need to intercept a method in a Rewired dll. // Normally, we use the hooks that Partiality uses MonoMod to generate (called HookGen), // but Partiality only instructs MonoMod to hook methods in the Assembly-CSharp.dll file, // so we need to manually hook the Rewired method. We do this in exactly the same way that // Partiality uses MonoMod--with MonoMod.RuntimeDetour--but we do it manually. private static void InitHooks() { // Create the manual hook of the Initialize method in Rewired's InputManager_Base class orig_Initialize = (h_Initialize = new Detour( typeof(InputManager_Base).GetMethod("Initialize", BindingFlags.Instance | BindingFlags.NonPublic), typeof(CustomKeybindings).GetMethod("InputManager_Base_Initialize", BindingFlags.Static | BindingFlags.NonPublic) )).GenerateTrampoline <d_Initialize>(); // Use a normal HookGen hook of the bindings panel to add action-to-element maps for our custom actions // ActionElementMaps bind a keyboard key or controller or mouse input to an action On.ControlMappingPanel.InitSections += new On.ControlMappingPanel.hook_InitSections(ControlMappingPanel_InitSections); // Use a normal HookGen hook of the localization manager to give our keybinding a nice name in the bindings menu On.LocalizationManager.StartLoading += new On.LocalizationManager.hook_StartLoading(LocalizationManager_StartLoading); // Expose & cache an object that will be accessed on every update to check for key presses. It's private so we have to get at it with reflection m_playerInputManager = (Dictionary <int, RewiredInputs>) typeof(ControlsInput).GetField("m_playerInputManager", BindingFlags.NonPublic | BindingFlags.Static).GetValue(null); // null for static field }
public SaveGameDetour GetSaveGameHook(Process game, IntPtr statusPtr) { if (SaveGameDetourT == null) { throw new Exception("No SaveGameDetour type defined"); } var originalPtr = Detour.FindExportedFunc(SaveGameDetourT, game); if (originalPtr != IntPtr.Zero) { return((SaveGameDetour)Activator.CreateInstance(SaveGameDetourT, statusPtr)); } else { return(null); } }
public bool ComputeSystem(byte[] tileRawData, int start) { m_ctx.enableLog(true); m_ctx.resetTimers(); // Start the build process. m_ctx.startTimer(Recast.rcTimerLabel.RC_TIMER_TOTAL); m_rawTileData = new Detour.dtRawTileData(); m_rawTileData.FromBytes(tileRawData, start); m_navMesh = new Detour.dtNavMesh(); if (m_navMesh == null) { m_ctx.log(Recast.rcLogCategory.RC_LOG_ERROR, "Could not create Detour navmesh"); return(false); } dtStatus status; status = m_navMesh.init(m_rawTileData, (int)Detour.dtTileFlags.DT_TILE_FREE_DATA); if (Detour.dtStatusFailed(status)) { m_ctx.log(Recast.rcLogCategory.RC_LOG_ERROR, "Could not init Detour navmesh"); return(false); } m_navQuery = new Detour.dtNavMeshQuery(); status = m_navQuery.init(m_navMesh, 2048); if (Detour.dtStatusFailed(status)) { m_ctx.log(Recast.rcLogCategory.RC_LOG_ERROR, "Could not init Detour navmesh query"); return(false); } m_ctx.stopTimer(Recast.rcTimerLabel.RC_TIMER_TOTAL); //m_ctx.log(Recast.rcLogCategory.RC_LOG_PROGRESS, ">> Polymesh: " + m_pmesh.nverts + " vertices " + m_pmesh.npolys + " polygons"); m_totalBuildTimeMs = (float)m_ctx.getAccumulatedTime(Recast.rcTimerLabel.RC_TIMER_TOTAL); return(true); }
void RemoveSwap(PhasedTile ptile, uint swap, uint packedXY) { uint x = (packedXY >> 16); uint y = (packedXY & 0x0000FFFF); if (!loadedPhasedTiles[swap].Contains(packedXY)) { Log.outDebug(LogFilter.Maps, "MMapData.RemoveSwap: mmtile {0:D4}[{1:D2}, {2:D2}] unload skipped, due to not loaded", swap, x, y); return; } Detour.dtMeshHeader header = ptile.data.header; Detour.dtRawTileData data; // remove old tile if (Detour.dtStatusFailed(navMesh.removeTile(loadedTileRefs[packedXY], out data))) { Log.outError(LogFilter.Maps, "MMapData.RemoveSwap: Could not unload phased {0:D4}{1:D2}{2:D2}.mmtile from navmesh", swap, x, y); } else { Log.outDebug(LogFilter.Maps, "MMapData.RemoveSwap: Unloaded phased {0:D4}{1:D2}{2:D2}.mmtile from navmesh", swap, x, y); // restore base tile ulong loadedRef = 0; if (Detour.dtStatusSucceed(navMesh.addTile(_baseTiles[packedXY].data, 0, 0, ref loadedRef))) { Log.outDebug(LogFilter.Maps, "MMapData.RemoveSwap: Loaded base mmtile {0:D4}[{1:D2}, {2:D2}] into {0:D4}[{1:D2}, {2:D2}]", _mapId, x, y, _mapId, header.x, header.y); } else { Log.outError(LogFilter.Maps, "MMapData.RemoveSwap: Could not load base {0:D4}{1:D2}{2:D2}.mmtile to navmesh", _mapId, x, y); } loadedTileRefs[packedXY] = loadedRef; } loadedPhasedTiles.Remove(swap, packedXY); if (loadedPhasedTiles[swap].Empty()) { _activeSwaps.Remove(swap); Log.outDebug(LogFilter.Maps, "MMapData.RemoveSwap: Fully removed swap {0} from map {1}", swap, _mapId); } }
bool unloadMapImpl(uint mapId, uint x, uint y) { // check if we have this map loaded MMapData mmap = GetMMapData(mapId); if (mmap == null) { // file may not exist, therefore not loaded Log.outDebug(LogFilter.Maps, "MMAP:unloadMap: Asked to unload not loaded navmesh map. {0:D4}{1:D2}{2:D2}.mmtile", mapId, x, y); return(false); } // check if we have this tile loaded uint packedGridPos = packTileID(x, y); if (!mmap.loadedTileRefs.ContainsKey(packedGridPos)) { // file may not exist, therefore not loaded Log.outDebug(LogFilter.Maps, "MMAP:unloadMap: Asked to unload not loaded navmesh tile. {0:D4}{1:D2}{2:D2}.mmtile", mapId, x, y); return(false); } ulong tileRef = mmap.loadedTileRefs[packedGridPos]; // unload, and mark as non loaded Detour.dtRawTileData data; if (Detour.dtStatusFailed(mmap.navMesh.removeTile(tileRef, out data))) { // this is technically a memory leak // if the grid is later reloaded, dtNavMesh.addTile will return error but no extra memory is used // we cannot recover from this error - assert out Log.outError(LogFilter.Maps, "MMAP:unloadMap: Could not unload {0:D4}{1:D2}{2:D2}.mmtile from navmesh", mapId, x, y); Cypher.Assert(false); } else { mmap.loadedTileRefs.Remove(packedGridPos); --loadedTiles; Log.outInfo(LogFilter.Maps, "MMAP:unloadMap: Unloaded mmtile {0:D4}[{1:D2}, {2:D2}] from {3:D4}", mapId, x, y, mapId); return(true); } return(false); }
bool loadMapData(uint mapId) { // we already have this map loaded? if (loadedMMaps.ContainsKey(mapId) && loadedMMaps[mapId] != null) { return(true); } // load and init dtNavMesh - read parameters from file string filename = string.Format(MAP_FILE_NAME_FORMAT, Global.WorldMgr.GetDataPath(), mapId); if (!File.Exists(filename)) { Log.outError(LogFilter.Maps, "Could not open mmap file {0}", filename); return(false); } using (BinaryReader reader = new BinaryReader(new FileStream(filename, FileMode.Open, FileAccess.Read), Encoding.UTF8)) { Detour.dtNavMeshParams Params = new Detour.dtNavMeshParams(); Params.orig[0] = reader.ReadSingle(); Params.orig[1] = reader.ReadSingle(); Params.orig[2] = reader.ReadSingle(); Params.tileWidth = reader.ReadSingle(); Params.tileHeight = reader.ReadSingle(); Params.maxTiles = reader.ReadInt32(); Params.maxPolys = reader.ReadInt32(); Detour.dtNavMesh mesh = new Detour.dtNavMesh(); if (Detour.dtStatusFailed(mesh.init(Params))) { Log.outError(LogFilter.Maps, "MMAP:loadMapData: Failed to initialize dtNavMesh for mmap {0:D4} from file {1}", mapId, filename); return(false); } Log.outInfo(LogFilter.Maps, "MMAP:loadMapData: Loaded {0:D4}.mmap", mapId); // store inside our map list loadedMMaps[mapId] = new MMapData(mesh, mapId); return(true); } }
private static void HookClassFromType() { var lib = LoadLibrary("GameAssembly.dll"); var classFromTypeEntryPoint = GetProcAddress(lib, nameof(IL2CPP.il2cpp_class_from_il2cpp_type)); LogSupport.Trace($"il2cpp_class_from_il2cpp_type entry address: {classFromTypeEntryPoint}"); var targetMethod = XrefScannerLowLevel.JumpTargets(classFromTypeEntryPoint).Single(); LogSupport.Trace($"Xref scan target: {targetMethod}"); if (targetMethod == IntPtr.Zero) { return; } ourOriginalTypeToClassMethod = Detour.Detour(targetMethod, new TypeToClassDelegate(ClassFromTypePatch)); LogSupport.Trace("il2cpp_class_from_il2cpp_type patched"); }
public static void Load() { Detours = new Dictionary <string, Detour>(); ILEdits = new Dictionary <string, ILEdit>(); foreach (Type type in CataclysmMod.Instance.Code.GetTypes()) { if (!type.IsAbstract && type.GetConstructor(new Type[] { }) != null) { if (type.IsSubclassOf(typeof(Detour))) { Detour detour = Activator.CreateInstance(type) as Detour; if (detour.Autoload()) { Detours.Add(detour.DictKey, detour); } } if (type.IsSubclassOf(typeof(ILEdit))) { ILEdit ilEdit = Activator.CreateInstance(type) as ILEdit; if (ilEdit.Autoload()) { ILEdits.Add(ilEdit.DictKey, ilEdit); } } } } foreach (Detour detour in Detours.Values) { detour.Load(); } foreach (ILEdit ilEdit in ILEdits.Values) { ilEdit.Load(); } }
public static void Initialize() { var window = new Form(); IntPtr direct3D = Direct3DAPI.Direct3DCreate9(Direct3DAPI.SDKVersion); if (direct3D == IntPtr.Zero) { throw new Exception("Direct3DCreate9 failed (SDK Version: " + Direct3DAPI.SDKVersion + ")"); } var pp = new Direct3DAPI.PresentParameters { Windowed = true, SwapEffect = 1, BackBufferFormat = 0 }; var createDevice = Helper.Magic.RegisterDelegate <Direct3DAPI.Direct3D9CreateDevice>(Helper.Magic.GetObjectVtableFunction(direct3D, 16)); IntPtr device; if (createDevice(direct3D, 0, 1, window.Handle, 0x20, ref pp, out device) < 0) { throw new Exception("Failed to create device"); } EndScenePointer = Helper.Magic.GetObjectVtableFunction(device, Direct3DAPI.EndSceneOffset); ResetPointer = Helper.Magic.GetObjectVtableFunction(device, Direct3DAPI.ResetOffset); ResetExPointer = Helper.Magic.GetObjectVtableFunction(device, Direct3DAPI.ResetExOffset); var deviceRelease = Helper.Magic.RegisterDelegate <Direct3DAPI.D3DRelease>(Helper.Magic.GetObjectVtableFunction(device, 2)); var release = Helper.Magic.RegisterDelegate <Direct3DAPI.D3DRelease>(Helper.Magic.GetObjectVtableFunction(direct3D, 2)); deviceRelease(device); release(direct3D); window.Dispose(); _endSceneDelegate = Helper.Magic.RegisterDelegate <Direct3DAPI.Direct3D9EndScene>(EndScenePointer); _endSceneHook = Helper.Magic.Detours.CreateAndApply(_endSceneDelegate, new Direct3DAPI.Direct3D9EndScene(EndSceneHook), "EndScene"); _resetDelegate = Helper.Magic.RegisterDelegate <Direct3DAPI.Direct3D9Reset>(ResetPointer); _resetHook = Helper.Magic.Detours.CreateAndApply(_resetDelegate, new Direct3DAPI.Direct3D9Reset(ResetHook), "Reset"); }
public void Remove(Delegate hookDelegate) { if (hookDelegate == null) { return; } // Note: A hook delegate can be applied multiple times. // The following code removes the last hook of that delegate type. Stack <Hook> hooks; if (!HookMap.TryGetValue(hookDelegate, out hooks)) { return; } Hook hook = hooks.Pop(); hook.Dispose(); if (hooks.Count == 0) { HookMap.Remove(hookDelegate); } int index = HookList.IndexOf(hook); HookList.RemoveAt(index); if (index == 0) { if (HookList.Count != 0) { HookList[0].UpdateOrig(ILManipulated); } else if (ILManipulated != null) { ILDetour = new Detour(Method, ILManipulated); } } }
public override void Initialize() { Device tmpDevice; SwapChain sc; using (var rf = new RenderForm()) { var desc = new SwapChainDescription { BufferCount = 1, Flags = SwapChainFlags.None, IsWindowed = true, ModeDescription = new ModeDescription(100, 100, new Rational(60, 1), Format.R8G8B8A8_UNorm), OutputHandle = rf.Handle, SampleDescription = new SampleDescription(1, 0), SwapEffect = SwapEffect.Discard, Usage = Usage.RenderTargetOutput }; Result res = Device.CreateWithSwapChain(DriverType.Hardware, DeviceCreationFlags.None, desc, out tmpDevice, out sc); if (res.IsSuccess) { using (tmpDevice) { using (sc) { PresentPointer = GeneralHelper.Memory.GetVFTableEntry(sc.ComPointer, VMT_PRESENT); ResetTargetPointer = GeneralHelper.Memory.GetVFTableEntry(sc.ComPointer, VMT_RESIZETARGET); } } } } _presentDelegate = GeneralHelper.Memory.CreateFunction <Direct3D11Present>(PresentPointer); _presentHook = GeneralHelper.Memory.Detours.CreateAndApply(_presentDelegate, new Direct3D11Present(Callback), "D11Present"); }
public bool Initialize(LaunchStage stage) { if (stage == LaunchStage.PostBlue) { { var addr = Utility.FindPattern("python27", "55 8b ec 81 ec 04 01 00 00 53 ff 75 0c 8b 5d 08 e8 ? ? ? ? 59 8d 8d fc fe ff ff 51 50 ff ? 0c e8 ? ? ? ? 59 50 e8 ? ? ? ? 83 c4 ?"); if (addr == 0) { Core.Log(LogSeverity.Warning, "Can't find get_module_info function; pattern outdated? Zip Importer hook disabling."); return(true); } _getModuleInfoOrig = Utility.Magic.RegisterDelegate <GetModuleInfoDel>(addr); _getModuleInfoFake = HandleGetModuleInfo; _getModuleInfoDetour = Utility.Magic.Detours.CreateAndApply(_getModuleInfoOrig, _getModuleInfoFake, "get_module_info"); } { var addr = Utility.FindPattern("python27", "55 8b ec 81 ec 10 01 00 00 56 ff 75 0c e8 ? ? ? ? 8b ? 08 59 8d ? ? ? ? ? 51 50 ff 76 ? e8 ? ? ? ? 59 50 e8 ? ? ? ? 83 c4 0c 85 c0 79 ? 33 c0"); if (addr == 0) { Core.Log(LogSeverity.Warning, "Can't find get_module_code function; pattern outdated? Zip Importer hook disabling."); return(true); } _getModuleCodeOrig = Utility.Magic.RegisterDelegate <GetModuleCodeDel>(addr); _getModuleCodeFake = HandleGetModuleCode; _getModuleCodeDetour = Utility.Magic.Detours.CreateAndApply(_getModuleCodeOrig, _getModuleCodeFake, "get_module_code"); } Core.Log(LogSeverity.Minor, "initialized zip importer hooks"); } return(true); }
internal IntPtr ToVTablePointer() { if (EndSceneVTablePtr != IntPtr.Zero) { return(EndSceneVTablePtr); } _iSceneEndDelegate = Memory.Reader.RegisterDelegate <Direct3D9ISceneEnd>(funcs.IsSceneEnd); _isSceneEndHook = Memory.Reader.Detours.CreateAndApply( _iSceneEndDelegate, new Direct3D9ISceneEnd(IsSceneEndHook), "IsSceneEnd"); while (EndSceneVTablePtr == IntPtr.Zero) { Task.Delay(5).Wait(); } return(EndSceneVTablePtr); }
internal static IntPtr ToPointer() { if (EndScenePtr != IntPtr.Zero) { return(EndScenePtr); } _isSceneEndDelegate = Memory.Reader.RegisterDelegate <Direct3D9IsSceneEnd>(funcs.IsSceneEnd); _isSceneEndHook = Memory.Reader.Detours.CreateAndApply( _isSceneEndDelegate, new Direct3D9IsSceneEnd(IsSceneEndHook), "IsSceneEnd"); while (EndScenePtr == IntPtr.Zero) { Thread.Sleep(5); } return(EndScenePtr); }
public bool Initialize(LaunchStage stage) { if (stage == LaunchStage.PreBlue) { _cryptVerifyDetour = DetourAPI <CryptVerifySignature>("advapi32.dll", "CryptVerifySignatureA", HandleVerify); if (_cryptVerifyDetour != null) { Core.Log(LogSeverity.Minor, "disabled all crypto verification"); } } if (stage == LaunchStage.PostBlue) { // Encryption & Decryption _cryptEncryptDetour = DetourAPI <CryptEncryptDelegate>("advapi32.dll", "CryptEncrypt", HandleCryptEncrypt); _cryptDecryptDetour = DetourAPI <CryptDecryptDelegate>("advapi32.dll", "CryptDecrypt", HandleCryptDecrypt); Core.Log(LogSeverity.Minor, "CryptoHook active"); } return(true); }
public bool unloadMap(uint mapId) { if (!loadedMMaps.ContainsKey(mapId)) { // file may not exist, therefore not loaded Log.outDebug(LogFilter.Maps, "MMAP:unloadMap: Asked to unload not loaded navmesh map {0:D4}", mapId); return(false); } // unload all tiles from given map MMapData mmap = loadedMMaps.LookupByKey(mapId); foreach (var i in mmap.loadedTileRefs) { uint x = (i.Key >> 16); uint y = (i.Key & 0x0000FFFF); Detour.dtRawTileData data; if (Detour.dtStatusFailed(mmap.navMesh.removeTile(i.Value, out data))) { Log.outError(LogFilter.Maps, "MMAP:unloadMap: Could not unload {0:D4}{1:D2}{2:D2}.mmtile from navmesh", mapId, x, y); } else { var phasedMaps = phaseMapData.LookupByKey(mapId); if (!phasedMaps.Empty()) { mmap.DeleteBaseTile(i.Key); UnloadPhaseTile(phasedMaps, (int)x, (int)y); } --loadedTiles; Log.outInfo(LogFilter.Maps, "MMAP:unloadMap: Unloaded mmtile {0:D4} [{1:D2}, {2:D2}] from {3:D4}", mapId, x, y, mapId); } } loadedMMaps.Remove(mapId); Log.outInfo(LogFilter.Maps, "MMAP:unloadMap: Unloaded {0:D4}.mmap", mapId); return(true); }
ulong GetPathPolyByPosition(ulong[] polyPath, uint polyPathSize, float[] point, ref float distance) { if (polyPath == null || polyPathSize == 0) { return(0); } ulong nearestPoly = 0; float minDist2d = float.MaxValue; float minDist3d = 0.0f; for (uint i = 0; i < polyPathSize; ++i) { float[] closestPoint = new float[3]; bool posOverPoly = false; if (Detour.dtStatusFailed(_navMeshQuery.closestPointOnPoly(polyPath[i], point, closestPoint, ref posOverPoly))) { continue; } float d = Detour.dtVdist2DSqr(point, closestPoint); if (d < minDist2d) { minDist2d = d; nearestPoly = polyPath[i]; minDist3d = Detour.dtVdistSqr(point, closestPoint); } if (minDist2d < 1.0f) // shortcut out - close enough for us { break; } } distance = (float)Math.Sqrt(minDist3d); return((minDist2d < 3.0f) ? nearestPoly : 0u); }
public override int GetHashCode() { int hash = 1; hash ^= user_.GetHashCode(); if (default_ != null) { hash ^= Default.GetHashCode(); } if (detour_ != null) { hash ^= Detour.GetHashCode(); } if (SecureEncryptionOnly != false) { hash ^= SecureEncryptionOnly.GetHashCode(); } if (_unknownFields != null) { hash ^= _unknownFields.GetHashCode(); } return(hash); }
internal HookEndpoint(MethodBase method) { Method = method; // Add a "transparent" detour for IL manipulation. bool hasMethodBody; try { hasMethodBody = (method.GetMethodBody()?.GetILAsByteArray()?.Length ?? 0) != 0; } catch { hasMethodBody = false; } if (hasMethodBody) { // Note: This can but shouldn't fail, mainly if the user hasn't provided a Cecil ModuleDefinition generator. DMD = new DynamicMethodDefinition(method, HookEndpointManager.GenerateCecilModule); ILCopy = method.CreateILCopy(); ILDetour = new Detour(method, ILCopy); DetourILDetourTarget(); } }
/// <summary> /// NOTE: You can currently only filter the packets for SEND and RECV channels. /// </summary> /// <param name="channels"> By default, all channels are selected. </param> /// <param name="interceptCallback"> The packets intercepted will be received here for logging, and filtering if necessary. </param> public NetworkDetour Install(PacketChannel channels, InterceptCallback interceptCallback) { SelectedChannels = channels; OnReceivePacket = interceptCallback; if (SelectedChannels.HasFlag(PacketChannel.Send)) { SendHook = new Detour().Install("ws2_32.dll", "send", callback_repl_send); } if (SelectedChannels.HasFlag(PacketChannel.Recv)) { RecvHook = new Detour().Install("ws2_32.dll", "recv", callback_repl_recv); } if (SelectedChannels.HasFlag(PacketChannel.SendTo)) { SendToHook = new Detour().Install("ws2_32.dll", "sendto", callback_repl_send_to); } if (SelectedChannels.HasFlag(PacketChannel.RecvFrom)) { RecvFromHook = new Detour().Install("ws2_32.dll", "recvfrom", callback_repl_recv_from); } if (SelectedChannels.HasFlag(PacketChannel.WSASend)) { WSASendHook = new Detour().Install("ws2_32.dll", "WSASend", callback_repl_wsa_send); } if (SelectedChannels.HasFlag(PacketChannel.WSARecv)) { WSARecvHook = new Detour().Install("ws2_32.dll", "WSARecv", callback_repl_wsa_recv); } return(this); }
ulong GetPolyByLocation(float[] point, ref float distance) { // first we check the current path // if the current path doesn't contain the current poly, // we need to use the expensive navMesh.findNearestPoly ulong polyRef = GetPathPolyByPosition(_pathPolyRefs, _polyLength, point, ref distance); if (polyRef != 0) { return(polyRef); } // we don't have it in our old path // try to get it by findNearestPoly() // first try with low search box float[] extents = { 3.0f, 5.0f, 3.0f }; // bounds of poly search area float[] closestPoint = { 0.0f, 0.0f, 0.0f }; if (Detour.dtStatusSucceed(_navMeshQuery.findNearestPoly(point, extents, _filter, ref polyRef, ref closestPoint)) && polyRef != 0) { distance = Detour.dtVdist(closestPoint, point); return(polyRef); } // still nothing .. // try with bigger search box // Note that the extent should not overlap more than 128 polygons in the navmesh (see dtNavMeshQuery.findNearestPoly) extents[1] = 50.0f; if (Detour.dtStatusSucceed(_navMeshQuery.findNearestPoly(point, extents, _filter, ref polyRef, ref closestPoint)) && polyRef != 0) { distance = Detour.dtVdist(closestPoint, point); return(polyRef); } distance = float.MaxValue; return(0); }
internal void UpdateILManipulated(bool force = false) { if (force || ILList.Count != 0) { ILManipulated = DMD.Generate(); } else { ILManipulated = null; } if (HookList.Count != 0) { HookList[0].UpdateOrig(ILManipulated); } else { ILDetour?.Dispose(); if (ILManipulated != null) { ILDetour = new Detour(Method, ILManipulated); } } }
public static void Install() { if (_applied) { return; } var refreshDet = new Detour(AccessTools.Method(AccessTools.Inner(typeof(ILHook), "Context"), "Refresh"), AccessTools.Method(typeof(StackTraceFixes), nameof(OnILChainRefresh))); _origRefresh = refreshDet.GenerateTrampoline <Action <object> >(); var getMethodDet = new Detour(AccessTools.Method(typeof(StackFrame), nameof(StackFrame.GetMethod)), AccessTools.Method(typeof(StackTraceFixes), nameof(GetMethodFix))); _origGetMethod = getMethodDet.GenerateTrampoline <Func <StackFrame, MethodBase> >(); var nat = new NativeDetour(AccessTools.Method(typeof(Assembly), nameof(Assembly.GetExecutingAssembly)), AccessTools.Method(typeof(StackTraceFixes), nameof(GetAssemblyFix))); _realGetAss = nat.GenerateTrampoline <Func <Assembly> >(); _applied = true; }
void BuildPolyPath(Vector3 startPos, Vector3 endPos) { // *** getting start/end poly logic *** float distToStartPoly = 0; float distToEndPoly = 0; float[] startPoint = { startPos.Y, startPos.Z, startPos.X }; float[] endPoint = { endPos.Y, endPos.Z, endPos.X }; ulong startPoly = GetPolyByLocation(startPoint, ref distToStartPoly); ulong endPoly = GetPolyByLocation(endPoint, ref distToEndPoly); // we have a hole in our mesh // make shortcut path and mark it as NOPATH ( with flying and swimming exception ) // its up to caller how he will use this info if (startPoly == 0 || endPoly == 0) { Log.outDebug(LogFilter.Maps, "++ BuildPolyPath . (startPoly == 0 || endPoly == 0)\n"); BuildShortcut(); bool path = _sourceUnit.IsTypeId(TypeId.Unit) && _sourceUnit.ToCreature().CanFly(); bool waterPath = _sourceUnit.IsTypeId(TypeId.Unit) && _sourceUnit.ToCreature().CanSwim(); if (waterPath) { // Check both start and end points, if they're both in water, then we can *safely* let the creature move for (uint i = 0; i < _pathPoints.Length; ++i) { ZLiquidStatus status = _sourceUnit.GetMap().getLiquidStatus(_pathPoints[i].X, _pathPoints[i].Y, _pathPoints[i].Z, MapConst.MapAllLiquidTypes); // One of the points is not in the water, cancel movement. if (status == ZLiquidStatus.NoWater) { waterPath = false; break; } } } pathType = (path || waterPath) ? (PathType.Normal | PathType.NotUsingPath) : PathType.NoPath; return; } // we may need a better number here bool farFromPoly = (distToStartPoly > 7.0f || distToEndPoly > 7.0f); if (farFromPoly) { Log.outDebug(LogFilter.Maps, "++ BuildPolyPath . farFromPoly distToStartPoly={0:F3} distToEndPoly={1:F3}\n", distToStartPoly, distToEndPoly); bool buildShotrcut = false; if (_sourceUnit.IsTypeId(TypeId.Unit)) { Creature owner = _sourceUnit.ToCreature(); Vector3 p = (distToStartPoly > 7.0f) ? startPos : endPos; if (_sourceUnit.GetMap().IsUnderWater(p.X, p.Y, p.Z)) { Log.outDebug(LogFilter.Maps, "++ BuildPolyPath . underWater case\n"); if (owner.CanSwim()) { buildShotrcut = true; } } else { Log.outDebug(LogFilter.Maps, "++ BuildPolyPath . flying case\n"); if (owner.CanFly()) { buildShotrcut = true; } } } if (buildShotrcut) { BuildShortcut(); pathType = (PathType.Normal | PathType.NotUsingPath); return; } else { float[] closestPoint = new float[3]; // we may want to use closestPointOnPolyBoundary instead bool posOverPoly = false; if (Detour.dtStatusSucceed(_navMeshQuery.closestPointOnPoly(endPoly, endPoint, closestPoint, ref posOverPoly))) { Detour.dtVcopy(endPoint, closestPoint); SetActualEndPosition(new Vector3(endPoint[2], endPoint[0], endPoint[1])); } pathType = PathType.Incomplete; } } // *** poly path generating logic *** // start and end are on same polygon // just need to move in straight line if (startPoly == endPoly) { Log.outDebug(LogFilter.Maps, "++ BuildPolyPath . (startPoly == endPoly)\n"); BuildShortcut(); _pathPolyRefs[0] = startPoly; _polyLength = 1; pathType = farFromPoly ? PathType.Incomplete : PathType.Normal; Log.outDebug(LogFilter.Maps, "BuildPolyPath . path type {0}\n", pathType); return; } // look for startPoly/endPoly in current path /// @todo we can merge it with getPathPolyByPosition() loop bool startPolyFound = false; bool endPolyFound = false; uint pathStartIndex = 0; uint pathEndIndex = 0; if (_polyLength != 0) { for (; pathStartIndex < _polyLength; ++pathStartIndex) { // here to carch few bugs if (_pathPolyRefs[pathStartIndex] == 0) { Log.outError(LogFilter.Maps, "Invalid poly ref in BuildPolyPath. _polyLength: {0}, pathStartIndex: {1}," + " startPos: {2}, endPos: {3}, mapid: {4}", _polyLength, pathStartIndex, startPos, endPos, _sourceUnit.GetMapId()); break; } if (_pathPolyRefs[pathStartIndex] == startPoly) { startPolyFound = true; break; } } for (pathEndIndex = _polyLength - 1; pathEndIndex > pathStartIndex; --pathEndIndex) { if (_pathPolyRefs[pathEndIndex] == endPoly) { endPolyFound = true; break; } } } if (startPolyFound && endPolyFound) { Log.outDebug(LogFilter.Maps, "BuildPolyPath : (startPolyFound && endPolyFound)\n"); // we moved along the path and the target did not move out of our old poly-path // our path is a simple subpath case, we have all the data we need // just "cut" it out _polyLength = pathEndIndex - pathStartIndex + 1; Array.Copy(_pathPolyRefs, pathStartIndex, _pathPolyRefs, 0, _polyLength); } else if (startPolyFound && !endPolyFound) { Log.outDebug(LogFilter.Maps, "BuildPolyPath : (startPolyFound && !endPolyFound)\n"); // we are moving on the old path but target moved out // so we have atleast part of poly-path ready _polyLength -= pathStartIndex; // try to adjust the suffix of the path instead of recalculating entire length // at given interval the target cannot get too far from its last location // thus we have less poly to cover // sub-path of optimal path is optimal // take ~80% of the original length /// @todo play with the values here uint prefixPolyLength = (uint)(_polyLength * 0.8f + 0.5f); Array.Copy(_pathPolyRefs, pathStartIndex, _pathPolyRefs, 0, prefixPolyLength); ulong suffixStartPoly = _pathPolyRefs[prefixPolyLength - 1]; // we need any point on our suffix start poly to generate poly-path, so we need last poly in prefix data float[] suffixEndPoint = new float[3]; bool posOverPoly = false; if (Detour.dtStatusFailed(_navMeshQuery.closestPointOnPoly(suffixStartPoly, endPoint, suffixEndPoint, ref posOverPoly))) { // we can hit offmesh connection as last poly - closestPointOnPoly() don't like that // try to recover by using prev polyref --prefixPolyLength; suffixStartPoly = _pathPolyRefs[prefixPolyLength - 1]; if (Detour.dtStatusFailed(_navMeshQuery.closestPointOnPoly(suffixStartPoly, endPoint, suffixEndPoint, ref posOverPoly))) { // suffixStartPoly is still invalid, error state BuildShortcut(); pathType = PathType.NoPath; return; } } // generate suffix uint suffixPolyLength = 0; uint dtResult; if (_straightLine) { float hit = 0; float[] hitNormal = new float[3]; dtResult = _navMeshQuery.raycast( suffixStartPoly, suffixEndPoint, endPoint, _filter, ref hit, hitNormal, _pathPolyRefs, ref suffixPolyLength, 74 - (int)prefixPolyLength); // raycast() sets hit to FLT_MAX if there is a ray between start and end if (hit != float.MaxValue) { // the ray hit something, return no path instead of the incomplete one pathType = PathType.NoPath; return; } } else { dtResult = _navMeshQuery.findPath( suffixStartPoly, // start polygon endPoly, // end polygon suffixEndPoint, // start position endPoint, // end position _filter, // polygon search filter _pathPolyRefs, ref suffixPolyLength, 74 - (int)prefixPolyLength); } if (suffixPolyLength == 0 || Detour.dtStatusFailed(dtResult)) { // this is probably an error state, but we'll leave it // and hopefully recover on the next Update // we still need to copy our preffix Log.outError(LogFilter.Maps, "{0}'s Path Build failed: 0 length path", _sourceUnit.GetGUID().ToString()); } Log.outDebug(LogFilter.Maps, "m_polyLength={0} prefixPolyLength={1} suffixPolyLength={2} \n", _polyLength, prefixPolyLength, suffixPolyLength); // new path = prefix + suffix - overlap _polyLength = prefixPolyLength + suffixPolyLength - 1; } else { Log.outDebug(LogFilter.Maps, "++ BuildPolyPath . (!startPolyFound && !endPolyFound)\n"); // either we have no path at all . first run // or something went really wrong . we aren't moving along the path to the target // just generate new path // free and invalidate old path data Clear(); uint dtResult; if (_straightLine) { float hit = 0; float[] hitNormal = new float[3]; dtResult = _navMeshQuery.raycast( startPoly, startPoint, endPoint, _filter, ref hit, hitNormal, _pathPolyRefs, ref _polyLength, 74); // raycast() sets hit to FLT_MAX if there is a ray between start and end if (hit != float.MaxValue) { // the ray hit something, return no path instead of the incomplete one pathType = PathType.NoPath; return; } } else { dtResult = _navMeshQuery.findPath( startPoly, // start polygon endPoly, // end polygon startPoint, // start position endPoint, // end position _filter, // polygon search filter _pathPolyRefs, // [out] path ref _polyLength, 74); // max number of polygons in output path } if (_polyLength == 0 || Detour.dtStatusFailed(dtResult)) { // only happens if we passed bad data to findPath(), or navmesh is messed up Log.outError(LogFilter.Maps, "{0}'s Path Build failed: 0 length path", _sourceUnit.GetGUID().ToString()); BuildShortcut(); pathType = PathType.NoPath; return; } } // by now we know what type of path we can get if (_pathPolyRefs[_polyLength - 1] == endPoly && !pathType.HasAnyFlag(PathType.Incomplete)) { pathType = PathType.Normal; } else { pathType = PathType.Incomplete; } // generate the point-path out of our up-to-date poly-path BuildPointPath(startPoint, endPoint); }
public static SmoothPath ComputeSmoothPath(Detour.dtNavMeshQuery navQuery, float[] startWorldPos, float[] endWorldPos, float distance = 10) { SmoothPath smoothPath = new SmoothPath(); if (navQuery == null) { return(smoothPath); } float[] extents = new float[3]; for (int i = 0; i < 3; ++i) { extents[i] = distance; } dtPolyRef startRef = 0; dtPolyRef endRef = 0; float[] startPt = new float[3]; float[] endPt = new float[3]; Detour.dtQueryFilter filter = new Detour.dtQueryFilter(); navQuery.findNearestPoly(startWorldPos, extents, filter, ref startRef, ref startPt); navQuery.findNearestPoly(endWorldPos, extents, filter, ref endRef, ref endPt); const int maxPath = SmoothPath.MAX_POLYS; dtPolyRef[] path = new dtPolyRef[maxPath]; int pathCount = -1; navQuery.findPath(startRef, endRef, startPt, endPt, filter, path, ref pathCount, maxPath); smoothPath.m_nsmoothPath = 0; if (pathCount > 0) { // Iterate over the path to find smooth path on the detail mesh surface. dtPolyRef[] polys = new dtPolyRef[SmoothPath.MAX_POLYS]; for (int i = 0; i < pathCount; ++i) { polys[i] = path[i]; } int npolys = pathCount; float[] iterPos = new float[3]; float[] targetPos = new float[3]; bool posOverPoly_dummy = false; navQuery.closestPointOnPoly(startRef, startPt, iterPos, ref posOverPoly_dummy); navQuery.closestPointOnPoly(polys[npolys - 1], endPt, targetPos, ref posOverPoly_dummy); const float STEP_SIZE = 0.5f; const float SLOP = 0.01f; smoothPath.m_nsmoothPath = 0; Detour.dtVcopy(smoothPath.m_smoothPath, smoothPath.m_nsmoothPath * 3, iterPos, 0); smoothPath.m_nsmoothPath++; // Move towards target a small advancement at a time until target reached or // when ran out of memory to store the path. while (npolys != 0 && smoothPath.m_nsmoothPath < SmoothPath.MAX_SMOOTH) { // Find location to steer towards. float[] steerPos = new float[3]; byte steerPosFlag = 0; dtPolyRef steerPosRef = 0; if (!getSteerTarget(navQuery, iterPos, targetPos, SLOP, polys, npolys, steerPos, ref steerPosFlag, ref steerPosRef)) { break; } bool endOfPath = (steerPosFlag & (byte)Detour.dtStraightPathFlags.DT_STRAIGHTPATH_END) != 0 ? true : false; bool offMeshConnection = (steerPosFlag & (byte)Detour.dtStraightPathFlags.DT_STRAIGHTPATH_OFFMESH_CONNECTION) != 0 ? true : false; // Find movement delta. float[] delta = new float[3]; //, len; float len = .0f; Detour.dtVsub(delta, steerPos, iterPos); len = (float)Mathf.Sqrt(Detour.dtVdot(delta, delta)); // If the steer target is end of path or off-mesh link, do not move past the location. if ((endOfPath || offMeshConnection) && len < STEP_SIZE) { len = 1; } else { len = STEP_SIZE / len; } float[] moveTgt = new float[3]; Detour.dtVmad(moveTgt, iterPos, delta, len); // Move float[] result = new float[3]; dtPolyRef[] visited = new dtPolyRef[16]; int nvisited = 0; navQuery.moveAlongSurface(polys[0], iterPos, moveTgt, filter, result, visited, ref nvisited, 16); npolys = fixupCorridor(polys, npolys, SmoothPath.MAX_POLYS, visited, nvisited); npolys = fixupShortcuts(polys, npolys, navQuery); float h = 0; dtStatus getHeightStatus = navQuery.getPolyHeight(polys[0], result, ref h); result[1] = h; if ((getHeightStatus & Detour.DT_FAILURE) != 0) { Debug.LogError("Failed to getPolyHeight " + polys[0] + " pos " + result[0] + " " + result[1] + " " + result[2] + " h " + h); } Detour.dtVcopy(iterPos, result); // Handle end of path and off-mesh links when close enough. if (endOfPath && inRange(iterPos, 0, steerPos, 0, SLOP, 1.0f)) { // Reached end of path. Detour.dtVcopy(iterPos, targetPos); if (smoothPath.m_nsmoothPath < SmoothPath.MAX_SMOOTH) { Detour.dtVcopy(smoothPath.m_smoothPath, smoothPath.m_nsmoothPath * 3, iterPos, 0); smoothPath.m_nsmoothPath++; } break; } else if (offMeshConnection && inRange(iterPos, 0, steerPos, 0, SLOP, 1.0f)) { // Reached off-mesh connection. float[] startPos = new float[3]; //, endPos[3]; float[] endPos = new float[3]; // Advance the path up to and over the off-mesh connection. dtPolyRef prevRef = 0, polyRef = polys[0]; int npos = 0; while (npos < npolys && polyRef != steerPosRef) { prevRef = polyRef; polyRef = polys[npos]; npos++; } for (int i = npos; i < npolys; ++i) { polys[i - npos] = polys[i]; } npolys -= npos; // Handle the connection. dtStatus status = navQuery.getAttachedNavMesh().getOffMeshConnectionPolyEndPoints(prevRef, polyRef, startPos, endPos); if (Detour.dtStatusSucceed(status)) { if (smoothPath.m_nsmoothPath < SmoothPath.MAX_SMOOTH) { Detour.dtVcopy(smoothPath.m_smoothPath, smoothPath.m_nsmoothPath * 3, startPos, 0); smoothPath.m_nsmoothPath++; // Hack to make the dotted path not visible during off-mesh connection. if ((smoothPath.m_nsmoothPath & 1) != 0) { Detour.dtVcopy(smoothPath.m_smoothPath, smoothPath.m_nsmoothPath * 3, startPos, 0); smoothPath.m_nsmoothPath++; } } // Move position at the other side of the off-mesh link. Detour.dtVcopy(iterPos, endPos); float eh = 0.0f; navQuery.getPolyHeight(polys[0], iterPos, ref eh); iterPos[1] = eh; } } // Store results. if (smoothPath.m_nsmoothPath < SmoothPath.MAX_SMOOTH) { Detour.dtVcopy(smoothPath.m_smoothPath, smoothPath.m_nsmoothPath * 3, iterPos, 0); smoothPath.m_nsmoothPath++; } } } return(smoothPath); }
public ZwCreateFile(IntPtr addr) { zwcfDetour = new Detour<dZwCreateFile>(addr, HookedZwCreateFile); zwcfDetour.Attach(); }
/// <summary> /// Builds the initial query, normally called by awake /// Can be callen manually with a different nav mesh. /// </summary> /// <param name="navMesh"></param> public void InitializeQuery(Detour.NavMesh navMesh) { _navMeshQuery = new NavMeshQuery(); _navMeshQuery.Init(navMesh, 2048); filter = new QueryFilter(); // These values need to me modifiable in the editor later using RecastArea filter.IncludeFlags = 15; filter.ExcludeFlags = 0; filter.SetAreaCost(1, 1.0f); filter.SetAreaCost(2, 10.0f); filter.SetAreaCost(3, 1.0f); filter.SetAreaCost(4, 1.0f); filter.SetAreaCost(5, 2); filter.SetAreaCost(6, 1.5f); }
/// <summary> /// Builds a single polygon from the nav mesh /// </summary> /// <param name="navmesh">the entire navmesh which contains all polygon data</param> /// <param name="refId">id of the polygon that is to be drawn</param> /// <param name="color">Color to make the polygon</param> /// <param name="verts">List of Verts to add to</param> /// <param name="colors">List of colors for specific polygons</param> /// <param name="uvs">List of UVs for the polygons</param> /// <param name="tris">List of Triangles for the polygons</param> private void BuildNavMeshPoly(Detour.NavMesh navmesh, long refId, Color color, List<Vector3> verts, List<Color> colors, List<Vector2> uvs, List<int> tris) { MeshTile tile = null; Poly poly = null; if ((navmesh.GetTileAndPolyByRef(refId, ref tile, ref poly) & Status.Failure) != 0) return; long ip = 0; for (int i = 0; i < tile.Polys.Length; i++) { if (poly == tile.Polys[i]) ip = i; } if (poly.Type == Detour.AtavismNavTile.PolyTypeOffMeshConnection) { // do nothing for now } else { PolyDetail pd = tile.DetailMeshes[ip]; for (int i = 0; i < pd.TriCount; i++) { int t = ((int)pd.TriBase + i) * 4; for (int j = 0; j < 3; j++) { if (tile.DetailTris[t + j] < poly.VertCount) { verts.Add(new Vector3(tile.Verts[poly.Verts[tile.DetailTris[t + j]] * 3 + 0], tile.Verts[poly.Verts[tile.DetailTris[t + j]] * 3 + 1], tile.Verts[poly.Verts[tile.DetailTris[t + j]] * 3 + 2])); } else { verts.Add( new Vector3(tile.DetailVerts[(pd.VertBase + tile.DetailTris[t + j] - poly.VertCount) * 3 + 0], tile.DetailVerts[(pd.VertBase + tile.DetailTris[t + j] - poly.VertCount) * 3 + 1], tile.DetailVerts[(pd.VertBase + tile.DetailTris[t + j] - poly.VertCount) * 3 + 2])); } uvs.Add(new Vector2()); colors.Add(color); tris.Add(tris.Count); } } } }
public bool Initialize(LaunchStage stage) { if (stage == LaunchStage.PostBlue) { { var addr = Utility.FindPattern("python27", "55 8b ec 81 ec 04 01 00 00 53 ff 75 0c 8b 5d 08 e8 ? ? ? ? 59 8d 8d fc fe ff ff 51 50 ff ? 0c e8 ? ? ? ? 59 50 e8 ? ? ? ? 83 c4 ?"); if (addr == 0) { Core.Log(LogSeverity.Warning, "Can't find get_module_info function; pattern outdated? Zip Importer hook disabling."); return true; } _getModuleInfoOrig = Utility.Magic.RegisterDelegate<GetModuleInfoDel>(addr); _getModuleInfoFake = HandleGetModuleInfo; _getModuleInfoDetour = Utility.Magic.Detours.CreateAndApply(_getModuleInfoOrig, _getModuleInfoFake, "get_module_info"); } { var addr = Utility.FindPattern("python27", "55 8b ec 81 ec 10 01 00 00 56 ff 75 0c e8 ? ? ? ? 8b ? 08 59 8d ? ? ? ? ? 51 50 ff 76 ? e8 ? ? ? ? 59 50 e8 ? ? ? ? 83 c4 0c 85 c0 79 ? 33 c0"); if (addr == 0) { Core.Log(LogSeverity.Warning, "Can't find get_module_code function; pattern outdated? Zip Importer hook disabling."); return true; } _getModuleCodeOrig = Utility.Magic.RegisterDelegate<GetModuleCodeDel>(addr); _getModuleCodeFake = HandleGetModuleCode; _getModuleCodeDetour = Utility.Magic.Detours.CreateAndApply(_getModuleCodeOrig, _getModuleCodeFake, "get_module_code"); } Core.Log(LogSeverity.Minor, "initialized zip importer hooks"); } return true; }
public static SmoothPath ComputeSmoothPath(Detour.dtNavMeshQuery navQuery, float[] startWorldPos, float[] endWorldPos) { SmoothPath smoothPath = new SmoothPath(); if (navQuery == null){ return smoothPath; } float[] extents = new float[3]; for (int i=0;i<3;++i){ extents[i] = 10.0f; } dtPolyRef startRef = 0; dtPolyRef endRef = 0; float[] startPt = new float[3]; float[] endPt = new float[3]; Detour.dtQueryFilter filter = new Detour.dtQueryFilter(); navQuery.findNearestPoly(startWorldPos, extents, filter, ref startRef, ref startPt); navQuery.findNearestPoly(endWorldPos, extents, filter, ref endRef, ref endPt); const int maxPath = SmoothPath.MAX_POLYS; dtPolyRef[] path = new dtPolyRef[maxPath]; int pathCount = -1; navQuery.findPath(startRef, endRef, startPt, endPt, filter, path, ref pathCount, maxPath ); smoothPath.m_nsmoothPath = 0; if (pathCount > 0) { // Iterate over the path to find smooth path on the detail mesh surface. dtPolyRef[] polys = new dtPolyRef[SmoothPath.MAX_POLYS]; for (int i=0;i<pathCount;++i){ polys[i] = path[i]; } int npolys = pathCount; float[] iterPos = new float[3]; float[] targetPos = new float[3]; bool posOverPoly_dummy = false; navQuery.closestPointOnPoly(startRef, startPt, iterPos, ref posOverPoly_dummy); navQuery.closestPointOnPoly(polys[npolys-1], endPt, targetPos, ref posOverPoly_dummy); const float STEP_SIZE = 0.5f; const float SLOP = 0.01f; smoothPath.m_nsmoothPath = 0; Detour.dtVcopy(smoothPath.m_smoothPath,smoothPath.m_nsmoothPath*3, iterPos, 0); smoothPath.m_nsmoothPath++; // Move towards target a small advancement at a time until target reached or // when ran out of memory to store the path. while (npolys != 0 && smoothPath.m_nsmoothPath < SmoothPath.MAX_SMOOTH) { // Find location to steer towards. float[] steerPos = new float[3]; byte steerPosFlag = 0; dtPolyRef steerPosRef = 0; if (!getSteerTarget(navQuery, iterPos, targetPos, SLOP, polys, npolys, steerPos, ref steerPosFlag, ref steerPosRef)) break; bool endOfPath = (steerPosFlag & (byte)Detour.dtStraightPathFlags.DT_STRAIGHTPATH_END) != 0 ? true : false; bool offMeshConnection = (steerPosFlag & (byte)Detour.dtStraightPathFlags.DT_STRAIGHTPATH_OFFMESH_CONNECTION) != 0 ? true : false; // Find movement delta. float[] delta = new float[3];//, len; float len = .0f; Detour.dtVsub(delta, steerPos, iterPos); len = (float)Mathf.Sqrt(Detour.dtVdot(delta,delta)); // If the steer target is end of path or off-mesh link, do not move past the location. if ((endOfPath || offMeshConnection) && len < STEP_SIZE) len = 1; else len = STEP_SIZE / len; float[] moveTgt = new float[3]; Detour.dtVmad(moveTgt, iterPos, delta, len); // Move float[] result = new float[3]; dtPolyRef[] visited = new dtPolyRef[16]; int nvisited = 0; navQuery.moveAlongSurface(polys[0], iterPos, moveTgt, filter, result, visited, ref nvisited, 16); npolys = fixupCorridor(polys, npolys, SmoothPath.MAX_POLYS, visited, nvisited); npolys = fixupShortcuts(polys, npolys, navQuery); float h = 0; dtStatus getHeightStatus = navQuery.getPolyHeight(polys[0], result, ref h); result[1] = h; if ((getHeightStatus & Detour.DT_FAILURE) != 0) { Debug.LogError("Failed to getPolyHeight " + polys[0] + " pos " + result[0] + " " + result[1] + " " + result[2] + " h " + h); } Detour.dtVcopy(iterPos, result); // Handle end of path and off-mesh links when close enough. if (endOfPath && inRange(iterPos, 0, steerPos, 0, SLOP, 1.0f)) { // Reached end of path. Detour.dtVcopy(iterPos, targetPos); if (smoothPath.m_nsmoothPath < SmoothPath.MAX_SMOOTH) { Detour.dtVcopy(smoothPath.m_smoothPath,smoothPath.m_nsmoothPath*3, iterPos, 0); smoothPath.m_nsmoothPath++; } break; } else if (offMeshConnection && inRange(iterPos, 0, steerPos, 0, SLOP, 1.0f)) { // Reached off-mesh connection. float[] startPos = new float[3];//, endPos[3]; float[] endPos = new float[3]; // Advance the path up to and over the off-mesh connection. dtPolyRef prevRef = 0, polyRef = polys[0]; int npos = 0; while (npos < npolys && polyRef != steerPosRef) { prevRef = polyRef; polyRef = polys[npos]; npos++; } for (int i = npos; i < npolys; ++i) polys[i-npos] = polys[i]; npolys -= npos; // Handle the connection. dtStatus status = navQuery.getAttachedNavMesh().getOffMeshConnectionPolyEndPoints(prevRef, polyRef, startPos, endPos); if (Detour.dtStatusSucceed(status)) { if (smoothPath.m_nsmoothPath < SmoothPath.MAX_SMOOTH) { Detour.dtVcopy(smoothPath.m_smoothPath,smoothPath.m_nsmoothPath*3, startPos, 0); smoothPath.m_nsmoothPath++; // Hack to make the dotted path not visible during off-mesh connection. if ((smoothPath.m_nsmoothPath & 1) != 0) { Detour.dtVcopy(smoothPath.m_smoothPath, smoothPath.m_nsmoothPath * 3, startPos, 0); smoothPath.m_nsmoothPath++; } } // Move position at the other side of the off-mesh link. Detour.dtVcopy(iterPos, endPos); float eh = 0.0f; navQuery.getPolyHeight(polys[0], iterPos, ref eh); iterPos[1] = eh; } } // Store results. if (smoothPath.m_nsmoothPath < SmoothPath.MAX_SMOOTH) { Detour.dtVcopy(smoothPath.m_smoothPath, smoothPath.m_nsmoothPath * 3, iterPos, 0); smoothPath.m_nsmoothPath++; } } } return smoothPath; }
static bool getSteerTarget(Detour.dtNavMeshQuery navQuery, float[] startPos, float[] endPos, float minTargetDist, dtPolyRef[] path, int pathSize, float[] steerPos, ref byte steerPosFlag, ref dtPolyRef steerPosRef) { // Find steer target. const int MAX_STEER_POINTS = 3; float[] steerPath = new float[MAX_STEER_POINTS*3]; byte[] steerPathFlags = new byte[MAX_STEER_POINTS]; dtPolyRef[] steerPathPolys = new dtPolyRef[MAX_STEER_POINTS]; int nsteerPath = 0; navQuery.findStraightPath(startPos, endPos, path, pathSize, steerPath, steerPathFlags, steerPathPolys, ref nsteerPath, MAX_STEER_POINTS, 0); if (nsteerPath == 0) return false; // Find vertex far enough to steer to. int ns = 0; while (ns < nsteerPath) { // Stop at Off-Mesh link or when point is further than slop away. if ((steerPathFlags[ns] & (byte)Detour.dtStraightPathFlags.DT_STRAIGHTPATH_OFFMESH_CONNECTION) != 0 || !inRange(steerPath, ns*3, startPos, 0, minTargetDist, 1000.0f)) break; ns++; } // Failed to find good point to steer to. if (ns >= nsteerPath) return false; Detour.dtVcopy(steerPos, 0, steerPath,ns*3); steerPos[1] = startPos[1]; steerPosFlag = steerPathFlags[ns]; steerPosRef = steerPathPolys[ns]; return true; }
public static StraightPath ComputeStraightPath(Detour.dtNavMeshQuery navQuery, float[] startPos, float[] endPos) { //m_ComputedPathType = PathType.Straight; StraightPath path = new StraightPath(); float[] extents = new float[3]; for (int i=0;i<3;++i){ extents[i] = 10.0f; } dtPolyRef startRef = 0; dtPolyRef endRef = 0; float[] startPt = new float[3]; float[] endPt = new float[3]; Detour.dtQueryFilter filter = new Detour.dtQueryFilter(); navQuery.findNearestPoly( startPos, extents, filter, ref startRef, ref startPt ); navQuery.findNearestPoly( endPos, extents, filter, ref endRef, ref endPt ); int pathCount = -1; navQuery.findPath(startRef, endRef, startPt, endPt, filter, path.m_RawPathPolys, ref pathCount, StraightPath.MAX_POLYS); path.m_RawPathLength = pathCount; if (pathCount > 0) { // In case of partial path, make sure the end point is clamped to the last polygon. float[] epos = new float[3]; Detour.dtVcopy(epos, endPt); if (path.m_RawPathPolys[pathCount - 1] != endRef) { bool posOverPoly = false; navQuery.closestPointOnPoly(path.m_RawPathPolys[pathCount - 1], endPt, epos, ref posOverPoly); } navQuery.findStraightPath(startPt, endPt, path.m_RawPathPolys, pathCount, path.m_straightPath, path.m_straightPathFlags, path.m_straightPathPolys, ref path.m_straightPathCount, StraightPath.MAX_POLYS, path.m_straightPathOptions); } return path; }
public static void Initialize() { var eventVictim = Helper.Magic.RegisterDelegate<LuaFunctionDelegate>(Offsets.EventVictim); _eventDetour = Helper.Magic.Detours.CreateAndApply(eventVictim, new LuaFunctionDelegate(HandleVictimCall), "EventVictim"); }
private static uint IDirect3D9CreateDeviceHandler(IntPtr thisPtr, uint adapter, uint deviceType, IntPtr hFocusWindow, uint behaviorFlags, IntPtr pPresentationParameters, [Out] IntPtr ppReturnedDeviceInterface) { uint ret; if (!_isXnaCreateDeviceCall) { try { var nativePresentationParameters = (NativePresentationParameters)Marshal.PtrToStructure(pPresentationParameters, typeof(NativePresentationParameters)); var presentationParameters = nativePresentationParameters.ToXnaPresentationParameters(hFocusWindow); _preservedBehaviorFlags = behaviorFlags; _isXnaCreateDeviceCall = true; _xnaGraphicsDevice = new GraphicsDevice(GraphicsAdapter.DefaultAdapter, GraphicsProfile.Reach, presentationParameters); var pComPtrField = _xnaGraphicsDevice.GetType().GetField("pComPtr", BindingFlags.NonPublic | BindingFlags.Instance); if (pComPtrField == null) throw new Exception("Unable to get pComPtr field from XNA Graphics Device"); unsafe { var pComPtr = new IntPtr(Pointer.Unbox(pComPtrField.GetValue(_xnaGraphicsDevice))); Marshal.WriteIntPtr(ppReturnedDeviceInterface, pComPtr); _endSceneDetour = pComPtr.VTable(IDirect3DDevice9VTable.EndScene) .DetourWith(EndSceneFunc); _resetDetour = pComPtr.VTable(IDirect3DDevice9VTable.Reset) .DetourWith(ResetFunc); } // TODO OnCreateDevice(); ret = 0; } catch (Exception) { // If we get an exception trying to create the XNA device, just call the original method and pass out the return ret = (uint)_createDeviceDetour.CallOriginal( thisPtr, adapter, deviceType, hFocusWindow, behaviorFlags, pPresentationParameters, ppReturnedDeviceInterface); } } else { // Now we're inside the XNA Device's call to CreateDevice - get our cached presentation parameters and add a required flag // TODO: check this process / flag var pp = (NativePresentationParameters)Marshal.PtrToStructure(pPresentationParameters, typeof(NativePresentationParameters)); pp.Flags |= 0x1; Marshal.StructureToPtr(pp, pPresentationParameters, true); ret = (uint) _createDeviceDetour.CallOriginal( thisPtr, adapter, deviceType, hFocusWindow, _preservedBehaviorFlags, pPresentationParameters, ppReturnedDeviceInterface); } return ret; }
// This function checks if the path has a small U-turn, that is, // a polygon further in the path is adjacent to the first polygon // in the path. If that happens, a shortcut is taken. // This can happen if the target (T) location is at tile boundary, // and we're (S) approaching it parallel to the tile edge. // The choice at the vertex can be arbitrary, // +---+---+ // |:::|:::| // +-S-+-T-+ // |:::| | <-- the step can end up in here, resulting U-turn path. // +---+---+ static int fixupShortcuts(dtPolyRef[] path, int npath, Detour.dtNavMeshQuery navQuery) { if (npath < 3) return npath; // Get connected polygons const int maxNeis = 16; dtPolyRef[] neis = new dtPolyRef[maxNeis]; int nneis = 0; Detour.dtMeshTile tile = null; Detour.dtPoly poly = null; if (Detour.dtStatusFailed(navQuery.getAttachedNavMesh().getTileAndPolyByRef(path[0], ref tile, ref poly))) return npath; for (uint k = poly.firstLink; k != Detour.DT_NULL_LINK; k = tile.links[k].next) { Detour.dtLink link = tile.links[k]; if (link.polyRef != 0) { if (nneis < maxNeis) neis[nneis++] = link.polyRef; } } // If any of the neighbour polygons is within the next few polygons // in the path, short cut to that polygon directly. const int maxLookAhead = 6; int cut = 0; for (int i = Math.Min(maxLookAhead, npath) - 1; i > 1 && cut == 0; i--) { for (int j = 0; j < nneis; j++) { if (path[i] == neis[j]) { cut = i; break; } } } if (cut > 1) { int offset = cut-1; npath -= offset; for (int i = 1; i < npath; i++) path[i] = path[i+offset]; } return npath; }
void BuildPointPath(float[] startPoint, float[] endPoint) { float[] pathPoints = new float[74 * 3]; int pointCount = 0; uint dtResult = Detour.DT_FAILURE; if (_straightLine) { dtResult = Detour.DT_SUCCESS; pointCount = 1; Array.Copy(startPoint, pathPoints, 3); // first point // path has to be split into polygons with dist SMOOTH_PATH_STEP_SIZE between them Vector3 startVec = new Vector3(startPoint[0], startPoint[1], startPoint[2]); Vector3 endVec = new Vector3(endPoint[0], endPoint[1], endPoint[2]); Vector3 diffVec = (endVec - startVec); Vector3 prevVec = startVec; float len = diffVec.GetLength(); diffVec *= 4.0f / len; while (len > 4.0f) { len -= 4.0f; prevVec += diffVec; pathPoints[3 * pointCount + 0] = prevVec.X; pathPoints[3 * pointCount + 1] = prevVec.Y; pathPoints[3 * pointCount + 2] = prevVec.Z; ++pointCount; } Array.Copy(endPoint, 0, pathPoints, 3 * pointCount, 3); // last point ++pointCount; } else if (_useStraightPath) { dtResult = _navMeshQuery.findStraightPath( startPoint, // start position endPoint, // end position _pathPolyRefs, (int)_polyLength, pathPoints, // [out] path corner points null, // [out] flags null, // [out] shortened path ref pointCount, (int)_pointPathLimit, 0); // maximum number of points/polygons to use } else { dtResult = FindSmoothPath( startPoint, // start position endPoint, // end position _pathPolyRefs, // current path _polyLength, // length of current path out pathPoints, // [out] path corner points out pointCount, _pointPathLimit); // maximum number of points } if (pointCount < 2 || Detour.dtStatusFailed(dtResult)) { // only happens if pass bad data to findStraightPath or navmesh is broken // single point paths can be generated here /// @todo check the exact cases Log.outDebug(LogFilter.Maps, "++ PathGenerator.BuildPointPath FAILED! path sized {0} returned\n", pointCount); BuildShortcut(); pathType = PathType.NoPath; return; } else if (pointCount == _pointPathLimit) { Log.outDebug(LogFilter.Maps, "++ PathGenerator.BuildPointPath FAILED! path sized {0} returned, lower than limit set to {1}\n", pointCount, _pointPathLimit); BuildShortcut(); pathType = PathType.Short; return; } _pathPoints = new Vector3[pointCount]; for (uint i = 0; i < pointCount; ++i) { _pathPoints[i] = new Vector3(pathPoints[i * 3 + 2], pathPoints[i * 3], pathPoints[i * 3 + 1]); } NormalizePath(); // first point is always our current location - we need the next one SetActualEndPosition(_pathPoints[pointCount - 1]); // force the given destination, if needed if (_forceDestination && (!pathType.HasAnyFlag(PathType.Normal) || !InRange(GetEndPosition(), GetActualEndPosition(), 1.0f, 1.0f))) { // we may want to keep partial subpath if (Dist3DSqr(GetActualEndPosition(), GetEndPosition()) < 0.3f * Dist3DSqr(GetStartPosition(), GetEndPosition())) { SetActualEndPosition(GetEndPosition()); _pathPoints[_pathPoints.Length - 1] = GetEndPosition(); } else { SetActualEndPosition(GetEndPosition()); BuildShortcut(); } pathType = (PathType.Normal | PathType.NotUsingPath); } Log.outDebug(LogFilter.Maps, "PathGenerator.BuildPointPath path type {0} size {1} poly-size {2}\n", pathType, pointCount, _polyLength); }
uint FindSmoothPath(float[] startPos, float[] endPos, ulong[] polyPath, uint polyPathSize, out float[] smoothPath, out int smoothPathSize, uint maxSmoothPathSize) { smoothPathSize = 0; int nsmoothPath = 0; smoothPath = new float[74 * 3]; ulong[] polys = new ulong[74]; Array.Copy(polyPath, polys, polyPathSize); uint npolys = polyPathSize; float[] iterPos = new float[3]; float[] targetPos = new float[3]; if (Detour.dtStatusFailed(_navMeshQuery.closestPointOnPolyBoundary(polys[0], startPos, iterPos))) { return(Detour.DT_FAILURE); } if (Detour.dtStatusFailed(_navMeshQuery.closestPointOnPolyBoundary(polys[npolys - 1], endPos, targetPos))) { return(Detour.DT_FAILURE); } Detour.dtVcopy(smoothPath, nsmoothPath * 3, iterPos, 0); nsmoothPath++; // Move towards target a small advancement at a time until target reached or // when ran out of memory to store the path. while (npolys != 0 && nsmoothPath < maxSmoothPathSize) { // Find location to steer towards. float[] steerPos; Detour.dtStraightPathFlags steerPosFlag; ulong steerPosRef = 0; if (!GetSteerTarget(iterPos, targetPos, 0.3f, polys, npolys, out steerPos, out steerPosFlag, out steerPosRef)) { break; } bool endOfPath = steerPosFlag.HasAnyFlag(Detour.dtStraightPathFlags.DT_STRAIGHTPATH_END); bool offMeshConnection = steerPosFlag.HasAnyFlag(Detour.dtStraightPathFlags.DT_STRAIGHTPATH_OFFMESH_CONNECTION); // Find movement delta. float[] delta = new float[3]; Detour.dtVsub(delta, steerPos, iterPos); float len = (float)Math.Sqrt(Detour.dtVdot(delta, delta)); // If the steer target is end of path or off-mesh link, do not move past the location. if ((endOfPath || offMeshConnection) && len < 4.0f) { len = 1.0f; } else { len = 4.0f / len; } float[] moveTgt = new float[3]; Detour.dtVmad(moveTgt, iterPos, delta, len); // Move float[] result = new float[3]; int MAX_VISIT_POLY = 16; ulong[] visited = new ulong[MAX_VISIT_POLY]; int nvisited = 0; _navMeshQuery.moveAlongSurface(polys[0], iterPos, moveTgt, _filter, result, visited, ref nvisited, MAX_VISIT_POLY); npolys = FixupCorridor(polys, npolys, 74, visited, nvisited); _navMeshQuery.getPolyHeight(polys[0], result, ref result[1]); result[1] += 0.5f; Detour.dtVcopy(iterPos, result); // Handle end of path and off-mesh links when close enough. if (endOfPath && InRangeYZX(iterPos, steerPos, 0.3f, 1.0f)) { // Reached end of path. Detour.dtVcopy(iterPos, targetPos); if (nsmoothPath < maxSmoothPathSize) { Detour.dtVcopy(smoothPath, nsmoothPath * 3, iterPos, 0); nsmoothPath++; } break; } else if (offMeshConnection && InRangeYZX(iterPos, steerPos, 0.3f, 1.0f)) { // Advance the path up to and over the off-mesh connection. ulong prevRef = 0; ulong polyRef = polys[0]; uint npos = 0; while (npos < npolys && polyRef != steerPosRef) { prevRef = polyRef; polyRef = polys[npos]; npos++; } for (uint i = npos; i < npolys; ++i) { polys[i - npos] = polys[i]; } npolys -= npos; // Handle the connection. float[] connectionStartPos = new float[3]; float[] connectionEndPos = new float[3]; if (Detour.dtStatusSucceed(_navMesh.getOffMeshConnectionPolyEndPoints(prevRef, polyRef, connectionStartPos, connectionEndPos))) { if (nsmoothPath < maxSmoothPathSize) { Detour.dtVcopy(smoothPath, nsmoothPath * 3, connectionStartPos, 0); nsmoothPath++; } // Move position at the other side of the off-mesh link. Detour.dtVcopy(iterPos, connectionEndPos); _navMeshQuery.getPolyHeight(polys[0], iterPos, ref iterPos[1]); iterPos[1] += 0.5f; } } // Store results. if (nsmoothPath < maxSmoothPathSize) { Detour.dtVcopy(smoothPath, nsmoothPath * 3, iterPos, 0); nsmoothPath++; } } smoothPathSize = nsmoothPath; // this is most likely a loop return(nsmoothPath < 74 ? Detour.DT_SUCCESS : Detour.DT_FAILURE); }
public override void Initialize() { // Create a new 'window' var window = new Form(); // Grabbed from d3d9.h const uint D3D_SDK_VERSION = 32; // Create the IDirect3D* object. IntPtr direct3D = Direct3DCreate9(D3D_SDK_VERSION); // Make sure it's valid. (Should always be valid....) if (direct3D == IntPtr.Zero) throw new Exception("Failed to create D3D."); // Setup some present params... var d3dpp = new D3DPRESENT_PARAMETERS { Windowed = true, SwapEffect = 1, BackBufferFormat = 0 }; IntPtr device; // CreateDevice is a vfunc of IDirect3D. Hence; why this entire thing only works in process! (Unless you // know of some way to hook funcs from out of process...) // It's the 16th vfunc btw. // Check d3d9.h var createDevice = Pulse.Magic.RegisterDelegate<IDirect3D9_CreateDevice>(Pulse.Magic.GetObjectVtableFunction(direct3D, 16)); // Pass it some vals. You can check d3d9.h for what these actually are.... if (createDevice(direct3D, 0, 1, window.Handle, 0x20, ref d3dpp, out device) < 0) throw new Exception("Failed to create device."); EndScenePointer = Pulse.Magic.GetObjectVtableFunction(device, VMT_ENDSCENE); ResetPointer = Pulse.Magic.GetObjectVtableFunction(device, VMT_RESET); // We now have a valid pointer to the device. We can release the shit we don't need now. :) // Again, the Release() funcs are virtual. Part of the IUnknown interface for COM. // They're the 3rd vfunc. (2nd index) var deviceRelease = Pulse.Magic.RegisterDelegate<D3DVirtVoid>(Pulse.Magic.GetObjectVtableFunction(device, 2)); var d3dRelease = Pulse.Magic.RegisterDelegate<D3DVirtVoid>(Pulse.Magic.GetObjectVtableFunction(direct3D, 2)); // And finally, release the device and d3d object. deviceRelease(device); d3dRelease(direct3D); // Destroy the window... window.Dispose(); // Hook endscene _endSceneDelegate = Pulse.Magic.RegisterDelegate<Direct3D9EndScene>(EndScenePointer); _endSceneHook = Pulse.Magic.Detours.CreateAndApply(_endSceneDelegate, new Direct3D9EndScene(Callback), "D9EndScene"); }
private static IntPtr Direct3DCreate9Handler(uint sdkVersion) { var pDirect3D9 = (IntPtr) _d3DCreateDetour.CallOriginal(sdkVersion); if (_iDirect3D9 == IntPtr.Zero) { // store the pointer and detour the CreateDevice function _iDirect3D9 = pDirect3D9; _createDeviceDetour = pDirect3D9.VTable(IDirect3D9VTable.CreateDevice) .DetourWith(IDirect3D9CreateDeviceFunc); } return pDirect3D9; }
public static SmoothPath ComputeSmoothPath(Detour.dtNavMeshQuery navQuery, Vector3 startPos, Vector3 endPos) { return ComputeSmoothPath(navQuery, Vector3ToArray(startPos), Vector3ToArray(endPos)); }
/// <summary> /// Hooks DirectX creation functions to intercept device creation to get the device pointer. /// Needs to be called on Process startup with process started suspended. /// </summary> public static void HookGraphicsDeviceCreation() { if (_isGraphicsCreationHooked) return; // Load d3d9.dll library to hook the necessary functions // NOTE: this is a potential resource leak as there is no matching FreeLibrary var hLib = LoadLibrary("d3d9.dll"); if (hLib == IntPtr.Zero) throw new Win32Exception(Marshal.GetLastWin32Error(), "Unable to load d3d9.dll"); var pDirect3DCreate9 = GetProcAddress(hLib, "Direct3DCreate9"); if (pDirect3DCreate9 == IntPtr.Zero) throw new Win32Exception(Marshal.GetLastWin32Error(), "Unable to find proc address for Direct3DCreate9"); _d3DCreateDetour = pDirect3DCreate9.DetourWith(Direct3DCreate9Func); _isGraphicsCreationHooked = true; }
public static float[] GetClosestPointOnNavMesh(Detour.dtNavMeshQuery navQuery, float[] pos) { float[] extents = new float[3]; for (int i = 0; i < 3; ++i) { extents[i] = 10.0f; } Detour.dtQueryFilter filter = new Detour.dtQueryFilter(); dtPolyRef startRef = 0; float[] res = new float[3]; navQuery.findNearestPoly(pos, extents, filter, ref startRef, ref res); return res; }