openDecal/Native/Inject/Attic/ProtocolStack.h
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

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