Game client codebase including: - CharacterActionControl: Character and creature management - GlobalScript: Network, items, skills, quests, utilities - RYLClient: Main client application with GUI and event handlers - Engine: 3D rendering engine (RYLGL) - MemoryManager: Custom memory allocation - Library: Third-party dependencies (DirectX, boost, etc.) - Tools: Development utilities 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
241 lines
8.8 KiB
C++
241 lines
8.8 KiB
C++
//-----------------------------------------------------------------------------
|
|
// File: Lobby.cpp
|
|
//
|
|
// Desc: DP lobby related routines
|
|
//
|
|
// Copyright (C) 1995-2001 Microsoft Corporation. All Rights Reserved.
|
|
//-----------------------------------------------------------------------------
|
|
#include "duel.h"
|
|
#include "lobby.h"
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Definitions
|
|
//-----------------------------------------------------------------------------
|
|
#define SAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } }
|
|
#define SAFE_DELETE_ARRAY(p) { if(p) { delete[] (p); (p)=NULL; } }
|
|
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
|
|
|
|
#define TIMERID 1 // Timer ID to use
|
|
#define TIMERINTERVAL 250 // Timer interval
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Globals
|
|
//-----------------------------------------------------------------------------
|
|
extern LPDIRECTPLAY4 g_pDP; // DirectPlay object pointer
|
|
extern LPDPLCONNECTION g_pDPLConnection; // Connection settings
|
|
extern LPDIRECTPLAYLOBBY3 g_pDPLobby; // Lobby object pointer
|
|
extern BOOL g_bHostPlayer; // Flag indicating if we are hosting
|
|
extern HWND g_hwndMain; // Main application window handle
|
|
extern HINSTANCE g_hInst; // Application instance handle
|
|
|
|
BOOL g_bLobbyMsgSupported; // Lobby messages are supported
|
|
GUID g_guidPlayer; // This player in this session
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Name: DPLobbyRelease()
|
|
// Desc: Wrapper for DirectPlayLobby Release API
|
|
//-----------------------------------------------------------------------------
|
|
HRESULT DPLobbyRelease()
|
|
{
|
|
// Cleanup lobby
|
|
SAFE_DELETE_ARRAY( g_pDPLConnection );
|
|
SAFE_RELEASE( g_pDPLobby );
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Name: DoingLobbyMessages()
|
|
// Desc: Return TRUE if connected to a lobby and messages are supported.
|
|
//-----------------------------------------------------------------------------
|
|
BOOL DoingLobbyMessages()
|
|
{
|
|
return( g_pDPLobby && g_bLobbyMsgSupported );
|
|
}
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Name: LobbyMessageInit()
|
|
// Desc: Initialize lobby message processing. Must be done while a lobby
|
|
// connection is open.
|
|
//-----------------------------------------------------------------------------
|
|
HRESULT LobbyMessageInit()
|
|
{
|
|
if( NULL ==g_pDPLobby ) // Not connected to a lobby
|
|
return E_FAIL;
|
|
|
|
g_bLobbyMsgSupported = FALSE; // Until we find out otherwise.
|
|
|
|
// Find out if lobby messages are supported by the lobby
|
|
DPLMSG_GETPROPERTY msgGetProp;
|
|
ZeroMemory( &msgGetProp, sizeof(DPLMSG_GETPROPERTY) );
|
|
msgGetProp.dwType = DPLSYS_GETPROPERTY;
|
|
msgGetProp.dwRequestID = 1; // guidPlayer is not used
|
|
msgGetProp.guidPropertyTag = DPLPROPERTY_MessagesSupported;
|
|
|
|
return g_pDPLobby->SendLobbyMessage( DPLMSG_STANDARD, 0, &msgGetProp,
|
|
sizeof(DPLMSG_GETPROPERTY) );
|
|
}
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Name: LobbyMessageReceive()
|
|
// Desc: Check for any lobby messages and handle them
|
|
// There are two modes:
|
|
// LMR_CONNECTIONSETTINGS - Waiting only for settings from a lobby
|
|
// LMR_PROPERTIES - Handle property message responses
|
|
//-----------------------------------------------------------------------------
|
|
HRESULT LobbyMessageReceive( DWORD dwMode )
|
|
{
|
|
HRESULT hr = NOERROR;
|
|
LPVOID lpMsgBuffer = NULL;
|
|
DWORD dwBufferSize = 0;
|
|
DWORD dwRequiredSize;
|
|
DWORD dwMsgFlags;
|
|
|
|
if( NULL == g_pDPLobby ) // No lobby interface
|
|
return DPERR_NOINTERFACE;
|
|
|
|
while( SUCCEEDED(hr) ) // Get all queued messages
|
|
{
|
|
dwRequiredSize = dwBufferSize;
|
|
hr = g_pDPLobby->ReceiveLobbyMessage( 0, 0, &dwMsgFlags,
|
|
lpMsgBuffer, &dwRequiredSize );
|
|
if( hr == DPERR_BUFFERTOOSMALL ) // Alloc msg buffer and try again
|
|
{
|
|
if( NULL == lpMsgBuffer )
|
|
lpMsgBuffer = GlobalAllocPtr( GHND, dwRequiredSize );
|
|
else
|
|
lpMsgBuffer = GlobalReAllocPtr( lpMsgBuffer, dwRequiredSize, 0 );
|
|
|
|
if( NULL == lpMsgBuffer)
|
|
return DPERR_NOMEMORY;
|
|
|
|
dwBufferSize = dwRequiredSize;
|
|
hr = S_OK;
|
|
}
|
|
else if( SUCCEEDED(hr) && dwRequiredSize >= sizeof(DPLMSG_GENERIC) )
|
|
{
|
|
// Decode the message
|
|
|
|
// Are we just looking for the CONNECTIONSETTINGS msg?
|
|
if( dwMode == LMR_CONNECTIONSETTINGS )
|
|
{
|
|
if( (dwMsgFlags & DPLMSG_SYSTEM) &&
|
|
((DPLMSG_GENERIC*)lpMsgBuffer)->dwType ==
|
|
DPLSYS_NEWCONNECTIONSETTINGS )
|
|
break;
|
|
else
|
|
TRACE(_T("Non CONNECTIONSETTINGS lobby message ignored\n"));
|
|
}
|
|
|
|
// Otherwise we handle only GetProperty responses
|
|
else if( (dwMsgFlags & DPLMSG_STANDARD) &&
|
|
((DPLMSG_GENERIC*)lpMsgBuffer)->dwType ==
|
|
DPLSYS_GETPROPERTYRESPONSE )
|
|
{
|
|
DPLMSG_GETPROPERTYRESPONSE* lpMsgGPR =
|
|
(DPLMSG_GETPROPERTYRESPONSE*)lpMsgBuffer;
|
|
if( IsEqualGUID( lpMsgGPR->guidPropertyTag,
|
|
DPLPROPERTY_MessagesSupported ) )
|
|
{
|
|
if( (BOOL)lpMsgGPR->dwPropertyData[0] ) // Supported
|
|
{
|
|
// So request our player instance guid
|
|
DPLMSG_GETPROPERTY msgGetProp;
|
|
ZeroMemory(&msgGetProp, sizeof(DPLMSG_GETPROPERTY));
|
|
msgGetProp.dwType = DPLSYS_GETPROPERTY;
|
|
msgGetProp.dwRequestID = 2;
|
|
// guidPlayer is left NULL
|
|
msgGetProp.guidPropertyTag = DPLPROPERTY_PlayerGuid;
|
|
hr = g_pDPLobby->SendLobbyMessage( DPLMSG_STANDARD, 0,
|
|
&msgGetProp,
|
|
sizeof(DPLMSG_GETPROPERTY) );
|
|
hr = S_OK; // keep fetching messages
|
|
}
|
|
else // not supported so close up shop
|
|
{
|
|
TRACE(_T("Lobby Messages not supported\n"));
|
|
DPLobbyRelease();
|
|
break;
|
|
}
|
|
}
|
|
else if( IsEqualGUID( lpMsgGPR->guidPropertyTag,
|
|
DPLPROPERTY_PlayerGuid ) )
|
|
{
|
|
// Have our player guid, ready to send property msgs
|
|
g_guidPlayer = ( (DPLDATA_PLAYERGUID*)
|
|
&lpMsgGPR->dwPropertyData)->guidPlayer;
|
|
g_bLobbyMsgSupported = TRUE;
|
|
}
|
|
}
|
|
else
|
|
TRACE(_T("Unrecognized lobby message ignored\n"));
|
|
}
|
|
}
|
|
|
|
if( lpMsgBuffer )
|
|
GlobalFreePtr( lpMsgBuffer );
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Name: LobbyMessageSetProperty()
|
|
// Desc: Send a SetProperty message
|
|
//-----------------------------------------------------------------------------
|
|
HRESULT LobbyMessageSetProperty( const GUID* pPropTagGUID, VOID* pData,
|
|
DWORD dwDataSize )
|
|
{
|
|
HRESULT hr;
|
|
LPBYTE lpBuffer;
|
|
LPDPLMSG_SETPROPERTY lpMsgSP;
|
|
DWORD dwMsgSize;
|
|
|
|
if( NULL == g_pDPLobby )
|
|
return DPERR_NOCONNECTION;
|
|
if( NULL == g_bLobbyMsgSupported )
|
|
return DPERR_UNAVAILABLE;
|
|
|
|
// Allocate and pack up the message
|
|
// Property data starts at dwPropertyData[0] for the size calculation
|
|
dwMsgSize = sizeof(DPLMSG_SETPROPERTY) - sizeof(DWORD) + dwDataSize;
|
|
lpBuffer = (LPBYTE)GlobalAllocPtr(GHND, dwMsgSize);
|
|
if( NULL == lpBuffer )
|
|
return (DPERR_NOMEMORY);
|
|
lpMsgSP = (LPDPLMSG_SETPROPERTY)lpBuffer;
|
|
lpMsgSP->dwType = DPLSYS_SETPROPERTY;
|
|
lpMsgSP->dwRequestID = DPL_NOCONFIRMATION;
|
|
lpMsgSP->guidPlayer = g_guidPlayer; // player property assumed
|
|
lpMsgSP->guidPropertyTag = (*pPropTagGUID);
|
|
lpMsgSP->dwDataSize = dwDataSize;
|
|
memcpy( lpMsgSP->dwPropertyData, pData, dwDataSize );
|
|
hr = g_pDPLobby->SendLobbyMessage( DPLMSG_STANDARD, 0, lpBuffer, dwMsgSize );
|
|
|
|
GlobalFreePtr( lpBuffer );
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
|