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:
erik 2026-02-08 18:27:56 +01:00
commit d1442e3747
1382 changed files with 170725 additions and 0 deletions

View file

@ -0,0 +1,212 @@
// IdentifyQueue.cpp : Implementation of CIdentifyQueue
#include "stdafx.h"
#include "IdentifyQueue.h"
// Timeout in millisec to re-request ID
#define TIMEOUT 700
enum AcMessages
{
msgGameEvent = 0xF7B0,
msgUnknown = 0
};
enum AcGameEvents
{
gevIDItem = 0x00C9,
gevUnknown = 0
};
// CIdentifyQueue
HRESULT CIdentifyQueue::onInitialize()
{
if( m_pService->get_Decal( &m_pDecal ) == S_OK )
{
if( m_pDecal->get_Hooks( &m_pHooks ) == S_OK )
{
m_pHooks->SetIDFilter( this );
long lRequestIDMemloc;
if( m_pHooks->QueryMemLoc( _bstr_t( "ItemEventAppraise" ), &lRequestIDMemloc ) == S_OK )
{
if( lRequestIDMemloc != 0 )
{
m_pfRequestFunc = reinterpret_cast< RequestPtr >( lRequestIDMemloc );
return S_OK;
}
}
}
}
m_pfRequestFunc = NULL;
m_pService.Release();
return E_FAIL;
}
HRESULT CIdentifyQueue::onTerminate()
{
m_pDecal.Release();
m_pHooks.Release();
m_pfRequestFunc = NULL;
return S_OK;
}
STDMETHODIMP CIdentifyQueue::DispatchServer( IMessage2 *pMsg )
{
long lType;
pMsg->get_Type( &lType );
CComPtr< IMessageIterator > pMembers;
pMsg->get_Begin( &pMembers );
switch( lType )
{
case msgGameEvent: MsgGameEvent( pMembers ); break;
}
if( m_Queue.empty() )
return S_OK;
// Check for timeout...
if( m_bWaiting )
{
if( abs( m_Queue[0]->lTime - timeGetTime() ) > TIMEOUT )
{
if( ++m_lAttempts >= 3 )
{
m_lAttempts = 0;
m_Queue.erase( m_Queue.begin() );
m_bWaiting = false;
Request();
}
else
{
m_Queue[0]->lTime = timeGetTime();
m_bWaiting = false;
Request();
}
}
}
return S_OK;
}
STDMETHODIMP CIdentifyQueue::AddToQueue( long lObjectID )
{
if( lObjectID == 0 )
return S_OK;
if( !m_Queue.empty() )
{
for( IDContainer::iterator pDeque = m_Queue.begin(); pDeque != m_Queue.end(); ++pDeque )
{
if( (*pDeque)->lObjectID == lObjectID )
return S_OK;
}
}
IDStruct *QueueObj = new IDStruct();
QueueObj->lObjectID = lObjectID;
QueueObj->lTime = timeGetTime();
m_Queue.push_back( QueueObj );
if( !m_bWaiting )
Request();
return S_OK;
}
STDMETHODIMP CIdentifyQueue::ShortcircuitID( long lObjectID )
{
m_lLastManualAttempt = lObjectID;
if( !m_Queue.empty() )
{
for( IDContainer::iterator pDeque = m_Queue.begin(); pDeque != m_Queue.end(); ++pDeque )
{
if ( (*pDeque)->lObjectID == lObjectID )
{
m_Queue.erase( pDeque );
break;
}
}
}
IDStruct *QueueObj = new IDStruct();
QueueObj->lObjectID = lObjectID;
QueueObj->lTime = timeGetTime();
m_Queue.push_front( QueueObj );
if( !m_bWaiting )
Request();
return S_OK;
}
void CIdentifyQueue::MsgGameEvent( IMessageIterator *pMembers )
{
long lEvent;
pMembers->get_NextInt( _bstr_t( "event" ), &lEvent );
switch( lEvent )
{
case gevIDItem: MsgIDItem( pMembers ); break;
}
}
void CIdentifyQueue::MsgIDItem( IMessageIterator *pMembers )
{
if( m_Queue.empty() )
return;
long lObjectID;
pMembers->get_NextInt( _bstr_t( "object" ), &lObjectID );
for( IDContainer::iterator pDeque = m_Queue.begin(); pDeque != m_Queue.end(); pDeque++ )
{
if ( (*pDeque)->lObjectID == lObjectID )
{
m_lAttempts = 0;
pDeque = m_Queue.erase( pDeque );
break;
}
}
if( m_bWaiting )
{
m_bWaiting = false;
Request();
}
}
void CIdentifyQueue::Request()
{
if( !m_bWaiting )
{
if( m_Queue.empty() )
{
m_pfRequestFunc( 0 );
return;
}
IDStruct *pQueueBegin = *m_Queue.begin();
m_pfRequestFunc( pQueueBegin->lObjectID );
m_bWaiting = true;
if( pQueueBegin->lObjectID == 0 )
{
m_bWaiting = false;
m_Queue.erase( m_Queue.begin() );
Request();
}
}
}