openDecal/Managed/Decal.Adapter/Decal.Adapter.Wrappers/HooksWrapper.cs
erik d1442e3747 Initial commit: Complete open-source Decal rebuild
All 5 phases of the open-source Decal rebuild:

Phase 1: 14 decompiled .NET projects (Interop.*, Adapter, FileService, DecalUtil)
Phase 2: 10 native DLLs rewritten as C# COM servers with matching GUIDs
  - DecalDat, DHS, SpellFilter, DecalInput, DecalNet, DecalFilters
  - Decal.Core, DecalControls, DecalRender, D3DService
Phase 3: C++ shims for Inject.DLL (D3D9 hooking) and LauncherHook.DLL
Phase 4: DenAgent WinForms tray application
Phase 5: WiX installer and build script

25 C# projects building with 0 errors.
Native C++ projects require VS 2022 + Windows SDK (x86).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 18:27:56 +01:00

540 lines
12 KiB
C#

using System;
using System.ComponentModel;
using System.Drawing;
using System.Reflection;
using System.Runtime.InteropServices;
using Decal.Interop.Core;
namespace Decal.Adapter.Wrappers;
[CLSCompliant(true)]
public sealed class HooksWrapper : MarshalByRefObject, IIndexedValueProvider, IDisposable
{
private IACHooks myHooks;
private bool isDisposed;
[CLSCompliant(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public IACHooks Underlying => myHooks;
public int BusyState => myHooks.BusyState;
public int BusyStateId => myHooks.BusyStateID;
public bool ChatState => myHooks.ChatState;
public CombatState CombatMode => (CombatState)myHooks.CombatMode;
public int CommandInterpreter => myHooks.CommandInterpreter;
public int CurrentSelection
{
get
{
return myHooks.CurrentSelection;
}
set
{
myHooks.CurrentSelection = value;
}
}
public double Heading
{
get
{
return myHooks.HeadingDegrees;
}
set
{
FaceHeading(value, bUnknown: true);
}
}
public double HeadingRadians
{
get
{
return myHooks.HeadingRadians;
}
set
{
RadianFaceHeading(value, bUnknown: true);
}
}
public int Landcell => myHooks.Landcell;
public double LocationX => myHooks.LocationX;
public double LocationY => myHooks.LocationY;
public double LocationZ => myHooks.LocationZ;
public int MaxSelectedStackCount => myHooks.MaxSelectedStackCount;
public int OpenedContainer => myHooks.OpenedContainer;
public int PointerState => myHooks.PointerState;
public int PreviousSelection
{
get
{
return myHooks.PreviousSelection;
}
set
{
myHooks.PreviousSelection = value;
}
}
public Rectangle Region3D
{
get
{
tagRECT aC3DRegionRect = myHooks.AC3DRegionRect;
return new Rectangle(aC3DRegionRect.left, aC3DRegionRect.top, aC3DRegionRect.right, aC3DRegionRect.bottom);
}
}
public Rectangle RegionWindow
{
get
{
tagRECT aCWindowRect = myHooks.ACWindowRect;
return new Rectangle(aCWindowRect.left, aCWindowRect.top, aCWindowRect.right, aCWindowRect.bottom);
}
}
public int SelectedStackCount
{
get
{
return myHooks.SelectedStackCount;
}
set
{
myHooks.SelectedStackCount = value;
}
}
public int VendorId => myHooks.VendorID;
[CLSCompliant(false)]
public HookIndexer<AttributeType> Attribute => new HookIndexer<AttributeType>(this, hookIndexType.Attribute);
[CLSCompliant(false)]
public HookIndexer<AttributeType> AttributeClicks => new HookIndexer<AttributeType>(this, hookIndexType.AttributeClicks);
[CLSCompliant(false)]
public HookIndexer<AttributeType> AttributeStart => new HookIndexer<AttributeType>(this, hookIndexType.AttributeStart);
[CLSCompliant(false)]
public HookIndexer<AttributeType> AttributeTotalXP => new HookIndexer<AttributeType>(this, hookIndexType.AttributeTotalXP);
[CLSCompliant(false)]
public HookIndexer<int> Misc => new HookIndexer<int>(this, hookIndexType.Misc);
[CLSCompliant(false)]
public HookIndexer<SkillType> Skill => new HookIndexer<SkillType>(this, hookIndexType.Skill);
[CLSCompliant(false)]
public HookIndexer<SkillType> SkillClicks => new HookIndexer<SkillType>(this, hookIndexType.SkillClicks);
[CLSCompliant(false)]
public HookIndexer<SkillType> SkillFreePoints => new HookIndexer<SkillType>(this, hookIndexType.SkillFreePoints);
[CLSCompliant(false)]
public HookIndexer<SkillType> SkillTotalXP => new HookIndexer<SkillType>(this, hookIndexType.SkillTotalXP);
[CLSCompliant(false)]
public HookIndexer<SkillType> SkillTrainLevel => new HookIndexer<SkillType>(this, hookIndexType.SkillTrainLevel);
[CLSCompliant(false)]
public HookIndexer<VitalType> Vital => new HookIndexer<VitalType>(this, hookIndexType.Vital);
[CLSCompliant(false)]
public HookIndexer<VitalType> VitalClicks => new HookIndexer<VitalType>(this, hookIndexType.VitalClicks);
[CLSCompliant(false)]
public HookIndexer<VitalType> VitalTotalXP => new HookIndexer<VitalType>(this, hookIndexType.VitalTotalXP);
internal HooksWrapper(ACHooks hooks)
{
myHooks = hooks;
}
~HooksWrapper()
{
Dispose(disposing: false);
}
public void Dispose()
{
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if (!isDisposed)
{
}
if (myHooks != null)
{
Marshal.ReleaseComObject(myHooks);
myHooks = null;
}
isDisposed = true;
}
public void AddChatText(string text, int color)
{
AddChatText(text, color, 0);
}
public void AddChatText(string text, int color, int target)
{
myHooks.AddChatText(text, color, target);
}
public void AddChatTextRaw(string text, int color)
{
AddChatTextRaw(text, color, 0);
}
public void AddChatTextRaw(string text, int color, int target)
{
myHooks.AddChatTextRaw(text, color, target);
}
public void AddStatusText(string text)
{
myHooks.AddStatusText(text);
}
public void ApplyItem(int useThis, int onThis)
{
myHooks.ApplyItem(useThis, onThis);
}
public void AutoWield(int item)
{
myHooks.AutoWield(item);
}
public void AutoWield(int item, int slot, int explic, int notexplic)
{
myHooks.AutoWieldEx(item, slot, explic, notexplic);
}
public void AutoWield(int item, int slot, int explic, int notexplic, int zero1, int zero2)
{
myHooks.AutoWieldRaw(item, slot, explic, notexplic, zero1, zero2);
}
public void CastSpell(int spellId, int objectId)
{
myHooks.CastSpell(spellId, objectId);
}
public void DropItem(int objectId)
{
myHooks.DropItem(objectId);
}
public bool FaceHeading(double heading, bool bUnknown)
{
return myHooks.FaceHeading((float)heading, bUnknown);
}
public bool RadianFaceHeading(double heading, bool bUnknown)
{
if (heading < 0.0)
{
throw new ArgumentOutOfRangeException("heading");
}
if (heading > Math.PI * 10.0)
{
throw new ArgumentOutOfRangeException("heading");
}
double num = heading * 180.0 / Math.PI;
return myHooks.FaceHeading((float)num, bUnknown);
}
public void FellowshipRecruit(int lObjectID)
{
myHooks.FellowshipRecruit(lObjectID);
}
public void FellowshipGrantLeader(int lObjectID)
{
myHooks.FellowshipGrantLeader(lObjectID);
}
public void FellowshipSetOpen(bool IsOpen)
{
myHooks.FellowshipSetOpen(IsOpen);
}
public void FellowshipQuit()
{
myHooks.FellowshipQuit();
}
public void FellowshipDisband()
{
myHooks.FellowshipDisband();
}
public void FellowshipDismiss(int lObjectID)
{
myHooks.FellowshipDismiss(lObjectID);
}
public void GiveItem(int lObject, int lDestination)
{
myHooks.GiveItem(lObject, lDestination);
}
public void RequestId(int objectId)
{
CoreManager.Current.IDQueue.AddToQueueForCaller(objectId, Assembly.GetCallingAssembly(), DateTime.MaxValue);
}
public void InvokeChatParser(string text)
{
myHooks.InvokeChatParser(text);
}
public bool IsValidObject(int objectId)
{
return myHooks.IsValidObject(objectId);
}
public void Logout()
{
myHooks.Logout();
}
public void MoveItem(int objectId, int packId, int slot, bool stack)
{
myHooks.MoveItem(objectId, packId, slot, stack);
}
public void MoveItem(int objectId, int destinationId)
{
myHooks.MoveItemEx(objectId, destinationId);
}
public void MoveItem(int objectId, int destinationId, int moveFlags)
{
myHooks.MoveItemExRaw(objectId, destinationId, moveFlags);
}
public void SalvagePanelAdd(int objectId)
{
myHooks.SalvagePanelAdd(objectId);
}
public void SalvagePanelSalvage()
{
myHooks.SalvagePanelSalvage();
}
public void SelectItem(int objectId)
{
myHooks.SelectItem(objectId);
}
public void SetAutorun(bool on)
{
myHooks.SetAutorun(on);
}
public void SetCombatMode(CombatState newMode)
{
myHooks.SetCombatMode((int)newMode);
}
public void SetCursorPosition(int x, int y)
{
myHooks.SetCursorPosition(x, y);
}
public void SetIdleTime(double timeout)
{
myHooks.SetIdleTime(timeout);
}
public void SpellTabAdd(int tab, int index, int spellId)
{
myHooks.SpellTabAdd(tab, index, spellId);
}
public void SpellTabDelete(int tab, int spellId)
{
myHooks.SpellTabDelete(tab, spellId);
}
public void TradeAccept()
{
myHooks.TradeAccept();
}
public void TradeAdd(int objectId)
{
myHooks.TradeAdd(objectId);
}
public IntPtr PhysicsObject(int objectId)
{
return new IntPtr(myHooks.GetPhysicsObjectPtr(objectId));
}
public IntPtr WeenieObject(int objectId)
{
return new IntPtr(myHooks.GetWeenieObjectPtr(objectId));
}
public void TradeDecline()
{
myHooks.TradeDecline();
}
public void TradeReset()
{
myHooks.TradeReset();
}
public void TradeEnd()
{
myHooks.TradeEnd();
}
public IntPtr UIElementLookup(UIElementType pUIElementType)
{
return new IntPtr(myHooks.UIElementLookup((int)pUIElementType));
}
public void UIElementMove(UIElementType pUIElementType, int x, int y)
{
myHooks.UIElementMove((int)pUIElementType, x, y);
}
public void UIElementResize(UIElementType pUIElementType, int width, int height)
{
myHooks.UIElementResize((int)pUIElementType, width, height);
}
public Rectangle UIElementRegion(UIElementType pUIElementType)
{
tagRECT tagRECT = myHooks.UIElementRegionRect((int)pUIElementType);
return new Rectangle(tagRECT.left, tagRECT.top, 1 + tagRECT.right - tagRECT.left, 1 + tagRECT.bottom - tagRECT.top);
}
public void UseItem(int objectId, int useState)
{
myHooks.UseItem(objectId, useState);
}
public void UseItem(int objectId, int useState, int useMethod)
{
myHooks.UseItemRaw(objectId, useState, useMethod);
}
public void VendorBuyAll()
{
myHooks.VendorBuyAll();
}
public void VendorAddBuyList(int templateId, int count)
{
myHooks.VendorBuyListAdd(templateId, count);
}
public void VendorClearBuyList()
{
myHooks.VendorBuyListClear();
}
public void VendorSellAll()
{
myHooks.VendorSellAll();
}
public void VendorAddSellList(int itemId)
{
myHooks.VendorSellListAdd(itemId);
}
public void VendorClearSellList()
{
myHooks.VendorSellListClear();
}
public void AddSkillExperience(SkillType skill, int experience)
{
myHooks.AddSkillExp((eSkill)skill, experience);
}
public void AddAttributeExperience(AttributeType attrib, int experience)
{
myHooks.AddAttributeExp((eAttribute)attrib, experience);
}
public void AddVitalExperience(VitalType vital, int experience)
{
myHooks.AddVitalExp((eVital)vital, experience);
}
int IIndexedValueProvider.GetIndexedObject(hookIndexType index, int item)
{
int result = 0;
switch (index)
{
case hookIndexType.Attribute:
result = ((dynamic)myHooks).get_Attribute(item);
break;
case hookIndexType.AttributeClicks:
result = ((dynamic)myHooks).get_AttributeClicks((eAttribute)item);
break;
case hookIndexType.AttributeStart:
result = ((dynamic)myHooks).get_AttributeStart((eAttribute)item);
break;
case hookIndexType.AttributeTotalXP:
result = ((dynamic)myHooks).get_AttributeTotalXP((eAttribute)item);
break;
case hookIndexType.Skill:
result = ((dynamic)myHooks).get_Skill(item);
break;
case hookIndexType.SkillClicks:
result = ((dynamic)myHooks).get_SkillClicks((eSkill)item);
break;
case hookIndexType.SkillFreePoints:
result = ((dynamic)myHooks).get_SkillFreePoints((eSkill)item);
break;
case hookIndexType.SkillTotalXP:
result = ((dynamic)myHooks).get_SkillTotalXP((eSkill)item);
break;
case hookIndexType.SkillTrainLevel:
result = (int)((dynamic)myHooks).get_SkillTrainLevel((eSkill)item);
break;
case hookIndexType.Vital:
result = ((dynamic)myHooks).get_Vital(item);
break;
case hookIndexType.VitalClicks:
result = ((dynamic)myHooks).get_VitalClicks((eVital)item);
break;
case hookIndexType.VitalTotalXP:
result = ((dynamic)myHooks).get_VitalTotalXP((eVital)item);
break;
case hookIndexType.Misc:
result = ((dynamic)myHooks).get_Misc(item);
break;
}
return result;
}
}