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>
This commit is contained in:
commit
d1442e3747
1382 changed files with 170725 additions and 0 deletions
281
Managed/Decal.Core/ACHooksImpl.cs
Normal file
281
Managed/Decal.Core/ACHooksImpl.cs
Normal file
|
|
@ -0,0 +1,281 @@
|
|||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using Decal.Interop.Core;
|
||||
|
||||
namespace Decal.Core
|
||||
{
|
||||
[ComVisible(true)]
|
||||
[Guid("CB8875CD-ABC2-42AD-8175-8908706EED37")]
|
||||
[ClassInterface(ClassInterfaceType.None)]
|
||||
[ComSourceInterfaces("Decal.Interop.Core.IACHooksEvents\0\0")]
|
||||
[ProgId("Decal.ACHooks")]
|
||||
public class ACHooksImpl : IACHooks
|
||||
{
|
||||
// COM events
|
||||
public event IACHooksEvents_ObjectDestroyedEventHandler ObjectDestroyed;
|
||||
public event IACHooksEvents_ChatTextInterceptEventHandler ChatTextIntercept;
|
||||
public event IACHooksEvents_ChatParserInterceptEventHandler ChatParserIntercept;
|
||||
public event IACHooksEvents_StatusTextInterceptEventHandler StatusTextIntercept;
|
||||
public event IACHooksEvents_ObjectSelectedEventHandler ObjectSelected;
|
||||
public event IACHooksEvents_MessageProcessedEventHandler MessageProcessed;
|
||||
public event IACHooksEvents_AC3DRegionChangedEventHandler AC3DRegionChanged;
|
||||
public event IACHooksEvents_ContainerOpenedEventHandler ContainerOpened;
|
||||
public event IACHooksEvents_ChatClickInterceptEventHandler ChatClickIntercept;
|
||||
public event IACHooksEvents_RenderPreUIEventHandler RenderPreUI;
|
||||
|
||||
private DecalCoreImpl _decal;
|
||||
private IIdentifyFilter _idFilter;
|
||||
|
||||
// State
|
||||
private int _currentSelection;
|
||||
private int _previousSelection;
|
||||
private int _selectedStackCount;
|
||||
private int _maxSelectedStackCount;
|
||||
private int _combatMode;
|
||||
private int _vendorId;
|
||||
private int _busyState;
|
||||
private int _busyStateId;
|
||||
private int _pointerState;
|
||||
private int _commandInterpreter;
|
||||
private int _openedContainer;
|
||||
private bool _chatState;
|
||||
private double _headingDegrees;
|
||||
private double _headingRadians;
|
||||
private int _landcell;
|
||||
private double _locationX, _locationY, _locationZ;
|
||||
private tagRECT _ac3dRegionRect;
|
||||
private tagRECT _acWindowRect;
|
||||
|
||||
public void SetIDFilter(IIdentifyFilter pIDFilter) => _idFilter = pIDFilter;
|
||||
|
||||
public void SetDecal(object pDecal)
|
||||
{
|
||||
_decal = pDecal as DecalCoreImpl;
|
||||
}
|
||||
|
||||
// Hook availability
|
||||
public int HooksAvail =>
|
||||
(int)(eAvailableHooks.eCurrentSelect | eAvailableHooks.ePrevSelect |
|
||||
eAvailableHooks.eCastSpell | eAvailableHooks.eMoveItem |
|
||||
eAvailableHooks.eSelectItem | eAvailableHooks.eUseItem |
|
||||
eAvailableHooks.eCombatMode | eAvailableHooks.eChatState |
|
||||
eAvailableHooks.eStackCount | eAvailableHooks.eMaxStackCount |
|
||||
eAvailableHooks.eVendorID | eAvailableHooks.eBusyState |
|
||||
eAvailableHooks.eBusyStateID | eAvailableHooks.ePointerState |
|
||||
eAvailableHooks.eMoveItemEx | eAvailableHooks.ePosition |
|
||||
eAvailableHooks.eFaceHeading | eAvailableHooks.eAC3DRegion |
|
||||
eAvailableHooks.eObjectDestroyed | eAvailableHooks.eSendTell |
|
||||
eAvailableHooks.eSetAutorun | eAvailableHooks.eSetCombatMode |
|
||||
eAvailableHooks.eGetMiscInt | eAvailableHooks.eGetAttribute |
|
||||
eAvailableHooks.eGetSkill | eAvailableHooks.eGetVital |
|
||||
eAvailableHooks.eHooksAvailEx);
|
||||
|
||||
public bool HooksAvailEx => true;
|
||||
|
||||
// Chat methods
|
||||
public void AddChatText(string szText, int lColor, int lTarget)
|
||||
{
|
||||
// In the open-source version, we fire this through the chat event system
|
||||
bool eat = false;
|
||||
ChatTextIntercept?.Invoke(szText, lColor, lTarget, ref eat);
|
||||
}
|
||||
|
||||
public void AddChatTextRaw(string szText, int lColor, int lTarget)
|
||||
{
|
||||
AddChatText(szText, lColor, lTarget);
|
||||
}
|
||||
|
||||
public void AddStatusText(string Text)
|
||||
{
|
||||
bool eat = false;
|
||||
StatusTextIntercept?.Invoke(Text, ref eat);
|
||||
}
|
||||
|
||||
public void InvokeChatParser(string Text)
|
||||
{
|
||||
bool eat = false;
|
||||
ChatParserIntercept?.Invoke(Text, ref eat);
|
||||
}
|
||||
|
||||
public void SetIdleTime(double dIdleTimeout) { }
|
||||
|
||||
public void Logout() { }
|
||||
|
||||
// Selection
|
||||
public int CurrentSelection { get => _currentSelection; set => _currentSelection = value; }
|
||||
public int PreviousSelection { get => _previousSelection; set => _previousSelection = value; }
|
||||
public int SelectedStackCount { get => _selectedStackCount; set => _selectedStackCount = value; }
|
||||
public int MaxSelectedStackCount => _maxSelectedStackCount;
|
||||
|
||||
public void SetCursorPosition(int lX, int lY) { }
|
||||
|
||||
// Window/region info
|
||||
public tagRECT AC3DRegionRect => _ac3dRegionRect;
|
||||
public IntPtr AC3DRegionRectPtr => IntPtr.Zero;
|
||||
public tagRECT ACWindowRect => _acWindowRect;
|
||||
|
||||
// State properties
|
||||
public bool ChatState => _chatState;
|
||||
public int BusyState => _busyState;
|
||||
public int BusyStateID => _busyStateId;
|
||||
public int PointerState => _pointerState;
|
||||
public int VendorID => _vendorId;
|
||||
|
||||
// Vendor operations
|
||||
public void VendorBuyListAdd(int lID, int lAmount) { }
|
||||
public void VendorBuyListClear() { }
|
||||
public void VendorBuyAll() { }
|
||||
public void VendorSellListAdd(int lID) { }
|
||||
public void VendorSellListClear() { }
|
||||
public void VendorSellAll() { }
|
||||
|
||||
// Combat
|
||||
public int CombatMode => _combatMode;
|
||||
public void SetCombatMode(int pVal) { _combatMode = pVal; }
|
||||
public void SetAutorun(bool bOnOff) { }
|
||||
public bool FaceHeading(float fHeading, bool bUnknown) { return true; }
|
||||
|
||||
public int CommandInterpreter => _commandInterpreter;
|
||||
|
||||
// Item operations
|
||||
public void SelectItem(int lObjectID)
|
||||
{
|
||||
_previousSelection = _currentSelection;
|
||||
_currentSelection = lObjectID;
|
||||
ObjectSelected?.Invoke(lObjectID);
|
||||
}
|
||||
|
||||
public void GiveItem(int lObject, int lDestination) { }
|
||||
public void ApplyItem(int UseThis, int OnThis) { }
|
||||
public void UseItem(int lObjectID, int lUseState) { }
|
||||
public void UseItemRaw(int lObjectID, int lUseState, int lUseMethod) { }
|
||||
public void MoveItem(int lObjectID, int lPackID, int lSlot, bool bStack) { }
|
||||
public void MoveItemEx(int lObjectID, int lDestinationID) { }
|
||||
public void MoveItemExRaw(int lObject, int lDestination, int lMoveFlags) { }
|
||||
public void DropItem(int lObjectID) { }
|
||||
|
||||
// Spell casting
|
||||
public void CastSpell(int lSpellID, int lObjectID) { }
|
||||
|
||||
// Object queries
|
||||
public bool IsValidObject(int lGUID) => false;
|
||||
public int GetWeenieObjectPtr(int lObjectID) => 0;
|
||||
public int GetPhysicsObjectPtr(int lObjectID) => 0;
|
||||
|
||||
// Position
|
||||
public double HeadingDegrees => _headingDegrees;
|
||||
public double HeadingRadians => _headingRadians;
|
||||
public int Landcell => _landcell;
|
||||
public double LocationX => _locationX;
|
||||
public double LocationY => _locationY;
|
||||
public double LocationZ => _locationZ;
|
||||
|
||||
// Character stats (parameterized properties — index-based access)
|
||||
public eTrainLevel SkillTrainLevel => eTrainLevel.eUntrained;
|
||||
public int SkillTotalXP => 0;
|
||||
public int SkillFreePoints => 0;
|
||||
public int SkillClicks => 0;
|
||||
public int AttributeTotalXP => 0;
|
||||
public int AttributeClicks => 0;
|
||||
public int AttributeStart => 0;
|
||||
public int VitalTotalXP => 0;
|
||||
public int VitalClicks => 0;
|
||||
public int Vital => 0;
|
||||
public int Attribute => 0;
|
||||
public int Skill => 0;
|
||||
public int Misc => 0;
|
||||
|
||||
// ID/object operations
|
||||
public void RequestID(int lObjectID) { _idFilter?.AddToQueue(lObjectID); }
|
||||
public void IDQueueAdd(int lObjectID) { _idFilter?.AddToQueue(lObjectID); }
|
||||
|
||||
// Spell bar
|
||||
public void SpellTabAdd(int lTab, int lIndex, int lSpellID) { }
|
||||
public void SpellTabDelete(int lTab, int lSpellID) { }
|
||||
|
||||
// Trade
|
||||
public void TradeAdd(int ItemID) { }
|
||||
public void TradeAccept() { }
|
||||
public void TradeDecline() { }
|
||||
public void TradeReset() { }
|
||||
public void TradeEnd() { }
|
||||
|
||||
// Salvage
|
||||
public void SalvagePanelAdd(int lObjectID) { }
|
||||
public void SalvagePanelSalvage() { }
|
||||
|
||||
public int OpenedContainer => _openedContainer;
|
||||
|
||||
// Experience
|
||||
public void AddSkillExp(eSkill SkillID, int lExperience) { }
|
||||
public void AddAttributeExp(eAttribute AttribID, int lExperience) { }
|
||||
public void AddVitalExp(eVital VitalID, int lExperience) { }
|
||||
|
||||
public int SmartboxPtr() => 0;
|
||||
public float ObjectHeight(int lObjectID) => 0f;
|
||||
|
||||
public int CallerRefInstanceInternal { set { } }
|
||||
|
||||
// Equipment
|
||||
public void AutoWieldRaw(int lObjectID, int SlotID, int Explicit, int NotExplicit, int zeroVal1, int zeroVal2) { }
|
||||
public void AutoWield(int lObjectID) { }
|
||||
public void AutoWieldEx(int lObjectID, int SlotID, int Explicit, int NotExplicit) { }
|
||||
|
||||
// Fellowship
|
||||
public void FellowshipRecruit(int lObjectID) { }
|
||||
public void FellowshipGrantLeader(int lObjectID) { }
|
||||
public void FellowshipSetOpen(bool IsOpen) { }
|
||||
public void FellowshipQuit() { }
|
||||
public void FellowshipDisband() { }
|
||||
public void FellowshipDismiss(int lObjectID) { }
|
||||
|
||||
// UI
|
||||
public void UIElementMove(int lUIElementType, int X, int Y) { }
|
||||
public void UIElementResize(int lUIElementType, int Width, int Height) { }
|
||||
public int UIElementLookup(int lUIElementType) => 0;
|
||||
public tagRECT UIElementRegionRect(int lUIElementType) => default;
|
||||
|
||||
// Internal event firing methods
|
||||
internal void FireObjectDestroyed(int guid) => ObjectDestroyed?.Invoke(guid);
|
||||
internal void FireContainerOpened(int guid) => ContainerOpened?.Invoke(guid);
|
||||
internal void FireRenderPreUI() => RenderPreUI?.Invoke();
|
||||
|
||||
internal void FireChatText(string text, int color, int target, ref bool eat)
|
||||
{
|
||||
ChatTextIntercept?.Invoke(text, color, target, ref eat);
|
||||
}
|
||||
|
||||
internal void FireChatParser(string text, ref bool eat)
|
||||
{
|
||||
ChatParserIntercept?.Invoke(text, ref eat);
|
||||
}
|
||||
|
||||
internal void FireStatusText(string text, ref bool eat)
|
||||
{
|
||||
StatusTextIntercept?.Invoke(text, ref eat);
|
||||
}
|
||||
|
||||
internal void FireObjectSelected(int guid) => ObjectSelected?.Invoke(guid);
|
||||
|
||||
internal void FireAC3DRegionChanged(int left, int top, int right, int bottom)
|
||||
{
|
||||
_ac3dRegionRect = new tagRECT { left = left, top = top, right = right, bottom = bottom };
|
||||
AC3DRegionChanged?.Invoke(left, top, right, bottom);
|
||||
}
|
||||
|
||||
internal void FireChatClick(string text, int id, ref bool eat)
|
||||
{
|
||||
ChatClickIntercept?.Invoke(text, id, ref eat);
|
||||
}
|
||||
|
||||
internal void UpdatePosition(double x, double y, double z, int landcell, double headDeg, double headRad)
|
||||
{
|
||||
_locationX = x;
|
||||
_locationY = y;
|
||||
_locationZ = z;
|
||||
_landcell = landcell;
|
||||
_headingDegrees = headDeg;
|
||||
_headingRadians = headRad;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue