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>
159 lines
2.9 KiB
C++
159 lines
2.9 KiB
C++
// ProtocolStack.h
|
|
// Declaration of class cProtocolStack
|
|
|
|
#ifndef __PROTOCOLSTACK_H
|
|
#define __PROTOCOLSTACK_H
|
|
|
|
#include <crtdbg.h> // For assertions
|
|
|
|
#define DEFAULT_HEADER_SIZE 16
|
|
#define FRAGMENT_SIZE 448
|
|
|
|
#define MAX_FRAGMENT_COUNT 1024
|
|
|
|
#pragma pack( push, 1 )
|
|
// The packet header
|
|
struct cPacketHeader
|
|
{
|
|
DWORD m_dwSequence;
|
|
DWORD m_dwFlags;
|
|
DWORD m_dwCRC;
|
|
|
|
WORD m_wUnk1;
|
|
WORD m_wUnk2;
|
|
WORD m_wTotalSize;
|
|
WORD m_wUnk3;
|
|
};
|
|
#pragma pack( pop )
|
|
|
|
|
|
class FragmentMask
|
|
{
|
|
public:
|
|
FragmentMask () { ::memset (m_mask, 0, sizeof (m_mask)); m_size = 0; }
|
|
|
|
void SetSize (WORD wSize)
|
|
{
|
|
_ASSERTE (wSize < MAX_FRAGMENT_COUNT);
|
|
m_size = wSize;
|
|
|
|
::memset (m_mask, 0, sizeof (m_mask));
|
|
for (WORD wIndex = 0; wIndex < wSize; ++wIndex)
|
|
{
|
|
m_mask[wIndex/32] |= (1L << (wIndex % 32));
|
|
}
|
|
}
|
|
|
|
void GotFragment (WORD wWhich)
|
|
{
|
|
_ASSERTE (wWhich < m_size && wWhich >= 0);
|
|
|
|
m_mask[wWhich/32] &= ~(1 << (wWhich % 32));
|
|
}
|
|
|
|
bool IsComplete ()
|
|
{
|
|
for (WORD wLoop = 0; wLoop < (FRAGMENT_SIZE/32); ++wLoop)
|
|
{
|
|
if (m_mask[wLoop])
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
private:
|
|
DWORD m_mask[FRAGMENT_SIZE/32];
|
|
WORD m_size;
|
|
};
|
|
|
|
class cMessageStack
|
|
{
|
|
public:
|
|
#pragma pack( push, 1 )
|
|
struct cMessageHeader
|
|
{
|
|
DWORD m_dwSequence;
|
|
DWORD m_dwObjectID;
|
|
WORD m_wFragmentCount;
|
|
WORD m_wFragmentLength;
|
|
WORD m_wFragmentIndex,
|
|
m_wUnknown1;
|
|
};
|
|
#pragma pack( pop )
|
|
|
|
class cMessage
|
|
{
|
|
protected:
|
|
// DWORD m_dwFragmentsMask;
|
|
BYTE *m_pbData;
|
|
mutable bool m_bOwn;
|
|
mutable FragmentMask m_FragmentMask;
|
|
|
|
public:
|
|
cMessage( BYTE *pbData );
|
|
cMessage( const cMessage &msg );
|
|
~cMessage();
|
|
|
|
cMessageHeader *getMessageHeader() const
|
|
{
|
|
return reinterpret_cast< cMessageHeader * >( m_pbData );
|
|
}
|
|
|
|
cMessage &operator= ( const cMessage &msg );
|
|
|
|
BYTE *getBody() const
|
|
{
|
|
return m_pbData + sizeof( cMessageHeader );
|
|
}
|
|
|
|
DWORD getBodyLength() const
|
|
{
|
|
return getMessageHeader()->m_wFragmentLength - sizeof( cMessageHeader );
|
|
}
|
|
|
|
bool isComplete() const
|
|
{
|
|
return m_FragmentMask.IsComplete ();
|
|
}
|
|
|
|
DWORD getMessageCode() const
|
|
{
|
|
return *reinterpret_cast< DWORD * >( m_pbData + sizeof( cMessageHeader ) );
|
|
}
|
|
|
|
bool fragmentMatch( BYTE *pFragmentStart );
|
|
void insertFragment( BYTE *pFragmentStart );
|
|
|
|
static DWORD calcMessageLength( BYTE *pbHeader );
|
|
};
|
|
|
|
// Objects wishing to receive
|
|
class cCallback
|
|
{
|
|
public:
|
|
virtual void onMessage( cMessage & ) = 0;
|
|
};
|
|
|
|
private:
|
|
typedef std::list< cMessage > cMessageList;
|
|
|
|
cCallback *m_pCallback;
|
|
cMessageList m_messages;
|
|
|
|
public:
|
|
cMessageStack();
|
|
~cMessageStack();
|
|
|
|
void start( cCallback * );
|
|
void stop();
|
|
|
|
void processPacket( DWORD dwLength, BYTE *pbPayload );
|
|
|
|
private:
|
|
void splitPacket( DWORD dwLength, BYTE *pbPayload );
|
|
};
|
|
|
|
#endif
|