2243 lines
62 KiB
C++
2243 lines
62 KiB
C++
// =================================================================
|
|
//
|
|
// Direct Play Network Methods
|
|
//
|
|
// Functions to manage communications over a network.
|
|
//
|
|
//
|
|
// =================================================================
|
|
#ifndef WIN32_LEAN_AND_MEAN
|
|
#define WIN32_LEAN_AND_MEAN
|
|
#endif
|
|
#include <windows.h>
|
|
#include <windowsx.h>
|
|
#include <winsock.h>
|
|
#ifndef _MT
|
|
#define _MT
|
|
#endif
|
|
#include <process.h>
|
|
#include <string.h>
|
|
|
|
#include "dpspimp.h"
|
|
#include "logit.h"
|
|
|
|
#include "tapicode.h"
|
|
#include "commcode.h"
|
|
#include "resource.h"
|
|
|
|
extern volatile BOOL g_bIgnoreReads;
|
|
extern volatile BOOL g_bRecovery;
|
|
extern volatile BOOL g_bCommStarted;
|
|
|
|
extern "C" HINSTANCE hInst;
|
|
extern volatile DWORD g_dwRate;
|
|
extern BOOL g_bCallCancel;
|
|
|
|
|
|
#define malloc(a) LocalAlloc(LMEM_FIXED, (a))
|
|
#define free(a) LocalFree((HLOCAL)(a))
|
|
|
|
|
|
CImpIDP_SP *pDirectPlayObject = NULL; // We only allow one object
|
|
// to be created currently - see below.
|
|
|
|
|
|
HANDLE hOnlyOneAllowed = NULL;
|
|
|
|
extern CImpIDP_SP *g_IDP;
|
|
|
|
extern BOOL CreateQueue(DWORD dwElements, DWORD dwMaxMsg, DWORD dwMaxPlayers);
|
|
extern BOOL DeleteQueue();
|
|
|
|
GUID DPLAY_MODEM = { /* 8cab4652-b1b6-11ce-920c-00aa006c4972 */
|
|
0x8cab4652,
|
|
0xb1b6,
|
|
0x11ce,
|
|
{0x92, 0x0c, 0x00, 0xaa, 0x00, 0x6c, 0x49, 0x72}
|
|
};
|
|
|
|
|
|
BOOL g_bPostHangup = FALSE;
|
|
DWORD WINAPI StartTapiThreadProc(LPVOID lpvParam)
|
|
{
|
|
HANDLE hEvent = (LPHANDLE) lpvParam;
|
|
MSG msg;
|
|
CImpIDP_SP *pIDP = NULL;
|
|
BOOL bShutdown = FALSE;
|
|
|
|
if (hEvent == NULL)
|
|
return(0);
|
|
|
|
if (! InitializeTAPI(NULL))
|
|
return(NULL);
|
|
|
|
SetEvent(hEvent);
|
|
while(!bShutdown && GetMessage(&msg, NULL, 0, 0) )
|
|
{
|
|
switch (msg.message)
|
|
{
|
|
case PWM_SETIDP:
|
|
pIDP = (CImpIDP_SP *) msg.wParam;
|
|
break;
|
|
|
|
case PWM_CLOSE:
|
|
TSHELL_INFO(TEXT("Close requested."));
|
|
bShutdown = TRUE;
|
|
break;
|
|
|
|
case PWM_HANGUP:
|
|
TSHELL_INFO(TEXT("Hangup Requested"));
|
|
pIDP->m_bConnected = FALSE;
|
|
pIDP->m_bPlayer0 = FALSE;
|
|
g_bIgnoreReads = FALSE;
|
|
pIDP->DeleteRemotePlayers();
|
|
pIDP->ResetSessionDesc();
|
|
|
|
if (!HangupCallI())
|
|
{
|
|
TSHELL_INFO(TEXT("HangupCall failed."));
|
|
bShutdown = TRUE;
|
|
}
|
|
g_bPostHangup = FALSE;
|
|
TSHELL_INFO(TEXT("Hangup Finished."));
|
|
break;
|
|
|
|
default:
|
|
TranslateMessage(&msg);
|
|
DispatchMessage(&msg);
|
|
break;
|
|
}
|
|
}
|
|
TSHELL_INFO( TEXT("Exit StartThreadTapi Loop. "));
|
|
ShutdownTAPI();
|
|
TSHELL_INFO(TEXT("StartThreadTapi exits."));
|
|
return(0);
|
|
|
|
}
|
|
|
|
//
|
|
// FUNCTION: PostHangupCall()
|
|
//
|
|
// PURPOSE: Posts a message to the main TAPI thread to hangup the call.
|
|
//
|
|
// PARAMETERS:
|
|
// none
|
|
//
|
|
// RETURN VALUE:
|
|
// none
|
|
//
|
|
// COMMENTS:
|
|
//
|
|
// TAPI is thread specific, meaning that only the thread that does the
|
|
// lineInitialize can get asynchronous messages through the callback.
|
|
// Since the HangupCall can potentially go into a loop waiting for
|
|
// specific events, any other threads that call HangupCall can cause
|
|
// timing confusion. Best to just have other threads 'ask' the main thread
|
|
// to hangup the call.
|
|
//
|
|
|
|
void PostHangupCall()
|
|
{
|
|
|
|
if (g_IDP)
|
|
g_IDP->PostHangup();
|
|
else
|
|
HangupCall(__LINE__);
|
|
}
|
|
|
|
HRESULT CImpIDP_SP::Initialize(LPGUID lpiid)
|
|
{
|
|
TSHELL_INFO(TEXT("Already Initialized."));
|
|
return(DPERR_ALREADYINITIALIZED);
|
|
}
|
|
|
|
void *CImpIDP_SP::operator new( size_t size )
|
|
{
|
|
return(LocalAlloc(LMEM_FIXED, size));
|
|
}
|
|
void CImpIDP_SP::operator delete( void *ptr )
|
|
{
|
|
LocalFree((HLOCAL)ptr);
|
|
}
|
|
|
|
|
|
|
|
|
|
VOID CImpIDP_SP::PostHangup()
|
|
{
|
|
g_bPostHangup = TRUE;
|
|
if (m_dwTapiThreadID)
|
|
PostThreadMessage( m_dwTapiThreadID, PWM_HANGUP, 0, 0);
|
|
|
|
}
|
|
CImpIDP_SP *CImpIDP_SP::NewCImpIDP_SP()
|
|
{
|
|
CImpIDP_SP *pImp = NULL;
|
|
HANDLE hEvent = NULL;
|
|
HANDLE hTapiThread = NULL;
|
|
DWORD dwTapiThreadID;
|
|
DWORD dwRet1;
|
|
DWORD dwRet2;
|
|
|
|
g_bIgnoreReads = FALSE;
|
|
|
|
if (g_IDP)
|
|
return(NULL);
|
|
|
|
if (!CreateQueue(64, MAX_MSG, MAX_PLAYERS))
|
|
{
|
|
TSHELL_INFO(TEXT("Couldn't initialize queue."));
|
|
return(NULL);
|
|
}
|
|
|
|
hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
|
|
|
if (!hEvent)
|
|
return(NULL);
|
|
|
|
pImp = new CImpIDP_SP;
|
|
|
|
if (!pImp)
|
|
return(NULL);
|
|
|
|
hTapiThread = CreateThread(NULL, 0, StartTapiThreadProc,
|
|
(LPVOID) hEvent, 0, &dwTapiThreadID);
|
|
|
|
if (!hTapiThread)
|
|
{
|
|
delete pImp;
|
|
return(NULL);
|
|
}
|
|
|
|
dwRet1 = WaitForSingleObject(hEvent, 10000);
|
|
|
|
CloseHandle(hEvent);
|
|
|
|
dwRet2 = WaitForSingleObject(hTapiThread, 0);
|
|
|
|
if (dwRet1 == WAIT_TIMEOUT || dwRet2 != WAIT_TIMEOUT)
|
|
{
|
|
if (dwRet2 == WAIT_TIMEOUT)
|
|
{
|
|
TerminateThread(hTapiThread, 0);
|
|
Sleep(200);
|
|
}
|
|
CloseHandle(hTapiThread);
|
|
delete pImp;
|
|
return(NULL);
|
|
}
|
|
|
|
|
|
PostThreadMessage( dwTapiThreadID, PWM_SETIDP, (WPARAM) pImp, 0);
|
|
pImp->m_dpcaps.dwMaxBufferSize = 512;
|
|
pImp->m_hTapiThread = hTapiThread;
|
|
pImp->m_dwTapiThreadID = dwTapiThreadID;
|
|
g_IDP = pImp;
|
|
|
|
|
|
|
|
|
|
return(pImp);
|
|
}
|
|
|
|
|
|
// ----------------------------------------------------------
|
|
// CreateNewDirectPlay - DCO object creation entry point
|
|
// called by the DCO interface functions to create a new
|
|
// DCO object.
|
|
// ----------------------------------------------------------
|
|
IDirectPlaySP * _cdecl CreateNewDirectPlay( LPGUID lpGuid )
|
|
{
|
|
//
|
|
// One object at a time, please.
|
|
//
|
|
if (pDirectPlayObject != NULL || hOnlyOneAllowed != NULL)
|
|
return(NULL);
|
|
|
|
hOnlyOneAllowed = CreateEvent(NULL, TRUE, TRUE, "DPSERIAL_UNIQUE");
|
|
if (hOnlyOneAllowed == NULL)
|
|
return(NULL);
|
|
else
|
|
{
|
|
if (GetLastError() == ERROR_ALREADY_EXISTS)
|
|
{
|
|
TSHELL_INFO(TEXT("Someone tried to run 2 modems!"));
|
|
CloseHandle(hOnlyOneAllowed);
|
|
hOnlyOneAllowed = NULL;
|
|
return(NULL);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
if (! IsEqualGUID((REFGUID) DPLAY_MODEM, (REFGUID) *lpGuid))
|
|
return(NULL);
|
|
|
|
//
|
|
// The network service provider doesn't support more than 1
|
|
// Guid, so we do nothing.
|
|
//
|
|
lpGuid;
|
|
|
|
pDirectPlayObject = CImpIDP_SP::NewCImpIDP_SP();
|
|
|
|
if (!pDirectPlayObject)
|
|
return(NULL);
|
|
else
|
|
return(pDirectPlayObject);
|
|
}
|
|
|
|
|
|
// Begin: IUnknown interface implementation
|
|
HRESULT CImpIDP_SP::QueryInterface(
|
|
REFIID iid,
|
|
LPVOID *ppvObj
|
|
)
|
|
{
|
|
HRESULT retVal = DPERR_GENERIC;
|
|
|
|
//
|
|
// BUGBUG
|
|
//
|
|
if (ppvObj && ! IsBadWritePtr(ppvObj, 4))
|
|
{
|
|
AddRef();
|
|
*ppvObj = this;
|
|
return(DP_OK);
|
|
}
|
|
else
|
|
return(DPERR_INVALIDPARAM);
|
|
|
|
}
|
|
|
|
ULONG CImpIDP_SP::AddRef( void)
|
|
{
|
|
ULONG newRefCount;
|
|
|
|
Lock();
|
|
m_refCount++;
|
|
newRefCount = m_refCount;
|
|
Unlock();
|
|
|
|
DBG_INFO((DBGARG, TEXT("newRefCount = %lu"), newRefCount));
|
|
|
|
return( newRefCount );
|
|
}
|
|
|
|
ULONG CImpIDP_SP::Release( void )
|
|
{
|
|
ULONG newRefCount;
|
|
DWORD ii;
|
|
DWORD dwTime = 0;
|
|
|
|
#ifdef DEBUG
|
|
DWORD dwTickCount = GetTickCount();
|
|
#endif
|
|
|
|
Lock();
|
|
m_refCount--;
|
|
newRefCount = m_refCount;
|
|
Unlock();
|
|
|
|
if (newRefCount == 0)
|
|
{
|
|
Close(DPLAY_CLOSE_INTERNAL);
|
|
|
|
if (m_dwTapiThreadID && m_hTapiThread)
|
|
{
|
|
while (m_hTapiThread && dwTime < 4000)
|
|
{
|
|
PostThreadMessage( m_dwTapiThreadID, PWM_CLOSE, 0, 0);
|
|
if (WaitForSingleObject(m_hTapiThread, 100) == WAIT_TIMEOUT)
|
|
{
|
|
dwTime += 100;
|
|
}
|
|
else
|
|
{
|
|
CloseHandle(m_hTapiThread);
|
|
m_hTapiThread = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (m_ppSessionArray)
|
|
{
|
|
for (ii = 0; ii < m_dwSessionPrev; ii++)
|
|
free(m_ppSessionArray[ii]);
|
|
free(m_ppSessionArray);
|
|
}
|
|
|
|
if (m_hTapiThread && WaitForSingleObject(m_hTapiThread, 100) == WAIT_TIMEOUT)
|
|
{
|
|
TSHELL_INFO(TEXT("Terminate Thread."));
|
|
TerminateThread(m_hTapiThread, 0);
|
|
Sleep(200);
|
|
CloseHandle(m_hTapiThread);
|
|
}
|
|
|
|
DeleteCriticalSection(&m_critSection);
|
|
DeleteQueue();
|
|
g_IDP = NULL;
|
|
|
|
hInst = NULL;
|
|
pDirectPlayObject = NULL;
|
|
|
|
DBG_INFO((DBGARG, TEXT("Total close time %d"), GetTickCount() - dwTickCount));
|
|
|
|
delete this;
|
|
pDirectPlayObject = NULL;
|
|
CloseHandle(hOnlyOneAllowed);
|
|
hOnlyOneAllowed = NULL;
|
|
}
|
|
|
|
DBG_INFO((DBGARG, TEXT("newRefCount = %lu"), newRefCount));
|
|
|
|
return( newRefCount );
|
|
}
|
|
|
|
// End : IUnknown interface implementation
|
|
|
|
|
|
// ----------------------------------------------------------
|
|
// CImpIDP_SP constructor - create a new DCO object
|
|
// along with a queue of receive buffers.
|
|
// ----------------------------------------------------------
|
|
CImpIDP_SP::CImpIDP_SP()
|
|
{
|
|
m_bConnected = FALSE;
|
|
m_bPlayer0 = FALSE;
|
|
m_dwPendingWrites = 0;
|
|
|
|
m_dwPingSent = 0;
|
|
m_hBlockingEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
|
m_dwNextPlayer = 1;
|
|
m_bEnablePlayerAdd = TRUE;
|
|
|
|
memset(&m_aPlayer[0], 0x00, sizeof(PLAYER_RECORD) * MAX_PLAYERS);
|
|
m_lpDisplay[0] = 0x00;
|
|
m_lpDialable[0] = 0x00;
|
|
m_dwID = 0;
|
|
m_iPlayerIndex = -1;
|
|
memset(&m_dpDesc, 0x00, sizeof(DPSESSIONDESC));
|
|
|
|
// Initialize ref count
|
|
m_refCount = 1;
|
|
InitializeCriticalSection( &m_critSection );
|
|
memset(&m_dpcaps, 0x00, sizeof(DPCAPS));
|
|
m_dpcaps.dwSize = sizeof(DPCAPS);
|
|
m_dpcaps.dwFlags = 0;
|
|
m_dpcaps.dwMaxQueueSize = 64;
|
|
m_dpcaps.dwMaxPlayers = MAX_PLAYERS;
|
|
m_dpcaps.dwHundredBaud = 0;
|
|
|
|
m_hNewPlayerEvent = NULL;
|
|
m_hTapiThread = NULL;
|
|
m_dwTapiThreadID = 0;
|
|
m_ppSessionArray = 0;
|
|
m_dwSessionPrev = 0;
|
|
m_dwSessionAlloc = 0;
|
|
|
|
}
|
|
|
|
// ----------------------------------------------------------
|
|
// CImpDirectPlay destructor -
|
|
// ----------------------------------------------------------
|
|
CImpIDP_SP::~CImpIDP_SP()
|
|
{
|
|
TSHELL_INFO(TEXT("Deletion."));
|
|
}
|
|
|
|
|
|
void CImpIDP_SP::Lock( void )
|
|
{
|
|
EnterCriticalSection( &m_critSection );
|
|
}
|
|
|
|
void CImpIDP_SP::Unlock( void )
|
|
{
|
|
LeaveCriticalSection( &m_critSection );
|
|
}
|
|
|
|
|
|
// ----------------------------------------------------------
|
|
// GetCaps - return info about the connection media
|
|
// ----------------------------------------------------------
|
|
|
|
//
|
|
// Return our caps immediately if we have a valid latency value.
|
|
// if we haven't gotten latency yet, send a DPSYS_PING. Latency is
|
|
// the time it takes to get a response DPSYS_PING / 2.
|
|
//
|
|
HRESULT CImpIDP_SP::GetCaps(
|
|
LPDPCAPS lpDPCaps // buffer to receive capabilities
|
|
)
|
|
{
|
|
m_dpcaps.dwHundredBaud = g_dwRate / 100;
|
|
*lpDPCaps = m_dpcaps;
|
|
|
|
if (m_dpcaps.dwLatency == 0)
|
|
SendPing();
|
|
|
|
return(DP_OK);
|
|
}
|
|
|
|
|
|
// ----------------------------------------------------------
|
|
// Connect - establishes communications with underlying transport,
|
|
// and initializes name services and network entities
|
|
// ----------------------------------------------------------
|
|
BOOL CImpIDP_SP::SetSession(DWORD dw)
|
|
{
|
|
m_lpDisplay[0] = 0x00;
|
|
if (dw == 0)
|
|
{
|
|
m_lpDialable[0] = 0x00;
|
|
return(TRUE);
|
|
}
|
|
else
|
|
{
|
|
dw--;
|
|
if (dw >= m_dwSessionPrev)
|
|
return(FALSE);
|
|
lstrcpy( m_lpDialable, (m_ppSessionArray[dw] + sizeof(dw)));
|
|
lstrcpy( m_lpDisplay, (m_ppSessionArray[dw] + sizeof(dw)));
|
|
|
|
DBG_INFO((DBGARG, TEXT("Got %s for dialable string."), m_lpDialable));
|
|
|
|
return(TRUE);
|
|
}
|
|
}
|
|
|
|
HRESULT CImpIDP_SP::Open(
|
|
LPDPSESSIONDESC lpSDesc, HANDLE lpHandle
|
|
)
|
|
{
|
|
DWORD ii;
|
|
SPMSG_CONNECT *pMsg;
|
|
|
|
TSHELL_INFO(TEXT("SP Open"));
|
|
|
|
for (ii = 0; ii < MAX_PLAYERS; ii++)
|
|
{
|
|
if (m_aPlayer[ii].bValid )
|
|
{
|
|
TSHELL_INFO(TEXT("Illegal player found, return error."));
|
|
return(DPERR_ACTIVEPLAYERS);
|
|
}
|
|
}
|
|
|
|
if (lpSDesc->dwFlags & DPOPEN_CREATESESSION)
|
|
{
|
|
TSHELL_INFO(TEXT("Place machine in Recieve mode."));
|
|
|
|
if (ReceiveCall())
|
|
{
|
|
m_bPlayer0 = TRUE;
|
|
memcpy( (LPVOID) &m_dpDesc, lpSDesc, sizeof(DPSESSIONDESC));
|
|
m_dpDesc.dwCurrentPlayers = 0;
|
|
m_dpDesc.dwReserved1 = 0;
|
|
m_dpDesc.dwReserved2 = 0;
|
|
|
|
return(DP_OK);
|
|
}
|
|
else
|
|
return(DPERR_GENERIC);
|
|
|
|
}
|
|
else if (lpSDesc->dwFlags & DPOPEN_OPENSESSION)
|
|
{
|
|
TSHELL_INFO(TEXT("Open a session."));
|
|
if (!SetSession(lpSDesc->dwSession))
|
|
return(DPERR_GENERIC);
|
|
|
|
|
|
TSHELL_INFO(TEXT("Dial call."));
|
|
|
|
g_bIgnoreReads = TRUE;
|
|
|
|
ResetEvent(m_hBlockingEvent);
|
|
|
|
if (DialCall(m_lpDisplay, m_lpDialable, &m_dwID, m_hBlockingEvent))
|
|
{
|
|
TSHELL_INFO(TEXT("DialCall Succeeded."));
|
|
|
|
if ( WaitForSingleObject(m_hBlockingEvent, 60000) == WAIT_TIMEOUT
|
|
|| !g_bCommStarted)
|
|
{
|
|
TSHELL_INFO(TEXT("Timeout waiting for connection."));
|
|
return(DPERR_NOCONNECTION);
|
|
}
|
|
|
|
TSHELL_INFO(TEXT("No messages sent yet."));
|
|
Sleep(1000);
|
|
g_bIgnoreReads = FALSE;
|
|
TSHELL_INFO(TEXT("Now try and connect."));
|
|
ResetEvent(m_hBlockingEvent);
|
|
//
|
|
// Send connection protocol messages.
|
|
//
|
|
for (ii = 0; (ii < 10)
|
|
&& !m_bConnected
|
|
&& !g_bRecovery
|
|
&& g_bCommStarted; ii++)
|
|
{
|
|
pMsg = (SPMSG_CONNECT *) malloc(sizeof(SPMSG_CONNECT));
|
|
pMsg->dpHdr.to = 0;
|
|
pMsg->dpHdr.from = 0;
|
|
pMsg->dpHdr.usCount = sizeof(SPMSG_CONNECT) - sizeof(DPHDR);
|
|
pMsg->dpHdr.usCookie = SPSYS_CONNECT;
|
|
pMsg->usVerMajor = DPVERSION_MAJOR;
|
|
pMsg->usVerMinor = DPVERSION_MINOR;
|
|
pMsg->dwConnect1 = DPSYS_KYRA;
|
|
pMsg->dwConnect2 = DPSYS_HALL;
|
|
// TSHELL_INFO(TEXT("Write Connection Msg."));
|
|
g_bIgnoreReads = FALSE;
|
|
WriteCommString( (LPVOID) pMsg, sizeof(SPMSG_CONNECT));
|
|
WaitForSingleObject(m_hBlockingEvent, 6000);
|
|
if (g_bRecovery)
|
|
{
|
|
TSHELL_INFO(TEXT("Open Generated recovery problem."));
|
|
ResetEvent(m_hBlockingEvent);
|
|
WaitForSingleObject(m_hBlockingEvent, 10000);
|
|
}
|
|
if (g_bRecovery)
|
|
{
|
|
TSHELL_INFO(TEXT("Open Still has recovery problem, give up."));
|
|
}
|
|
|
|
}
|
|
|
|
if (m_bConnected && m_dpDesc.dwMaxPlayers != 0)
|
|
{
|
|
TSHELL_INFO(TEXT("Connection Made."));
|
|
DBG_INFO((DBGARG, TEXT("Current Players. %d"), m_dpDesc.dwCurrentPlayers));
|
|
SendPing();
|
|
return(DP_OK);
|
|
}
|
|
else
|
|
{
|
|
TSHELL_INFO(TEXT("Connection timed out"));
|
|
Close(0);
|
|
return(DPERR_NOCONNECTION);
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
if (g_bCallCancel)
|
|
return(DPERR_USERCANCEL);
|
|
|
|
TSHELL_INFO(TEXT("DialCall failed."));
|
|
return(DPERR_GENERIC);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
TSHELL_INFO(TEXT("Unhandled Open flags."));
|
|
return(DPERR_UNSUPPORTED);
|
|
}
|
|
}
|
|
|
|
|
|
// ----------------------------------------------------------
|
|
// CreatePlayer - registers new player, N.B. may fail if
|
|
// not currently connected to name server
|
|
// ----------------------------------------------------------
|
|
LONG CImpIDP_SP::FindInvalidIndex()
|
|
{
|
|
DWORD ii;
|
|
|
|
for (ii = 0; ii < MAX_PLAYERS; ii++)
|
|
if (m_aPlayer[ii].bValid == FALSE)
|
|
return(ii);
|
|
|
|
return(-1);
|
|
}
|
|
VOID CImpIDP_SP::LocalMsg(LONG iIndex, LPVOID lpv, DWORD dwSize)
|
|
{
|
|
|
|
LONG ii;
|
|
|
|
for (ii = 0; ii < MAX_PLAYERS; ii++)
|
|
if ( ii != iIndex
|
|
&& m_aPlayer[ii].bValid
|
|
&& m_aPlayer[ii].bLocal
|
|
&& m_aPlayer[ii].bPlayer)
|
|
AddMessage(lpv, dwSize, m_aPlayer[ii].pid, 0, 0);
|
|
|
|
}
|
|
VOID CImpIDP_SP::RemoteMsg(LONG iIndex, LPVOID lpv, DWORD dwSize)
|
|
{
|
|
SPMSG_GENERIC *pMsg;
|
|
DWORD dwTotal = dwSize + sizeof(DPHDR);
|
|
|
|
pMsg = (SPMSG_GENERIC *) malloc(dwTotal);
|
|
if (pMsg)
|
|
{
|
|
pMsg->dpHdr.usCookie = SPSYS_SYS;
|
|
pMsg->dpHdr.to = 0;
|
|
pMsg->dpHdr.from = 0;
|
|
pMsg->dpHdr.usCount = (USHORT) dwSize;
|
|
memcpy( (LPVOID) &pMsg->sMsg, lpv, dwSize);
|
|
WriteCommString( (LPVOID) pMsg, dwTotal);
|
|
}
|
|
}
|
|
|
|
extern BOOL SetupLocalPlayer(DPID pid, HANDLE hEvent);
|
|
HRESULT CImpIDP_SP::CreatePlayer(
|
|
LPDPID pPlayerID,
|
|
LPSTR pNickName,
|
|
LPSTR pFullName,
|
|
LPHANDLE lpReceiveEvent,
|
|
BOOL bPlayer
|
|
)
|
|
{
|
|
DWORD ii, jj;
|
|
SPMSG_ADDPLAYER *pMsg;
|
|
HANDLE hEvent = NULL;
|
|
BOOL bb = TRUE;
|
|
HRESULT hr = DP_OK;
|
|
LONG iIndex;
|
|
DPMSG_ADDPLAYER dpAdd;
|
|
|
|
// TSHELL_INFO(TEXT("Enter Create Player"));
|
|
|
|
if (m_dwNextPlayer > MAXIMUM_PLAYER_ID)
|
|
{
|
|
return(DPERR_CANTCREATEPLAYER);
|
|
}
|
|
|
|
if (m_bConnected == FALSE)
|
|
if (m_bPlayer0 != TRUE)
|
|
return(DPERR_NOCONNECTION);
|
|
|
|
if (m_bEnablePlayerAdd == FALSE && bPlayer == TRUE)
|
|
return(DPERR_CANTCREATEPLAYER);
|
|
|
|
if (m_dpDesc.dwMaxPlayers == m_dpDesc.dwCurrentPlayers)
|
|
{
|
|
DBG_INFO((DBGARG, TEXT("CreatePlayer: at max players already. %d"),
|
|
m_dpDesc.dwMaxPlayers));
|
|
return(DPERR_CANTADDPLAYER);
|
|
}
|
|
|
|
if (m_iPlayerIndex != -1)
|
|
{
|
|
TSHELL_INFO(TEXT("Player index not -1, create already in progress."));
|
|
return(DPERR_GENERIC);
|
|
}
|
|
|
|
iIndex = FindInvalidIndex();
|
|
if (iIndex == -1)
|
|
return(DPERR_GENERIC);
|
|
|
|
if (m_hNewPlayerEvent)
|
|
return(DPERR_GENERIC);
|
|
|
|
if (!(hEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
|
|
{
|
|
TSHELL_INFO(TEXT("CreatePlayer: CreateEvent failure."));
|
|
return(DPERR_GENERIC);
|
|
}
|
|
else
|
|
{
|
|
; // DBG_INFO((DBGARG, TEXT("CreatePlayer %8x Event"), hEvent));
|
|
}
|
|
|
|
|
|
dpAdd.dwType = DPSYS_ADDPLAYER;
|
|
dpAdd.dwPlayerType = bPlayer;
|
|
dpAdd.dpId = 0;
|
|
lstrcpy( dpAdd.szShortName, pNickName);
|
|
lstrcpy( dpAdd.szLongName , pFullName);
|
|
|
|
if (m_bPlayer0)
|
|
{
|
|
m_dpDesc.dwCurrentPlayers++;
|
|
m_aPlayer[iIndex].pid = (DPID) m_dwNextPlayer++;
|
|
lstrcpy( m_aPlayer[iIndex].chNickName, pNickName);
|
|
lstrcpy( m_aPlayer[iIndex].chFullName, pFullName);
|
|
m_aPlayer[iIndex].bValid = TRUE;
|
|
m_aPlayer[iIndex].bPlayer = bPlayer;
|
|
m_aPlayer[iIndex].hEvent = hEvent;
|
|
m_aPlayer[iIndex].bLocal = TRUE;
|
|
for (ii = 0; ii < MAX_PLAYERS; ii++)
|
|
m_aPlayer[iIndex].aGroup[ii] = 0;
|
|
|
|
|
|
dpAdd.dpId = m_aPlayer[iIndex].pid;
|
|
|
|
LocalMsg( iIndex, (LPVOID) &dpAdd, sizeof(DPMSG_ADDPLAYER));
|
|
RemoteMsg(iIndex, (LPVOID) &dpAdd, sizeof(DPMSG_ADDPLAYER));
|
|
hEvent = NULL;
|
|
*pPlayerID = (DPID) (0x0000ffff & m_aPlayer[iIndex].pid);
|
|
if (lpReceiveEvent)
|
|
*lpReceiveEvent = m_aPlayer[iIndex].hEvent;
|
|
SetupLocalPlayer(m_aPlayer[iIndex].pid, m_aPlayer[iIndex].hEvent);
|
|
return(DP_OK);
|
|
}
|
|
|
|
m_hNewPlayerEvent = hEvent;
|
|
for (jj = 0; jj < 3; jj++)
|
|
{
|
|
pMsg = (SPMSG_ADDPLAYER *) malloc(sizeof(SPMSG_ADDPLAYER));
|
|
if (pMsg)
|
|
{
|
|
TSHELL_INFO(TEXT("Prepare AddPlayer message"));
|
|
pMsg->dpHdr.usCookie = SPSYS_SYS;
|
|
pMsg->dpHdr.to = 0;
|
|
pMsg->dpHdr.from = 0;
|
|
pMsg->dpHdr.usCount = SIZE_ADDPLAYER;
|
|
memcpy( (LPVOID) &pMsg->sMsg, &dpAdd, sizeof(DPMSG_ADDPLAYER));
|
|
WriteCommString( (LPVOID) pMsg, sizeof(SPMSG_ADDPLAYER));
|
|
pMsg = NULL;
|
|
|
|
if (WaitForSingleObject(m_hNewPlayerEvent, 4500) != WAIT_TIMEOUT);
|
|
{
|
|
if (m_iPlayerIndex != -1)
|
|
{
|
|
SetupLocalPlayer(m_aPlayer[m_iPlayerIndex].pid, m_hNewPlayerEvent);
|
|
m_aPlayer[m_iPlayerIndex].hEvent = m_hNewPlayerEvent;
|
|
if (lpReceiveEvent)
|
|
*lpReceiveEvent = m_aPlayer[m_iPlayerIndex].hEvent;
|
|
m_hNewPlayerEvent = NULL;
|
|
*pPlayerID = (DPID) (0x0000ffff & m_aPlayer[m_iPlayerIndex].pid);
|
|
m_iPlayerIndex = -1;
|
|
|
|
return(DP_OK);
|
|
}
|
|
}
|
|
|
|
ResetEvent(m_hNewPlayerEvent);
|
|
}
|
|
else
|
|
{
|
|
hr = DPERR_NOMEMORY;
|
|
goto abort;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
hr = DPERR_CANTADDPLAYER;
|
|
|
|
|
|
abort:
|
|
m_hNewPlayerEvent = NULL;
|
|
|
|
if (pMsg)
|
|
LocalFree((HLOCAL) pMsg);
|
|
if (hEvent)
|
|
CloseHandle(hEvent);
|
|
|
|
return(hr);
|
|
|
|
}
|
|
|
|
LONG CImpIDP_SP::GetPlayerIndex(DPID playerID)
|
|
{
|
|
DWORD ii;
|
|
DPID pid = 0xffff & ((DPID) playerID);
|
|
|
|
for (ii = 0; ii < MAX_PLAYERS; ii++)
|
|
{
|
|
if (m_aPlayer[ii].bValid)
|
|
if (m_aPlayer[ii].pid == pid)
|
|
return(ii);
|
|
}
|
|
return(-1);
|
|
}
|
|
|
|
|
|
// ----------------------------------------------------------
|
|
// DestroyPlayer
|
|
// ----------------------------------------------------------
|
|
HRESULT CImpIDP_SP::DestroyPlayer( DPID playerID, BOOL bPlayer)
|
|
{
|
|
LONG iIndex;
|
|
DWORD ii, jj;
|
|
|
|
DPMSG_GETPLAYER dpGet;
|
|
|
|
SPMSG_GETPLAYER *pMsg;
|
|
HANDLE hEvent = NULL;
|
|
HRESULT hr = DP_OK;
|
|
|
|
if ((iIndex = GetPlayerIndex(playerID)) == -1)
|
|
return(DPERR_INVALIDPLAYER);
|
|
|
|
if (m_aPlayer[iIndex].bPlayer != bPlayer)
|
|
return(DPERR_INVALIDPLAYER);
|
|
|
|
|
|
if (bPlayer)
|
|
{
|
|
dpGet.dwType = DPSYS_DELETEPLAYER;
|
|
}
|
|
else
|
|
{
|
|
dpGet.dwType = DPSYS_DELETEGROUP;
|
|
}
|
|
|
|
m_dpDesc.dwCurrentPlayers--;
|
|
dpGet.dpId = m_aPlayer[iIndex].pid;
|
|
|
|
if (m_bPlayer0)
|
|
{
|
|
if (m_aPlayer[iIndex].bLocal)
|
|
{
|
|
FlushQueue(playerID);
|
|
CloseHandle(m_aPlayer[iIndex].hEvent);
|
|
}
|
|
m_aPlayer[iIndex].bValid = FALSE;
|
|
LocalMsg(iIndex, (LPVOID) &dpGet, sizeof(DPMSG_GETPLAYER));
|
|
}
|
|
|
|
pMsg = (SPMSG_GETPLAYER *) malloc(sizeof(SPMSG_GETPLAYER));
|
|
if (pMsg)
|
|
{
|
|
pMsg->dpHdr.usCookie = SPSYS_SYS;
|
|
pMsg->dpHdr.to = 0;
|
|
pMsg->dpHdr.from = 0;
|
|
pMsg->dpHdr.usCount = sizeof(DPMSG_GETPLAYER);
|
|
memcpy( (LPVOID) &pMsg->sMsg, (LPVOID) &dpGet, sizeof(DPMSG_GETPLAYER));
|
|
WriteCommString( (LPVOID) pMsg, sizeof(SPMSG_GETPLAYER));
|
|
}
|
|
|
|
|
|
for (ii = 0; ii < MAX_PLAYERS; ii++)
|
|
{
|
|
if ( m_aPlayer[ii].bValid == TRUE
|
|
&& m_aPlayer[ii].bPlayer == FALSE
|
|
&& m_aPlayer[ii].aGroup)
|
|
{
|
|
for (jj = 0; jj < MAX_PLAYERS; jj++)
|
|
{
|
|
if (m_aPlayer[ii].aGroup[jj] == playerID)
|
|
{
|
|
m_aPlayer[ii].aGroup[jj] = 0;
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
return(DP_OK);
|
|
|
|
}
|
|
|
|
|
|
// ----------------------------------------------------------
|
|
// Close - close the connection
|
|
// ----------------------------------------------------------
|
|
HRESULT CImpIDP_SP::Close( DWORD dwFlag)
|
|
{
|
|
DWORD ii;
|
|
|
|
TSHELL_INFO(TEXT("Close Processing."));
|
|
for (ii = 0; ii < MAX_PLAYERS; ii++)
|
|
{
|
|
if (m_aPlayer[ii].bValid)
|
|
{
|
|
m_aPlayer[ii].bValid = FALSE;
|
|
|
|
if (m_aPlayer[ii].bLocal && m_aPlayer[ii].bPlayer)
|
|
{
|
|
FlushQueue(m_aPlayer[ii].pid);
|
|
CloseHandle(m_aPlayer[ii].hEvent);
|
|
}
|
|
}
|
|
}
|
|
|
|
g_bIgnoreReads = FALSE;
|
|
m_bConnected = FALSE;
|
|
m_bPlayer0 = FALSE;
|
|
PostHangup();
|
|
return(DP_OK);
|
|
}
|
|
|
|
// ----------------------------------------------------------
|
|
// GetName -
|
|
// ----------------------------------------------------------
|
|
HRESULT CImpIDP_SP::GetPlayerName(
|
|
DPID dpID,
|
|
LPSTR lpNickName, // buffer to hold name
|
|
LPDWORD pdwNickNameLength, // length of name buffer
|
|
LPSTR lpFullName,
|
|
LPDWORD pdwFullNameLength
|
|
)
|
|
{
|
|
LONG iIndex;
|
|
|
|
HRESULT hr = DP_OK;
|
|
DPID pid = (DPID) dpID;
|
|
|
|
if ((iIndex = GetPlayerIndex(dpID)) != -1)
|
|
{
|
|
lstrcpy( lpNickName, m_aPlayer[iIndex].chNickName);
|
|
lstrcpy( lpFullName, m_aPlayer[iIndex].chFullName);
|
|
*pdwNickNameLength = lstrlen(lpNickName) + 1;
|
|
*pdwFullNameLength = lstrlen(lpFullName) + 1;
|
|
return(DP_OK);
|
|
}
|
|
else
|
|
{
|
|
return(DPERR_INVALIDPID);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
HRESULT CImpIDP_SP::EnumGroupPlayers(
|
|
DPID dwGroupPid,
|
|
LPDPENUMPLAYERSCALLBACK EnumCallback,
|
|
LPVOID pContext,
|
|
DWORD dwFlags)
|
|
{
|
|
|
|
DWORD ii;
|
|
HRESULT hr = DP_OK;
|
|
LONG iIndexG;
|
|
LONG iIndexP;
|
|
DPID pid;
|
|
|
|
iIndexG = GetPlayerIndex(dwGroupPid);
|
|
|
|
if (iIndexG == -1)
|
|
return(DPERR_INVALIDPID);
|
|
|
|
if (m_aPlayer[iIndexG].bPlayer)
|
|
return(DPERR_INVALIDPID);
|
|
|
|
for (ii = 0; ii < MAX_PLAYERS; ii++)
|
|
{
|
|
if ((pid = m_aPlayer[iIndexG].aGroup[ii]) != 0)
|
|
{
|
|
iIndexP = GetPlayerIndex(pid);
|
|
if (iIndexP != -1)
|
|
{
|
|
(EnumCallback)((DPID) m_aPlayer[iIndexP].pid,
|
|
m_aPlayer[iIndexP].chNickName,
|
|
m_aPlayer[iIndexP].chFullName,
|
|
((m_aPlayer[iIndexP].bLocal ) ? DPENUMPLAYERS_LOCAL : DPENUMPLAYERS_REMOTE)
|
|
| ((!m_aPlayer[iIndexP].bPlayer) ? DPENUMPLAYERS_GROUP : 0),
|
|
pContext);
|
|
}
|
|
else
|
|
{
|
|
m_aPlayer[iIndexG].aGroup[ii] = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
return(DP_OK);
|
|
}
|
|
|
|
// ----------------------------------------------------------
|
|
// EnumPlayers - return info on peer connections.
|
|
// ----------------------------------------------------------
|
|
HRESULT CImpIDP_SP::EnumPlayers(
|
|
DWORD dwSessionId,
|
|
LPDPENUMPLAYERSCALLBACK EnumCallback,
|
|
LPVOID pContext,
|
|
DWORD dwFlags)
|
|
{
|
|
|
|
DWORD ii;
|
|
HRESULT hr = DP_OK;
|
|
|
|
if (dwFlags & DPENUMPLAYERS_PREVIOUS)
|
|
{
|
|
return(DPERR_UNSUPPORTED);
|
|
}
|
|
|
|
for (ii = 0; ii < MAX_PLAYERS; ii++)
|
|
if ( m_aPlayer[ii].bValid
|
|
&& ( (m_aPlayer[ii].bPlayer == FALSE && (dwFlags & DPENUMPLAYERS_GROUP))
|
|
|| (m_aPlayer[ii].bPlayer == TRUE && !(dwFlags & DPENUMPLAYERS_NOPLAYERS))))
|
|
{
|
|
if((EnumCallback)((DPID) m_aPlayer[ii].pid,
|
|
m_aPlayer[ii].chNickName,
|
|
m_aPlayer[ii].chFullName,
|
|
((m_aPlayer[ii].bLocal ) ? DPENUMPLAYERS_LOCAL : DPENUMPLAYERS_REMOTE)
|
|
| ((!m_aPlayer[ii].bPlayer) ? DPENUMPLAYERS_GROUP : 0),
|
|
pContext) == FALSE)
|
|
{
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
return(DP_OK);
|
|
}
|
|
|
|
HRESULT CImpIDP_SP::EnumSessions(
|
|
LPDPSESSIONDESC lpSDesc,
|
|
DWORD dwTimeout,
|
|
LPDPENUMSESSIONSCALLBACK EnumCallback,
|
|
LPVOID lpvContext,
|
|
DWORD dwFlags)
|
|
{
|
|
DPSESSIONDESC dpSDesc;
|
|
|
|
|
|
|
|
|
|
|
|
memcpy( &dpSDesc.guidSession, &(lpSDesc->guidSession), sizeof(GUID));
|
|
dpSDesc.dwSession = 0;
|
|
dpSDesc.dwMaxPlayers = MAX_PLAYERS;
|
|
dpSDesc.dwCurrentPlayers = 0;
|
|
dpSDesc.dwFlags = 0;
|
|
dpSDesc.dwSize = sizeof(DPSESSIONDESC);
|
|
LoadString(hInst, IDS_DIALNEW, dpSDesc.szSessionName, sizeof(dpSDesc.szSessionName));
|
|
|
|
EnumCallback( &dpSDesc, lpvContext, NULL, 0);
|
|
|
|
|
|
if (m_dwSessionPrev && dwFlags & DPENUMSESSIONS_PREVIOUS)
|
|
{
|
|
DWORD ii;
|
|
DWORD dw;
|
|
|
|
for (ii = 0; ii < m_dwSessionPrev; ii++)
|
|
{
|
|
dpSDesc.dwSession = ii + 1;
|
|
dw = *((DWORD *)(m_ppSessionArray[ii]));
|
|
lstrcpyn( dpSDesc.szSessionName,
|
|
((m_ppSessionArray[ii]) + sizeof(DWORD) + dw), DPLONGNAMELEN);
|
|
dpSDesc.szSessionName[DPLONGNAMELEN-1] = 0x00;
|
|
EnumCallback( &dpSDesc, lpvContext, NULL, 0);
|
|
}
|
|
}
|
|
|
|
|
|
return(DP_OK);
|
|
}
|
|
|
|
VOID CImpIDP_SP::ISend(
|
|
LONG iFrom,
|
|
LONG iTo,
|
|
DWORD dwFlags,
|
|
LPVOID lpvBuffer,
|
|
DWORD dwBuffSize)
|
|
{
|
|
|
|
MSG_BUILDER *pMsg;
|
|
DWORD ii;
|
|
LONG iIndexT;
|
|
|
|
if (m_aPlayer[iTo].bPlayer == FALSE)
|
|
{
|
|
for (ii = 0; ii < MAX_PLAYERS; ii++)
|
|
{
|
|
if (m_aPlayer[iTo].aGroup[ii])
|
|
if ((iIndexT = GetPlayerIndex(m_aPlayer[iTo].aGroup[ii])) != -1)
|
|
ISend(iFrom, iIndexT, dwFlags, lpvBuffer, dwBuffSize);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (m_aPlayer[iTo].bLocal)
|
|
{
|
|
AddMessage(lpvBuffer,
|
|
dwBuffSize,
|
|
m_aPlayer[iTo].pid,
|
|
m_aPlayer[iFrom].pid,
|
|
dwFlags & DPSEND_HIGHPRIORITY);
|
|
|
|
}
|
|
else
|
|
{
|
|
LPVOID lpv = malloc(sizeof(DPHDR) + dwBuffSize);
|
|
if (!lpv)
|
|
return;
|
|
|
|
// TSHELL_INFO(TEXT("Sending Remote Message."));
|
|
|
|
pMsg = (MSG_BUILDER *) lpv;
|
|
pMsg->dpHdr.usCookie = (dwFlags & DPSEND_HIGHPRIORITY) ? SPSYS_HIGH : SPSYS_USER;
|
|
pMsg->dpHdr.to = (BYTE) m_aPlayer[iTo].pid;
|
|
pMsg->dpHdr.from = (BYTE) m_aPlayer[iFrom].pid;
|
|
pMsg->dpHdr.usCount = (USHORT) dwBuffSize;
|
|
memcpy( pMsg->chMsgCompose, lpvBuffer, dwBuffSize);
|
|
WriteCommString( (LPVOID) pMsg, sizeof(DPHDR) + dwBuffSize);
|
|
lpv = NULL;
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// ----------------------------------------------------------
|
|
// Send - transmit data over socket.
|
|
// ----------------------------------------------------------
|
|
HRESULT CImpIDP_SP::Send(
|
|
DPID from,
|
|
DPID to,
|
|
DWORD dwFlags,
|
|
LPVOID lpvBuffer,
|
|
DWORD dwBuffSize)
|
|
{
|
|
DWORD ii;
|
|
LONG iFrom;
|
|
BOOL bSent = FALSE;
|
|
|
|
if (m_dwPendingWrites > m_dpcaps.dwMaxQueueSize)
|
|
{
|
|
return(DPERR_BUSY);
|
|
}
|
|
|
|
if (dwBuffSize > MAX_MSG)
|
|
return(DPERR_INVALIDPARAMS);
|
|
|
|
if (from == 0)
|
|
{
|
|
return(DPERR_INVALIDPID);
|
|
}
|
|
else
|
|
{
|
|
iFrom = GetPlayerIndex(from);
|
|
// DBG_INFO((DBGARG, TEXT("Send From Pid %d Player Index %d"), from, iFrom));
|
|
if (iFrom == -1)
|
|
for (ii = 0; ii < MAX_PLAYERS; ii++)
|
|
{
|
|
DBG_INFO((DBGARG, TEXT("Index %d Valid %d Pid %d Local %d"),
|
|
ii,
|
|
m_aPlayer[ii].bValid,
|
|
m_aPlayer[ii].pid,
|
|
m_aPlayer[ii].bLocal));
|
|
}
|
|
|
|
|
|
if (iFrom == -1 || ! m_aPlayer[iFrom].bLocal)
|
|
return(DPERR_INVALIDPID);
|
|
}
|
|
|
|
|
|
for (ii = 0; ii < MAX_PLAYERS; ii++)
|
|
if (m_aPlayer[ii].bValid && m_aPlayer[ii].pid != from)
|
|
{
|
|
if ( (to == 0 && m_aPlayer[ii].bPlayer == TRUE)
|
|
|| m_aPlayer[ii].pid == to)
|
|
{
|
|
ISend(iFrom, ii, dwFlags, lpvBuffer, dwBuffSize);
|
|
bSent = TRUE;
|
|
}
|
|
}
|
|
|
|
return(bSent ? m_dwPendingWrites : DPERR_INVALIDPID);
|
|
}
|
|
|
|
// ----------------------------------------------------------
|
|
// Receive - receive message
|
|
// ----------------------------------------------------------
|
|
HRESULT CImpIDP_SP::Receive(
|
|
LPDPID pidfrom,
|
|
LPDPID pidto,
|
|
DWORD dwFlags,
|
|
LPVOID lpvBuffer,
|
|
LPDWORD lpdwSize)
|
|
{
|
|
HRESULT hr;
|
|
LONG iIndex;
|
|
BOOL bb;
|
|
|
|
bb = TRUE;
|
|
|
|
if (dwFlags & DPRECEIVE_TOPLAYER)
|
|
{
|
|
iIndex = GetPlayerIndex(*pidto);
|
|
|
|
if (iIndex == -1 || m_aPlayer[iIndex].bLocal == FALSE)
|
|
bb = FALSE;
|
|
}
|
|
|
|
if ((dwFlags & DPRECEIVE_FROMPLAYER) && *pidfrom != 0)
|
|
{
|
|
iIndex = GetPlayerIndex(*pidfrom);
|
|
|
|
if (iIndex == -1 || m_aPlayer[iIndex].bLocal == FALSE)
|
|
bb = FALSE;
|
|
}
|
|
|
|
if (bb == FALSE)
|
|
{
|
|
return(DPERR_INVALIDPID);
|
|
}
|
|
|
|
hr = GetQMessage(lpvBuffer, lpdwSize, pidto, pidfrom, dwFlags,
|
|
dwFlags & DPRECEIVE_PEEK);
|
|
return(hr);
|
|
}
|
|
|
|
|
|
HRESULT CImpIDP_SP::SetPlayerName(
|
|
DPID pid,
|
|
LPSTR lpFriendlyName,
|
|
LPSTR lpFormalName,
|
|
BOOL bPlayer)
|
|
{
|
|
SPMSG_ADDPLAYER *pMsg;
|
|
|
|
|
|
//
|
|
// Send DPSYS_SETPLAYER to nameserver.
|
|
//
|
|
LONG iIndex = GetPlayerIndex(pid);
|
|
|
|
if (iIndex == -1)
|
|
return(DPERR_INVALIDPLAYER);
|
|
|
|
|
|
if (m_aPlayer[iIndex].bPlayer != bPlayer)
|
|
return(DPERR_INVALIDPLAYER);
|
|
|
|
lstrcpyn( m_aPlayer[iIndex].chNickName, lpFriendlyName, DPSHORTNAMELEN);
|
|
lstrcpyn( m_aPlayer[iIndex].chFullName, lpFormalName , DPLONGNAMELEN);
|
|
|
|
pMsg = (SPMSG_ADDPLAYER *) malloc(sizeof(SPMSG_ADDPLAYER));
|
|
if (!pMsg)
|
|
{
|
|
return(DPERR_NOMEMORY);
|
|
}
|
|
|
|
pMsg->dpHdr.usCookie = SPSYS_SYS;
|
|
pMsg->dpHdr.to = 0;
|
|
pMsg->dpHdr.from = 0;
|
|
pMsg->dpHdr.usCount = SIZE_ADDPLAYER;
|
|
pMsg->sMsg.dwType = DPSYS_SETPLAYER;
|
|
pMsg->sMsg.dwPlayerType = bPlayer;
|
|
pMsg->sMsg.dpId = m_aPlayer[iIndex].pid;
|
|
lstrcpy( pMsg->sMsg.szShortName, lpFriendlyName);
|
|
lstrcpy( pMsg->sMsg.szLongName, lpFormalName);
|
|
|
|
WriteCommString( pMsg, sizeof(SPMSG_ADDPLAYER));
|
|
|
|
return(DP_OK);
|
|
}
|
|
|
|
HRESULT CImpIDP_SP::SaveSession(LPVOID lpv, LPDWORD lpdw)
|
|
{
|
|
DWORD dwLen;
|
|
|
|
if (!m_bConnected)
|
|
return(DPERR_NOCONNECTION);
|
|
|
|
if (m_bPlayer0)
|
|
return(DPERR_UNSUPPORTED);
|
|
|
|
if (m_lpDialable[0] == 0x00)
|
|
return(DPERR_GENERIC);
|
|
|
|
dwLen = 1 + lstrlen(m_lpDialable);
|
|
|
|
if (*lpdw < dwLen)
|
|
{
|
|
*lpdw = dwLen;
|
|
TSHELL_INFO(TEXT("SaveSession buffer too small."));
|
|
return(DPERR_BUFFERTOOSMALL);
|
|
}
|
|
|
|
if (lpv)
|
|
{
|
|
lstrcpy( (char *) lpv, m_lpDialable);
|
|
*lpdw = dwLen;
|
|
}
|
|
|
|
return(DP_OK);
|
|
}
|
|
|
|
|
|
HRESULT CImpIDP_SP::SetPrevSession(LPSTR lpName, LPVOID lpv, DWORD dw)
|
|
{
|
|
//
|
|
//
|
|
//
|
|
DWORD dwLen;
|
|
|
|
// TSHELL_INFO(TEXT("SetPrevSession"));
|
|
if (m_dwSessionAlloc == m_dwSessionPrev)
|
|
{
|
|
char **ppTmp;
|
|
|
|
m_dwSessionAlloc += 16;
|
|
ppTmp = (char **) malloc(sizeof(char *) * m_dwSessionAlloc);
|
|
if (ppTmp)
|
|
{
|
|
if (m_ppSessionArray)
|
|
{
|
|
memcpy( ppTmp, m_ppSessionArray, m_dwSessionPrev);
|
|
free(m_ppSessionArray);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_dwSessionAlloc -= 16;
|
|
return(DPERR_NOMEMORY);
|
|
}
|
|
m_ppSessionArray = ppTmp;
|
|
|
|
}
|
|
dwLen = lstrlen(lpName) + 1;
|
|
m_ppSessionArray[m_dwSessionPrev] = (char *) malloc(dwLen + dw + sizeof(dw));
|
|
if (m_ppSessionArray[m_dwSessionPrev])
|
|
{
|
|
// TSHELL_INFO(TEXT("Fill in structure"));
|
|
*((DWORD *)(m_ppSessionArray[m_dwSessionPrev])) = dw;
|
|
memcpy(((m_ppSessionArray[m_dwSessionPrev]) + sizeof(dw)), lpv, dw);
|
|
lstrcpy(((m_ppSessionArray[m_dwSessionPrev]) + sizeof(dw) + dw), lpName);
|
|
m_dwSessionPrev++;
|
|
return(DP_OK);
|
|
}
|
|
else
|
|
{
|
|
return(DPERR_NOMEMORY);
|
|
}
|
|
|
|
return(DPERR_UNSUPPORTED);
|
|
}
|
|
|
|
|
|
HRESULT CImpIDP_SP::SetPrevPlayer(LPSTR lpName, LPVOID lpv, DWORD dw)
|
|
{
|
|
//
|
|
//
|
|
// This doesn't make sense for a serial point to point SP.
|
|
//
|
|
TSHELL_INFO( TEXT("not currently supported") );
|
|
return(DPERR_UNSUPPORTED);
|
|
}
|
|
|
|
HRESULT CImpIDP_SP::EnableNewPlayers(BOOL bEnable)
|
|
{
|
|
//
|
|
// Implementation not set, and won't follow this calling convention.
|
|
// ignore for now.
|
|
//
|
|
SPMSG_ENABLEPLAYER *pMsg;
|
|
|
|
pMsg = (SPMSG_ENABLEPLAYER *) malloc(sizeof(SPMSG_ENABLEPLAYER));
|
|
if (pMsg)
|
|
{
|
|
m_bEnablePlayerAdd = bEnable;
|
|
pMsg->dpHdr.usCookie = SPSYS_SYS;
|
|
pMsg->dpHdr.to = 0;
|
|
pMsg->dpHdr.from = 0;
|
|
pMsg->dpHdr.usCount = sizeof(DPMSG_ENABLEPLAYER);
|
|
pMsg->sMsg.dwType = DPSYS_ENABLEPLAYER;
|
|
pMsg->sMsg.bEnable = bEnable;
|
|
WriteCommString( pMsg, sizeof(SPMSG_ENABLEPLAYER));
|
|
return(DP_OK);
|
|
}
|
|
else
|
|
return(DPERR_NOMEMORY);
|
|
}
|
|
|
|
HRESULT CImpIDP_SP::GetPlayerCaps(
|
|
DPID pid,
|
|
LPDPCAPS lpDPCaps)
|
|
{
|
|
LONG iIndex = GetPlayerIndex(pid);
|
|
|
|
if (iIndex == -1 || m_aPlayer[iIndex].bPlayer == FALSE)
|
|
return(DPERR_INVALIDPID);
|
|
|
|
m_dpcaps.dwHundredBaud = g_dwRate / 100;
|
|
*lpDPCaps = m_dpcaps;
|
|
if (m_aPlayer[iIndex].bLocal)
|
|
lpDPCaps->dwLatency = 1;
|
|
|
|
return(DP_OK);
|
|
}
|
|
|
|
HRESULT CImpIDP_SP::GetMessageCount(DPID pid, LPDWORD lpdw )
|
|
{
|
|
//
|
|
// Return count for this pid, if it is a local player we have
|
|
// been tracking with Interlock calls.
|
|
//
|
|
LONG iIndex = GetPlayerIndex((DPID) pid);
|
|
|
|
if (iIndex == -1 || m_aPlayer[iIndex].bPlayer == FALSE)
|
|
return(DPERR_INVALIDPLAYER);
|
|
|
|
if (m_aPlayer[iIndex].bLocal == FALSE)
|
|
return(DPERR_INVALIDPLAYER);
|
|
|
|
*lpdw = GetPlayerCount((DPID) pid);
|
|
return(DP_OK);
|
|
|
|
}
|
|
HRESULT CImpIDP_SP::AddPlayerToGroup(
|
|
DPID pidGroup,
|
|
DPID pidPlayer)
|
|
{
|
|
DPMSG_GROUPADD dpGAdd;
|
|
LONG iIndexG;
|
|
LONG iIndexP;
|
|
DWORD ii;
|
|
SPMSG_GROUPADD *pMsg;
|
|
|
|
iIndexG = GetPlayerIndex(pidGroup);
|
|
iIndexP = GetPlayerIndex(pidPlayer);
|
|
|
|
if (iIndexG == -1 || m_aPlayer[iIndexG].bPlayer == TRUE)
|
|
return(DPERR_INVALIDPID);
|
|
|
|
if (iIndexP == -1 || m_aPlayer[iIndexP].bPlayer == FALSE)
|
|
return(DPERR_INVALIDPID);
|
|
|
|
for (ii = 0; ii < MAX_PLAYERS; ii++)
|
|
{
|
|
if (m_aPlayer[iIndexG].aGroup[ii] == m_aPlayer[iIndexP].pid)
|
|
{
|
|
return(DPERR_INVALIDPID);
|
|
}
|
|
}
|
|
|
|
|
|
for (ii = 0; ii < MAX_PLAYERS; ii++)
|
|
{
|
|
if (m_aPlayer[iIndexG].aGroup[ii] == 0)
|
|
{
|
|
dpGAdd.dwType = DPSYS_ADDPLAYERTOGROUP;
|
|
dpGAdd.dpIdGroup = m_aPlayer[iIndexG].pid;
|
|
dpGAdd.dpIdPlayer = m_aPlayer[iIndexP].pid;
|
|
LocalMsg(iIndexG, (LPVOID) &dpGAdd, sizeof(DPMSG_GROUPADD));
|
|
m_aPlayer[iIndexG].aGroup[ii] = m_aPlayer[iIndexP].pid;
|
|
|
|
|
|
pMsg = (SPMSG_GROUPADD *) malloc(sizeof(SPMSG_GROUPADD));
|
|
|
|
if (pMsg)
|
|
{
|
|
pMsg->dpHdr.usCookie = SPSYS_SYS;
|
|
pMsg->dpHdr.to = 0;
|
|
pMsg->dpHdr.from = 0;
|
|
pMsg->dpHdr.usCount = sizeof(DPMSG_GROUPADD);
|
|
|
|
memcpy( (LPVOID) &pMsg->sMsg, (LPVOID) &dpGAdd, sizeof(DPMSG_GROUPADD));
|
|
WriteCommString( pMsg, sizeof(SPMSG_GROUPADD));
|
|
return(DP_OK);
|
|
}
|
|
else
|
|
return(DPERR_NOMEMORY);
|
|
}
|
|
}
|
|
return(DPERR_GENERIC);
|
|
}
|
|
|
|
HRESULT CImpIDP_SP::DeletePlayerFromGroup(
|
|
DPID pidGroup,
|
|
DPID pidPlayer)
|
|
{
|
|
DPMSG_GROUPADD dpGAdd;
|
|
LONG iIndexG;
|
|
LONG iIndexP;
|
|
DWORD ii;
|
|
SPMSG_GROUPADD *pMsg;
|
|
|
|
iIndexG = GetPlayerIndex(pidGroup);
|
|
iIndexP = GetPlayerIndex(pidPlayer);
|
|
|
|
if (iIndexG == -1 || m_aPlayer[iIndexG].bPlayer == TRUE)
|
|
return(DPERR_INVALIDPID);
|
|
|
|
if (iIndexP == -1 || m_aPlayer[iIndexP].bPlayer == FALSE)
|
|
return(DPERR_INVALIDPID);
|
|
|
|
|
|
for (ii = 0; ii < MAX_PLAYERS; ii++)
|
|
{
|
|
if (m_aPlayer[iIndexG].aGroup[ii] == m_aPlayer[iIndexP].pid)
|
|
{
|
|
dpGAdd.dwType = DPSYS_DELETEPLAYERFROMGRP;
|
|
dpGAdd.dpIdGroup = m_aPlayer[iIndexG].pid;
|
|
dpGAdd.dpIdPlayer = m_aPlayer[iIndexP].pid;
|
|
LocalMsg(iIndexG, (LPVOID) &dpGAdd, sizeof(DPMSG_GROUPADD));
|
|
|
|
m_aPlayer[iIndexG].aGroup[ii] = 0;
|
|
|
|
pMsg = (SPMSG_GROUPADD *) malloc(sizeof(SPMSG_GROUPADD));
|
|
|
|
if (pMsg)
|
|
{
|
|
pMsg->dpHdr.usCookie = SPSYS_SYS;
|
|
pMsg->dpHdr.to = 0;
|
|
pMsg->dpHdr.from = 0;
|
|
pMsg->dpHdr.usCount = sizeof(DPMSG_GROUPADD);
|
|
|
|
memcpy( (LPVOID) &pMsg->sMsg, (LPVOID) &dpGAdd, sizeof(DPMSG_GROUPADD));
|
|
WriteCommString( pMsg, sizeof(SPMSG_GROUPADD));
|
|
return(DP_OK);
|
|
}
|
|
else
|
|
return(DPERR_NOMEMORY);
|
|
}
|
|
}
|
|
return(DPERR_INVALIDPID);
|
|
}
|
|
|
|
VOID CImpIDP_SP::HandleMessage(LPVOID lpv, DWORD dwSize)
|
|
{
|
|
DPHDR *pHdr;
|
|
BOOL bHigh = FALSE;
|
|
DPID pidTo, pidFrom;
|
|
DWORD ii;
|
|
SPMSG_ADDPLAYER *pAddPlayer;
|
|
LONG iIndex;
|
|
|
|
pHdr = (DPHDR *) lpv;
|
|
|
|
|
|
// TSHELL_INFO(TEXT("HandleMessage entered."));
|
|
switch(pHdr->usCookie)
|
|
{
|
|
default:
|
|
TSHELL_INFO(TEXT("Unknown message value"));
|
|
break;
|
|
|
|
case SPSYS_CONNECT:
|
|
SPMSG_CONNECT *pConnect;
|
|
|
|
pConnect = (SPMSG_CONNECT *) lpv;
|
|
if ( pConnect->dpHdr.usCount == sizeof(SPMSG_CONNECT) - sizeof(DPHDR)
|
|
&& pConnect->usVerMajor == DPVERSION_MAJOR
|
|
&& pConnect->usVerMinor == DPVERSION_MINOR
|
|
&& pConnect->dwConnect1 == DPSYS_KYRA
|
|
&& pConnect->dwConnect2 == DPSYS_HALL)
|
|
{
|
|
HandleConnect();
|
|
}
|
|
|
|
return;
|
|
|
|
case SPSYS_HIGH:
|
|
bHigh = TRUE;
|
|
//
|
|
// Fall Through!
|
|
//
|
|
case SPSYS_USER:
|
|
pidTo = 0x00ff & ((DPID) pHdr->to);
|
|
pidFrom = 0x00ff & ((DPID) pHdr->from);
|
|
dwSize = (DWORD) ((DPID) pHdr->usCount);
|
|
AddMessage((LPVOID) (((LPBYTE) lpv) + sizeof(DPHDR)), dwSize,
|
|
pidTo, pidFrom, bHigh);
|
|
if ( pidFrom != 0
|
|
&& ((iIndex = GetPlayerIndex(pidFrom)) == -1))
|
|
{
|
|
SPMSG_GETPLAYER *pMsg;
|
|
pMsg = (SPMSG_GETPLAYER *) malloc(sizeof(SPMSG_GETPLAYER));
|
|
if (pMsg)
|
|
{
|
|
pMsg->dpHdr.usCookie = SPSYS_SYS;
|
|
pMsg->dpHdr.to = 0;
|
|
pMsg->dpHdr.from = 0;
|
|
pMsg->dpHdr.usCount = sizeof(DPMSG_GETPLAYER);
|
|
pMsg->sMsg.dwType = DPSYS_GETPLAYER;
|
|
pMsg->sMsg.dpId = pidFrom;
|
|
WriteCommString((LPVOID) pMsg, sizeof(SPMSG_GETPLAYER));
|
|
}
|
|
}
|
|
break;
|
|
|
|
case SPSYS_SYS:
|
|
TSHELL_INFO(TEXT("HandleMessage System Message."));
|
|
switch(((SPMSG_GENERIC *)lpv)->sMsg.dwType)
|
|
{
|
|
default:
|
|
|
|
DBG_INFO((DBGARG, TEXT("Unknown Type %x"), ((SPMSG_GENERIC *)lpv)->sMsg.dwType));
|
|
break;
|
|
|
|
case DPSYS_ENABLEPLAYER:
|
|
{
|
|
SPMSG_ENABLEPLAYER *pMsg;
|
|
|
|
pMsg = (SPMSG_ENABLEPLAYER *) lpv;
|
|
if (pMsg->dpHdr.usCount == sizeof(DPMSG_ENABLEPLAYER))
|
|
{
|
|
m_bEnablePlayerAdd = pMsg->sMsg.bEnable;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case DPSYS_SETGROUPPLAYER:
|
|
{
|
|
SPMSG_SETGROUPPLAYERS16 *pMsgG;
|
|
LONG iIndexG;
|
|
DWORD ii, jj;
|
|
DPID pid;
|
|
|
|
pMsgG = (SPMSG_SETGROUPPLAYERS16 *) lpv;
|
|
|
|
if (pMsgG->dpHdr.usCount == (sizeof(SPMSG_SETGROUPPLAYERS16) - sizeof(DPHDR)))
|
|
{
|
|
iIndexG = GetPlayerIndex((DPID) (0x000000ff & pMsgG->Group));
|
|
if (iIndexG == -1)
|
|
{
|
|
TSHELL_INFO(TEXT("Invalid SetGroupMembers message."));
|
|
}
|
|
else
|
|
{
|
|
for (ii = 0, jj = 0; ii < 16; ii++)
|
|
{
|
|
if (pMsgG->bytePlayers[ii] != 0)
|
|
{
|
|
pid = (DPID) (0x000000ff & pMsgG->bytePlayers[ii]);
|
|
if (GetPlayerIndex(pid) != -1)
|
|
{
|
|
m_aPlayer[iIndexG].aGroup[jj++] = pid;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
break;
|
|
|
|
case DPSYS_DELETEPLAYERFROMGRP:
|
|
case DPSYS_ADDPLAYERTOGROUP:
|
|
{
|
|
SPMSG_GROUPADD *pMsg;
|
|
LONG iIndexG;
|
|
LONG iIndexP;
|
|
|
|
pMsg = (SPMSG_GROUPADD *) lpv;
|
|
|
|
if (pMsg->dpHdr.usCount == sizeof(DPMSG_GROUPADD))
|
|
{
|
|
iIndexG = GetPlayerIndex(pMsg->sMsg.dpIdGroup);
|
|
iIndexP = GetPlayerIndex(pMsg->sMsg.dpIdPlayer);
|
|
if ( iIndexG == -1
|
|
|| m_aPlayer[iIndexG].bPlayer == TRUE
|
|
|| iIndexP == -1
|
|
|| m_aPlayer[iIndexP].bPlayer == FALSE)
|
|
{
|
|
TSHELL_INFO(TEXT("Invalid GroupAdd message."));
|
|
}
|
|
else
|
|
{
|
|
if (pMsg->sMsg.dwType == DPSYS_ADDPLAYERTOGROUP)
|
|
{
|
|
|
|
for (ii = 0; ii < MAX_PLAYERS; ii++)
|
|
if (m_aPlayer[iIndexG].aGroup[ii] == 0)
|
|
{
|
|
m_aPlayer[iIndexG].aGroup[ii] = m_aPlayer[iIndexP].pid;
|
|
LocalMsg(iIndexG, (LPVOID) &pMsg->sMsg, sizeof(DPMSG_GROUPADD));
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
|
|
for (ii = 0; ii < MAX_PLAYERS; ii++)
|
|
if (m_aPlayer[iIndexG].aGroup[ii] == m_aPlayer[iIndexP].pid)
|
|
{
|
|
m_aPlayer[iIndexG].aGroup[ii] = 0;
|
|
LocalMsg(iIndexG, (LPVOID) &pMsg->sMsg, sizeof(DPMSG_GROUPADD));
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
TSHELL_INFO(TEXT("Invalid size on system message"));
|
|
}
|
|
}
|
|
break;
|
|
|
|
|
|
|
|
case DPSYS_SENDDESC:
|
|
{
|
|
SPMSG_SENDDESC *pMsg;
|
|
|
|
pMsg = (SPMSG_SENDDESC *) lpv;
|
|
if (pMsg->dpHdr.usCount == SIZE_SENDDESC)
|
|
{
|
|
memcpy( (LPVOID) &m_dpDesc, (LPVOID) &pMsg->dpDesc, sizeof(m_dpDesc));
|
|
DBG_INFO((DBGARG, TEXT("New Description. Current Players %d, Max %d"),
|
|
m_dpDesc.dwCurrentPlayers, m_dpDesc.dwMaxPlayers));
|
|
}
|
|
else
|
|
{
|
|
TSHELL_INFO(TEXT("Bad SendDesc message."));
|
|
}
|
|
}
|
|
break;
|
|
|
|
case DPSYS_PING:
|
|
{
|
|
SPMSG_PING *pMsg;
|
|
|
|
pMsg = (SPMSG_PING *) lpv;
|
|
if (pMsg->dpHdr.usCount == SIZE_PING)
|
|
{
|
|
if (pMsg->dwTicks == m_dwPingSent)
|
|
{
|
|
m_dpcaps.dwLatency = (GetTickCount() - m_dwPingSent) /2;
|
|
m_dwPingSent = 0;
|
|
// TSHELL_INFO(TEXT("Latency Accepted from our Ping."));
|
|
}
|
|
else
|
|
{
|
|
SPMSG_PING *pMsg2;
|
|
|
|
pMsg2 = (SPMSG_PING *) malloc(sizeof(SPMSG_PING));
|
|
if (pMsg2)
|
|
{
|
|
memcpy( (LPVOID) pMsg2, (LPVOID) pMsg, sizeof(SPMSG_PING));
|
|
WriteCommString(pMsg2, sizeof(SPMSG_PING));
|
|
// TSHELL_INFO(TEXT("Return Ping."));
|
|
}
|
|
|
|
}
|
|
TSHELL_INFO(TEXT("Ping Recieved."));
|
|
}
|
|
}
|
|
break;
|
|
|
|
case DPSYS_SETPLAYER:
|
|
{
|
|
pAddPlayer = (SPMSG_ADDPLAYER *) lpv;
|
|
|
|
TSHELL_INFO(TEXT("Received SETPLAYER message"));
|
|
if (pAddPlayer->dpHdr.usCount == SIZE_ADDPLAYER)
|
|
{
|
|
iIndex = GetPlayerIndex(pAddPlayer->sMsg.dpId);
|
|
if (iIndex != -1)
|
|
{
|
|
if (m_aPlayer[iIndex].bPlayer == (BOOL) pAddPlayer->sMsg.dwPlayerType)
|
|
{
|
|
lstrcpyn( m_aPlayer[iIndex].chNickName, pAddPlayer->sMsg.szShortName, DPSHORTNAMELEN);
|
|
lstrcpyn( m_aPlayer[iIndex].chFullName, pAddPlayer->sMsg.szLongName , DPLONGNAMELEN);
|
|
}
|
|
TSHELL_INFO(TEXT("Name change through SETPLAYER"));
|
|
|
|
|
|
}
|
|
else if ( !m_bPlayer0
|
|
&& ((iIndex = FindInvalidIndex()) != -1))
|
|
{
|
|
lstrcpy( m_aPlayer[iIndex].chNickName, pAddPlayer->sMsg.szShortName);
|
|
lstrcpy( m_aPlayer[iIndex].chFullName, pAddPlayer->sMsg.szLongName);
|
|
m_aPlayer[iIndex].bValid = TRUE;
|
|
m_aPlayer[iIndex].bPlayer = pAddPlayer->sMsg.dwPlayerType;
|
|
m_aPlayer[iIndex].bLocal = FALSE;
|
|
for (ii = 0; ii < MAX_PLAYERS; ii++)
|
|
m_aPlayer[iIndex].aGroup[ii] = 0;
|
|
|
|
m_aPlayer[iIndex].pid = pAddPlayer->sMsg.dpId;
|
|
TSHELL_INFO(TEXT("Remote player updated with SETPLAYER."));
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case DPSYS_ADDPLAYER:
|
|
{
|
|
pAddPlayer = (SPMSG_ADDPLAYER *) lpv;
|
|
|
|
if (pAddPlayer->dpHdr.usCount == SIZE_ADDPLAYER)
|
|
{
|
|
|
|
if (m_bEnablePlayerAdd == FALSE && pAddPlayer->sMsg.dwPlayerType == TRUE)
|
|
break;
|
|
|
|
if (m_bPlayer0)
|
|
{
|
|
TSHELL_INFO(TEXT("Begin AddPlayer Processing Player 0."));
|
|
|
|
if ( m_dpDesc.dwMaxPlayers >= m_dpDesc.dwCurrentPlayers
|
|
&& pAddPlayer->sMsg.dpId == 0
|
|
&& ((iIndex = FindInvalidIndex()) != -1)
|
|
&& (m_dwNextPlayer < MAXIMUM_PLAYER_ID))
|
|
{
|
|
|
|
SPMSG_ADDPLAYER *pReplyMsg;
|
|
|
|
m_dpDesc.dwCurrentPlayers++;
|
|
m_aPlayer[iIndex].pid = (DPID) m_dwNextPlayer++;
|
|
lstrcpy( m_aPlayer[iIndex].chNickName, pAddPlayer->sMsg.szShortName);
|
|
lstrcpy( m_aPlayer[iIndex].chFullName, pAddPlayer->sMsg.szLongName);
|
|
m_aPlayer[iIndex].bValid = TRUE;
|
|
m_aPlayer[iIndex].bPlayer = pAddPlayer->sMsg.dwPlayerType;
|
|
m_aPlayer[iIndex].bLocal = FALSE;
|
|
for (ii = 0; ii < MAX_PLAYERS; ii++)
|
|
m_aPlayer[iIndex].aGroup[ii] = 0;
|
|
|
|
pAddPlayer->sMsg.dpId = m_aPlayer[iIndex].pid;
|
|
|
|
pReplyMsg = (SPMSG_ADDPLAYER *) malloc(sizeof(SPMSG_ADDPLAYER));
|
|
if (pReplyMsg)
|
|
{
|
|
TSHELL_INFO(TEXT("Replying to AddPlayer message."));
|
|
memcpy((LPVOID) pReplyMsg, (LPVOID) pAddPlayer,
|
|
sizeof(SPMSG_ADDPLAYER));
|
|
WriteCommString( (LPVOID) pReplyMsg, sizeof(SPMSG_ADDPLAYER));
|
|
}
|
|
|
|
LocalMsg(iIndex, &pAddPlayer->sMsg, sizeof(DPMSG_ADDPLAYER));
|
|
|
|
}
|
|
else
|
|
{
|
|
TSHELL_INFO(TEXT("Ignoring message, it will timeout."));
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
TSHELL_INFO(TEXT("Begin AddPlayer Processing Remote."));
|
|
iIndex = GetPlayerIndex(pAddPlayer->sMsg.dpId);
|
|
if (iIndex == -1 && (iIndex = FindInvalidIndex()) != -1)
|
|
{
|
|
lstrcpy( m_aPlayer[iIndex].chNickName, pAddPlayer->sMsg.szShortName);
|
|
lstrcpy( m_aPlayer[iIndex].chFullName, pAddPlayer->sMsg.szLongName);
|
|
m_aPlayer[iIndex].bValid = TRUE;
|
|
m_aPlayer[iIndex].bPlayer = pAddPlayer->sMsg.dwPlayerType;
|
|
for (ii = 0; ii < MAX_PLAYERS; ii++)
|
|
m_aPlayer[iIndex].aGroup[ii] = 0;
|
|
|
|
m_aPlayer[iIndex].pid = pAddPlayer->sMsg.dpId;
|
|
LocalMsg(iIndex, &pAddPlayer->sMsg, sizeof(DPMSG_ADDPLAYER));
|
|
if (m_hNewPlayerEvent)
|
|
{
|
|
m_aPlayer[iIndex].bLocal = TRUE;
|
|
m_iPlayerIndex = iIndex;
|
|
SetEvent(m_hNewPlayerEvent);
|
|
}
|
|
else
|
|
m_aPlayer[iIndex].bLocal = FALSE;
|
|
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
TSHELL_INFO(TEXT("Invalid size on system message ADDPLAYER"));
|
|
}
|
|
}
|
|
break;
|
|
|
|
case DPSYS_DELETEGROUP:
|
|
case DPSYS_DELETEPLAYER:
|
|
{
|
|
SPMSG_GETPLAYER *pMsg;
|
|
SPMSG_GETPLAYER *pMsg2;
|
|
|
|
pMsg = (SPMSG_GETPLAYER *) lpv;
|
|
|
|
TSHELL_INFO(TEXT("Got Delete"));
|
|
if (pMsg->dpHdr.usCount == SIZE_GETPLAYER)
|
|
{
|
|
if ((iIndex = GetPlayerIndex(pMsg->sMsg.dpId)) != -1)
|
|
{
|
|
if (m_bPlayer0)
|
|
{
|
|
pMsg2 = (SPMSG_GETPLAYER *) malloc(sizeof(SPMSG_GETPLAYER));
|
|
if (pMsg2)
|
|
{
|
|
TSHELL_INFO(TEXT("Player 0 Pings Delete."));
|
|
memcpy( (LPVOID) pMsg2, (LPVOID) pMsg, sizeof(SPMSG_GETPLAYER));
|
|
WriteCommString( (LPVOID) pMsg2, sizeof(SPMSG_GETPLAYER));
|
|
}
|
|
}
|
|
|
|
if (m_aPlayer[iIndex].bLocal)
|
|
{
|
|
CloseHandle(m_aPlayer[iIndex].hEvent);
|
|
FlushQueue(m_aPlayer[iIndex].pid);
|
|
}
|
|
m_aPlayer[iIndex].bValid = FALSE;
|
|
LocalMsg(iIndex, (LPVOID) &pMsg->sMsg, sizeof(DPMSG_GETPLAYER));
|
|
|
|
m_dpDesc.dwCurrentPlayers--;
|
|
|
|
if (pMsg->sMsg.dwType == DPSYS_DELETEPLAYER)
|
|
{
|
|
DWORD ii, jj;
|
|
|
|
for (ii = 0; ii < MAX_PLAYERS; ii++)
|
|
{
|
|
if ( m_aPlayer[ii].bValid == TRUE
|
|
&& m_aPlayer[ii].bPlayer == FALSE
|
|
&& m_aPlayer[ii].aGroup)
|
|
{
|
|
for (jj = 0; jj < MAX_PLAYERS; jj++)
|
|
{
|
|
if (m_aPlayer[ii].aGroup[jj] == pMsg->sMsg.dpId)
|
|
{
|
|
m_aPlayer[ii].aGroup[jj] = 0;
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
TSHELL_INFO(TEXT("Invalid size on system message"));
|
|
}
|
|
}
|
|
break;
|
|
|
|
case DPSYS_GETPLAYER:
|
|
{
|
|
DPID pid = ((SPMSG_GETPLAYER *) lpv)->sMsg.dpId;
|
|
BOOL bFound = FALSE;
|
|
|
|
if (m_bPlayer0)
|
|
{
|
|
|
|
if ((iIndex = GetPlayerIndex((DPID) pid)) != -1)
|
|
{
|
|
SPMSG_ADDPLAYER *pMsg;
|
|
|
|
pMsg = (SPMSG_ADDPLAYER *) malloc(sizeof(SPMSG_ADDPLAYER));
|
|
pMsg->dpHdr.usCookie = SPSYS_SYS;
|
|
pMsg->dpHdr.to = 0;
|
|
pMsg->dpHdr.from = 0;
|
|
pMsg->dpHdr.usCount = SIZE_ADDPLAYER;
|
|
pMsg->sMsg.dwType = DPSYS_SETPLAYER;
|
|
pMsg->sMsg.dwPlayerType = m_aPlayer[iIndex].bPlayer;
|
|
pMsg->sMsg.dpId = pid;
|
|
lstrcpy( pMsg->sMsg.szShortName, m_aPlayer[iIndex].chNickName);
|
|
lstrcpy( pMsg->sMsg.szLongName, m_aPlayer[iIndex].chFullName);
|
|
|
|
WriteCommString( pMsg, sizeof(SPMSG_ADDPLAYER));
|
|
}
|
|
}
|
|
|
|
}
|
|
break;
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
VOID CImpIDP_SP::SendDesc(LPDPSESSIONDESC pDesc)
|
|
{
|
|
if (!m_bConnected || ! m_bPlayer0)
|
|
return;
|
|
|
|
TSHELL_INFO(TEXT("Here"));
|
|
|
|
SPMSG_SENDDESC *pMsg = (SPMSG_SENDDESC *) malloc(sizeof(SPMSG_SENDDESC));
|
|
|
|
if (pMsg)
|
|
{
|
|
pMsg->dpHdr.usCookie = SPSYS_SYS;
|
|
pMsg->dpHdr.to = 0;
|
|
pMsg->dpHdr.from = 0;
|
|
pMsg->dpHdr.usCount = SIZE_SENDDESC;
|
|
pMsg->dwType = DPSYS_SENDDESC;
|
|
memcpy((LPVOID) &pMsg->dpDesc, (LPVOID) pDesc, sizeof(pMsg->dpDesc));
|
|
WriteCommString( (LPVOID) pMsg, sizeof(SPMSG_SENDDESC));
|
|
TSHELL_INFO(TEXT("Description Sent."));
|
|
}
|
|
|
|
|
|
}
|
|
VOID CImpIDP_SP::SendPing()
|
|
{
|
|
|
|
if (!m_bConnected)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if ( m_dwPingSent
|
|
&& (GetTickCount() < (m_dwPingSent + 2000)))
|
|
{
|
|
return;
|
|
}
|
|
else
|
|
m_dwPingSent = 0;
|
|
|
|
SPMSG_PING *pMsg = (SPMSG_PING *) malloc(sizeof(SPMSG_PING));
|
|
|
|
if (pMsg)
|
|
{
|
|
pMsg->dpHdr.usCookie = SPSYS_SYS;
|
|
pMsg->dpHdr.to = 0;
|
|
pMsg->dpHdr.from = 0;
|
|
pMsg->dpHdr.usCount = SIZE_PING;
|
|
pMsg->dwType = DPSYS_PING;
|
|
pMsg->dwTicks = m_dwPingSent = GetTickCount();
|
|
WriteCommString( (LPVOID) pMsg, sizeof(SPMSG_PING));
|
|
}
|
|
|
|
|
|
|
|
}
|
|
VOID CImpIDP_SP::ConnectPlayers()
|
|
{
|
|
|
|
DWORD ii;
|
|
DWORD jj;
|
|
DWORD kk;
|
|
SPMSG_ADDPLAYER *pMsg;
|
|
DPMSG_ADDPLAYER dpAdd;
|
|
|
|
SPMSG_SETGROUPPLAYERS16 *pMsgG;
|
|
|
|
dpAdd.dwType = DPSYS_SETPLAYER;
|
|
dpAdd.dpId = 0;
|
|
|
|
|
|
for (ii = 0; ii < MAX_PLAYERS; ii++)
|
|
{
|
|
if (m_aPlayer[ii].bValid && m_aPlayer[ii].bLocal)
|
|
{
|
|
pMsg = (SPMSG_ADDPLAYER *) malloc(sizeof(SPMSG_ADDPLAYER));
|
|
if (pMsg)
|
|
{
|
|
dpAdd.dpId = m_aPlayer[ii].pid;
|
|
dpAdd.dwPlayerType = m_aPlayer[ii].bPlayer;
|
|
lstrcpy( dpAdd.szShortName, m_aPlayer[ii].chNickName);
|
|
lstrcpy( dpAdd.szLongName , m_aPlayer[ii].chFullName);
|
|
|
|
pMsg->dpHdr.usCookie = SPSYS_SYS;
|
|
pMsg->dpHdr.to = (BYTE) m_aPlayer[ii].pid;
|
|
pMsg->dpHdr.from = 0;
|
|
pMsg->dpHdr.usCount = sizeof(DPMSG_ADDPLAYER);
|
|
memcpy( (LPVOID) &pMsg->sMsg, &dpAdd, sizeof(DPMSG_ADDPLAYER));
|
|
WriteCommString( (LPVOID) pMsg, sizeof(SPMSG_ADDPLAYER));
|
|
}
|
|
}
|
|
}
|
|
|
|
for (ii = 0; ii < MAX_PLAYERS; ii++)
|
|
{
|
|
if ( m_aPlayer[ii].bValid
|
|
&& m_aPlayer[ii].bLocal
|
|
&& m_aPlayer[ii].bPlayer == FALSE)
|
|
{
|
|
pMsgG = (SPMSG_SETGROUPPLAYERS16 *) malloc(sizeof(SPMSG_SETGROUPPLAYERS16));
|
|
if (pMsgG)
|
|
{
|
|
pMsgG->dpHdr.usCookie = SPSYS_SYS;
|
|
pMsgG->dpHdr.to = 0;
|
|
pMsgG->dpHdr.from = 0;
|
|
pMsgG->dpHdr.usCount = sizeof(SPMSG_SETGROUPPLAYERS16) - sizeof(DPHDR);
|
|
pMsgG->dwType = DPSYS_SETGROUPPLAYER;
|
|
pMsgG->Group = (BYTE) m_aPlayer[ii].pid;
|
|
|
|
memset((LPVOID) pMsgG->bytePlayers, 0x00, 16);
|
|
|
|
kk = 0;
|
|
for (jj = 0; jj < MAX_PLAYERS && kk < 16; jj++)
|
|
{
|
|
if (m_aPlayer[ii].aGroup[jj] != 0)
|
|
pMsgG->bytePlayers[kk++] = (BYTE) m_aPlayer[ii].aGroup[jj];
|
|
|
|
}
|
|
WriteCommString( (LPVOID) pMsgG, sizeof(SPMSG_SETGROUPPLAYERS16));
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
VOID CImpIDP_SP::DeleteRemotePlayers()
|
|
{
|
|
DWORD ii;
|
|
DPMSG_DELETEPLAYER dpDel;
|
|
DPMSG_GENERIC dpGeneric;
|
|
|
|
dpDel.dwType = DPSYS_DELETEPLAYER;
|
|
dpGeneric.dwType = DPSYS_SESSIONLOST;
|
|
|
|
for (ii = 0; ii < MAX_PLAYERS; ii++)
|
|
{
|
|
if ( m_aPlayer[ii].bValid
|
|
&& m_aPlayer[ii].bLocal == FALSE
|
|
&& m_aPlayer[ii].bPlayer == TRUE)
|
|
{
|
|
m_aPlayer[ii].bValid = FALSE;
|
|
m_dpDesc.dwCurrentPlayers--;
|
|
dpDel.dpId = m_aPlayer[ii].pid;
|
|
LocalMsg(-1, (LPVOID) &dpDel, sizeof(DPMSG_DELETEPLAYER));
|
|
}
|
|
}
|
|
|
|
LocalMsg(-1, (LPVOID) &dpGeneric, sizeof(DPMSG_GENERIC));
|
|
}
|
|
|
|
VOID CImpIDP_SP::HandleConnect()
|
|
{
|
|
|
|
DPMSG_GENERIC notice;
|
|
|
|
TSHELL_INFO(TEXT("Handle Connect"));
|
|
|
|
if (!m_bConnected && m_dpDesc.dwMaxPlayers != 0)
|
|
{
|
|
TSHELL_INFO(TEXT("We are Connected.!"));
|
|
m_bConnected = TRUE;
|
|
SetEvent(m_hBlockingEvent);
|
|
}
|
|
|
|
if (m_bPlayer0)
|
|
{
|
|
|
|
SPMSG_CONNECT *pMsg = (SPMSG_CONNECT *) malloc(sizeof(SPMSG_CONNECT));
|
|
SendPing();
|
|
TSHELL_INFO(TEXT("Ping Sent."));
|
|
SendDesc(&m_dpDesc);
|
|
TSHELL_INFO(TEXT("Game Description Sent."));
|
|
|
|
if (pMsg)
|
|
{
|
|
TSHELL_INFO(TEXT("Here."));
|
|
pMsg->dpHdr.to = 0;
|
|
pMsg->dpHdr.from = 0;
|
|
pMsg->dpHdr.usCount = sizeof(SPMSG_CONNECT) - sizeof(DPHDR);
|
|
pMsg->dpHdr.usCookie = SPSYS_CONNECT;
|
|
pMsg->usVerMajor = DPVERSION_MAJOR;
|
|
pMsg->usVerMinor = DPVERSION_MINOR;
|
|
pMsg->dwConnect1 = DPSYS_KYRA;
|
|
pMsg->dwConnect2 = DPSYS_HALL;
|
|
TSHELL_INFO(TEXT("Here."));
|
|
WriteCommString( (LPVOID) pMsg, sizeof(SPMSG_CONNECT));
|
|
notice.dwType = DPSYS_CONNECT;
|
|
TSHELL_INFO(TEXT("Here."));
|
|
AddMessage((LPVOID) ¬ice, sizeof(DPMSG_GENERIC), 0, 0, FALSE);
|
|
TSHELL_INFO(TEXT("Here."));
|
|
}
|
|
|
|
TSHELL_INFO(TEXT("Here."));
|
|
if (m_dpDesc.dwCurrentPlayers != 0)
|
|
{
|
|
TSHELL_INFO(TEXT("Here."));
|
|
ConnectPlayers();
|
|
TSHELL_INFO(TEXT("Current players Sent."));
|
|
}
|
|
}
|
|
|
|
TSHELL_INFO(TEXT("Leave Connect"));
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|