Files
Jedi-Academy/codemp/xbox/match.h
2013-04-04 14:32:05 -07:00

440 lines
12 KiB
C++

//-----------------------------------------------------------------------------
//
// Xbox Matchmaking Definitions for Title: Jedi Academy [0x4C41000B]
// Generated by MatchSim
//
//-----------------------------------------------------------------------------
#pragma once
#include <xtl.h>
#include <xonline.h>
#include <assert.h>
//-----------------------------------------------------------------------------
// Constants
//-----------------------------------------------------------------------------
//
// Attribute IDs ID num Data Type
// ------ ----------------------------
const DWORD XATTRIB_GAME_TYPE = 0x0001 | X_ATTRIBUTE_DATATYPE_INTEGER;
const DWORD XATTRIB_CURRENT_MAP = 0x0002 | X_ATTRIBUTE_DATATYPE_INTEGER;
const DWORD XATTRIB_SESSION_NAME = 0x0003 | X_ATTRIBUTE_DATATYPE_STRING;
const DWORD XATTRIB_FRIENDLY_FIRE = 0x0004 | X_ATTRIBUTE_DATATYPE_INTEGER;
const DWORD XATTRIB_JEDI_MASTERY = 0x0005 | X_ATTRIBUTE_DATATYPE_INTEGER;
const DWORD XATTRIB_TOTAL_PLAYERS = 0x0007 | X_ATTRIBUTE_DATATYPE_INTEGER;
const DWORD XATTRIB_SABER_ONLY = 0x0008 | X_ATTRIBUTE_DATATYPE_INTEGER;
const DWORD XATTRIB_DEDICATED = 0x0009 | X_ATTRIBUTE_DATATYPE_INTEGER;
//
// Attribute Maximum Lengths
// (for strings, this doesn't include the terminating NULL)
//
const DWORD XATTRIB_SESSION_NAME_MAX_LEN = 16; // SessionName attribute
// Specify X_MATCH_NULL_INTEGER for optional integer query arguments
const ULONGLONG X_MATCH_NULL_INTEGER = 0x7FFFFFFFFFFFFFFFui64;
// Maximum number of sessions returned by OptiMatch query
const DWORD MAX_OPTI_MATCH_RESULTS = 25;
// Maximum number of sessions returned by JoinSessionByID query
const DWORD MAX_JOIN_SESSION_BY_ID_RESULTS = 1;
// Number of QoS probes
const DWORD NUM_QOS_PROBES = 8;
// Maximum bandwidth to consume for QoS probes
const DWORD QOS_BITS_PER_SEC = 16000;
//-----------------------------------------------------------------------------
// Types
//-----------------------------------------------------------------------------
// Helper class for getting/setting blob attributes
class CBlob
{
public:
CBlob() : m_wLength( 0 ), m_pvData( NULL ) {}
CBlob( WORD wLength, const PVOID pvData ) : m_wLength( wLength), m_pvData( pvData) {}
CBlob( const CBlob & b ) { *this = b; }
CBlob & operator=( const CBlob & b )
{ m_wLength = b.Length; m_pvData = b.Data; return *this; }
BOOL operator==( const CBlob & b ) const
{ return m_wLength == b.Length && memcmp( m_pvData, b.Data, b.Length ) == 0; }
BOOL IsNull() { return m_pvData == NULL; }
__declspec( property( put = SetData, get=GetData ) ) const PVOID Data;
const PVOID GetData() const { return m_pvData; }
VOID SetData( const PVOID pvData ) { m_pvData = pvData; }
__declspec( property( put = SetLength, get=GetLength ) ) WORD Length;
WORD GetLength() const { return m_wLength; }
VOID SetLength( WORD wLength ) { m_wLength = wLength; }
private:
WORD m_wLength;
PVOID m_pvData;
};
// A null blob is defined as having a NULL pointer
#define NULL_BLOB CBlob( 0, NULL )
// Macro for declaring "blob literals" (much like the _T() macro does for strings)
#define B( length, ptr ) CBlob( length, (const PVOID) ptr )
class CSession
{
public:
CSession();
~CSession();
HRESULT Create();
HRESULT Update();
HRESULT Delete();
HRESULT Process();
VOID Reset();
DWORD PublicFilled;
DWORD PublicOpen;
DWORD PrivateFilled;
DWORD PrivateOpen;
XNKEY KeyExchangeKey;
XNKID SessionID;
BOOL IsUpdating() const { return m_State == STATE_UPDATING; }
BOOL IsDeleting() const { return m_State == STATE_DELETING; }
BOOL IsCreating() const { return m_State == STATE_CREATING; }
BOOL Exists() const { return m_State == STATE_ACTIVE || IsUpdating(); }
// Attribute Accessors
BOOL IsListening() const { return m_bListening; }
__declspec( property( put = SetQosResponse, get = GetQosResponse ) ) CBlob QosResponse;
CBlob GetQosResponse();
VOID SetQosResponse( CBlob Value );
VOID Listen( BOOL bEnable = TRUE, DWORD dwBitsPerSec = 0 );
static const DWORD NO_WAIT = 1;
__declspec( property( put = SetGameType, get=GetGameType ) ) ULONGLONG GameType;
ULONGLONG GetGameType();
VOID SetGameType( ULONGLONG Value );
__declspec( property( put = SetCurrentMap, get=GetCurrentMap ) ) ULONGLONG CurrentMap;
ULONGLONG GetCurrentMap();
VOID SetCurrentMap( ULONGLONG Value );
__declspec( property( put = SetSessionName, get=GetSessionName ) ) const WCHAR * SessionName;
const WCHAR * GetSessionName();
VOID SetSessionName( const WCHAR * Value );
__declspec( property( put = SetFriendlyFire, get=GetFriendlyFire ) ) ULONGLONG FriendlyFire;
ULONGLONG GetFriendlyFire();
VOID SetFriendlyFire( ULONGLONG Value );
__declspec( property( put = SetJediMastery, get=GetJediMastery ) ) ULONGLONG JediMastery;
ULONGLONG GetJediMastery();
VOID SetJediMastery( ULONGLONG Value );
__declspec( property( put = SetTotalPlayers, get=GetTotalPlayers ) ) ULONGLONG TotalPlayers;
ULONGLONG GetTotalPlayers();
VOID SetTotalPlayers( ULONGLONG Value );
__declspec( property( put = SetSaberOnly, get=GetSaberOnly ) ) ULONGLONG SaberOnly;
ULONGLONG GetSaberOnly();
VOID SetSaberOnly( ULONGLONG Value );
__declspec( property( put = SetDedicated, get=GetDedicated ) ) ULONGLONG Dedicated;
ULONGLONG GetDedicated();
VOID SetDedicated( ULONGLONG Value );
private:
// The m_Attributes array is accessed using predefined constants:
enum
{
GAME_TYPE_INDEX,
CURRENT_MAP_INDEX,
SESSION_NAME_INDEX,
FRIENDLY_FIRE_INDEX,
JEDI_MASTERY_INDEX,
TOTAL_PLAYERS_INDEX,
SABER_ONLY_INDEX,
DEDICATED_INDEX,
NUM_ATTRIBUTES
};
XONLINE_ATTRIBUTE m_Attributes[NUM_ATTRIBUTES];
// Storage for the SessionName string attribute
WCHAR m_strSessionName[XATTRIB_SESSION_NAME_MAX_LEN+1];
// Qos listening
struct QosQEntry
{
XNKID SessionID; // Session to unregister
DWORD dwStartTick; // Time entry was added
struct QosQEntry *pNext; // Next item in the queue
};
class CSessionQosQ
{
public:
CSessionQosQ();
VOID Add( XNKID & SessionID, DWORD dwStartTick );
VOID Remove( XNKID &SessionID );
VOID Dequeue();
const QosQEntry *Head() const { return m_pHead; }
const QosQEntry *Tail() const { return m_pTail; }
private:
QosQEntry *m_pHead;
QosQEntry *m_pTail;
};
CSessionQosQ m_SessionQosQ;
BOOL m_bListening; // Listening for Qos probes
CBlob m_QosResponse;
VOID PurgeSessionQ( BOOL fRemoveAll = FALSE );
VOID PurgeSessionQHead();
HRESULT ProcessStateCreateSession();
HRESULT ProcessStateUpdateSession();
HRESULT ProcessStateDeleteSession();
HRESULT ProcessStateActiveSession();
VOID Close();
VOID SetupAttributes();
XONLINETASK_HANDLE m_hSessionTask;
enum STATE
{
STATE_IDLE,
STATE_CREATING,
STATE_UPDATING,
STATE_DELETING,
STATE_ACTIVE
};
STATE m_State;
BOOL m_bKeyRegistered;
BOOL m_bUpdate;
};
//
// COptiMatchResult represents a single return result from the
// OptiMatch query
//
#pragma pack(push, 1)
class COptiMatchResult
{
public:
// The query return attributes must come first, and in the order
// returned by the query
ULONGLONG GameType;
ULONGLONG CurrentMap;
WCHAR SessionName[XATTRIB_SESSION_NAME_MAX_LEN+1];
ULONGLONG FriendlyFire;
ULONGLONG JediMastery;
ULONGLONG SaberOnly;
ULONGLONG Dedicated;
XNKID SessionID;
XNKEY KeyExchangeKey;
XNADDR HostAddress;
DWORD PublicOpen;
DWORD PrivateOpen;
DWORD PublicFilled;
DWORD PrivateFilled;
XNQOSINFO* pQosInfo;
};
#pragma pack(pop)
// Collection of results for the OptiMatch query
class COptiMatchQueryResults
{
public:
COptiMatchQueryResults() { m_dwSize = 0; }
DWORD Size() { return m_dwSize; }
COptiMatchResult &operator[]( DWORD i ) { return v[i]; }
private:
void Clear() { m_dwSize = 0; }
void Remove( DWORD i )
{
assert( i < m_dwSize );
if( i < m_dwSize )
{
m_dwSize--;
memcpy( &v[i], &v[i+1], sizeof( v[0] ) * ( m_dwSize - i ) );
}
}
void SetSize( DWORD dwSize ) { m_dwSize = dwSize; }
friend class COptiMatchQuery;
COptiMatchResult v[MAX_OPTI_MATCH_RESULTS];
DWORD m_dwSize;
};
//
// Query object for OptiMatch query (id 0x1)
//
class COptiMatchQuery
{
public:
COptiMatchQuery();
~COptiMatchQuery();
COptiMatchQueryResults Results;
HRESULT Process();
void Cancel();
void Clear();
BOOL Done() const { return m_State == STATE_DONE; }
BOOL Succeeded() const { return SUCCEEDED( m_hrQuery ); }
HRESULT Query(
ULONGLONG GameType, // Optional: X_MATCH_NULL_INTEGER to omit
ULONGLONG CurrentMap, // Optional: X_MATCH_NULL_INTEGER to omit
ULONGLONG MinimumPlayers,
ULONGLONG MaximumPlayers,
ULONGLONG FriendlyFire, // Optional: X_MATCH_NULL_INTEGER to omit
ULONGLONG JediMastery, // Optional: X_MATCH_NULL_INTEGER to omit
ULONGLONG SaberOnly, // Optional: X_MATCH_NULL_INTEGER to omit
ULONGLONG Dedicated // Optional: X_MATCH_NULL_INTEGER to omit
);
BOOL IsRunning() const { return m_State == STATE_RUNNING || m_State == STATE_PROBING_CONNECTIVITY; }
BOOL IsProbing() const { return m_State == STATE_PROBING_BANDWIDTH; }
HRESULT Probe();
private:
// Quality of Service
const XNADDR *m_rgpXnAddr[ MAX_OPTI_MATCH_RESULTS ];
const XNKID *m_rgpXnKid [ MAX_OPTI_MATCH_RESULTS ];
const XNKEY *m_rgpXnKey [ MAX_OPTI_MATCH_RESULTS ];
XNQOS *m_pXnQos;
enum STATE
{
STATE_IDLE,
STATE_RUNNING,
STATE_PROBING_CONNECTIVITY,
STATE_PROBING_BANDWIDTH,
STATE_DONE
};
STATE m_State;
HRESULT m_hrQuery;
XONLINETASK_HANDLE m_hSearchTask;
};
//
// CJoinSessionByIDResult represents a single return result from the
// JoinSessionByID query
//
#pragma pack(push, 1)
class CJoinSessionByIDResult
{
public:
XNKID SessionID;
XNKEY KeyExchangeKey;
XNADDR HostAddress;
DWORD PublicOpen;
DWORD PrivateOpen;
DWORD PublicFilled;
DWORD PrivateFilled;
XNQOSINFO* pQosInfo;
};
#pragma pack(pop)
// Collection of results for the JoinSessionByID query
class CJoinSessionByIDQueryResults
{
public:
CJoinSessionByIDQueryResults() { m_dwSize = 0; }
DWORD Size() { return m_dwSize; }
CJoinSessionByIDResult &operator[]( DWORD i ) { return v[i]; }
private:
void Clear() { m_dwSize = 0; }
void Remove( DWORD i )
{
assert( i < m_dwSize );
if( i < m_dwSize )
{
m_dwSize--;
memcpy( &v[i], &v[i+1], sizeof( v[0] ) * ( m_dwSize - i ) );
}
}
void SetSize( DWORD dwSize ) { m_dwSize = dwSize; }
friend class CJoinSessionByIDQuery;
CJoinSessionByIDResult v[MAX_JOIN_SESSION_BY_ID_RESULTS];
DWORD m_dwSize;
};
//
// Query object for JoinSessionByID query (id 0x2)
//
class CJoinSessionByIDQuery
{
public:
CJoinSessionByIDQuery();
~CJoinSessionByIDQuery();
CJoinSessionByIDQueryResults Results;
HRESULT Process();
void Cancel();
void Clear();
BOOL Done() const { return m_State == STATE_DONE; }
BOOL Succeeded() const { return SUCCEEDED( m_hrQuery ); }
HRESULT Query(
ULONGLONG SessionID
);
BOOL IsRunning() const { return m_State == STATE_RUNNING || m_State == STATE_PROBING_CONNECTIVITY; }
BOOL IsProbing() const { return m_State == STATE_PROBING_BANDWIDTH; }
HRESULT Probe();
private:
// Quality of Service
const XNADDR *m_rgpXnAddr[ MAX_JOIN_SESSION_BY_ID_RESULTS ];
const XNKID *m_rgpXnKid [ MAX_JOIN_SESSION_BY_ID_RESULTS ];
const XNKEY *m_rgpXnKey [ MAX_JOIN_SESSION_BY_ID_RESULTS ];
XNQOS *m_pXnQos;
enum STATE
{
STATE_IDLE,
STATE_RUNNING,
STATE_PROBING_CONNECTIVITY,
STATE_PROBING_BANDWIDTH,
STATE_DONE
};
STATE m_State;
HRESULT m_hrQuery;
XONLINETASK_HANDLE m_hSearchTask;
};