6481 lines
285 KiB
C
6481 lines
285 KiB
C
/********************************************************************************/
|
||
/* */
|
||
/* NetSer.c */
|
||
/* */
|
||
/* This file defines the level 2 functions : */
|
||
/* general API functions, system message handling */
|
||
/* */
|
||
/********************************************************************************/
|
||
|
||
#include "warnings.h"
|
||
#if defined(_MSC_VER)
|
||
#pragma warning(disable : 4054)
|
||
#endif
|
||
|
||
#ifndef _NO_USE_DEFAULT_NET_FUNCTIONS_
|
||
#include <windows.h>
|
||
#include <stdlib.h>
|
||
#endif /*_NO_USE_DEFAULT_NET_FUNCTIONS_*/
|
||
#include <memory.h>
|
||
|
||
#include "NetMemCo.h"
|
||
#define GLOBALS
|
||
#include "PrivNetDef.h"
|
||
#undef GLOBALS
|
||
#include "PrivNetSer.h"
|
||
#include "PrivNetSynch.h"
|
||
#include "NetL2Pri.h"
|
||
#include "NetL1Pri.h"
|
||
#include "NetList2.h"
|
||
#include "NetEnd.h"
|
||
#include "NET\NetDebug.h"
|
||
|
||
#include <stdio.h>
|
||
#include <errno.h>
|
||
#include <direct.h>
|
||
|
||
/*
|
||
------------------------------------------------------------------------------------------
|
||
DEFINITION OF INTERNAL CONSTANTS :
|
||
------------------------------------------------------------------------------------------
|
||
*/
|
||
|
||
/* this is the unit in which the time delta between machines is expressed */
|
||
#define C_ulUniversalLagUnit 1000
|
||
/*this is the number of connection requests sent for a single call to ConnectToSession*/
|
||
#define REPEAT_COUNT 3
|
||
|
||
/*
|
||
------------------------------------------------------------------------------------------
|
||
DEFINITION OF INTERNAL STRUCTURES :
|
||
------------------------------------------------------------------------------------------
|
||
*/
|
||
|
||
/* this structure tells for each remote player in the session an estimation*/
|
||
/* of the time lag between the timer callback values between us and another machine.*/
|
||
/* That is to say, the difference between the returned values of this callback on the*/
|
||
/* two machines at the same absolute instant.*/
|
||
typedef struct tdstNetTimeDelta_
|
||
{
|
||
NetLib_tduxPlayerId ulPlayerId;
|
||
double dDeltaWithLocal; /* in C_ulTimeDeltaPrecision th of second*/
|
||
unsigned long ulLatency; /* in gs_ulLocalTimeScale th of second*/
|
||
unsigned long ulScaleOfRecipient;
|
||
unsigned short NumberOfRetries;
|
||
unsigned short LastRetries;
|
||
}tdstNetTimeDelta;
|
||
|
||
/*
|
||
* this structure is the message that is sent back and forth to dertermine the
|
||
* connexion parameters between the local machine and the other players
|
||
*/
|
||
#pragma pack(push)
|
||
#pragma pack(1)
|
||
|
||
typedef struct tdstNetPingMessage_
|
||
{
|
||
unsigned long ulTimeOfSender;
|
||
unsigned long ulTimeOfRecipient;
|
||
unsigned long ulScaleOfRecipient;
|
||
unsigned short numPing;
|
||
}tdstNetPingMessage;
|
||
|
||
#pragma pack(pop)
|
||
|
||
/* Used for checking sessions : */
|
||
typedef struct _tdstNetTemp
|
||
{
|
||
unsigned char ucWaitForReply;
|
||
NetLib_tduxPlayerId ulPlayerId;
|
||
}tdstNetTemp;
|
||
|
||
typedef struct _tdstMsgInfo
|
||
{
|
||
NetLib_tdulTimeInfo m_ulSendingTime;/* The time at which the message will be sent*/
|
||
tdstNetMessage *m_p_stMessage;
|
||
NetLib_tduxPlayerId m_ulPlayerId;
|
||
}tdstMsgInfo;
|
||
|
||
typedef struct _tdstCopyInfo
|
||
{
|
||
NetLib_tdstPlayerInfo *p_stPlayerInfoArray;
|
||
unsigned short uwCurrentPlayerSlot;
|
||
}tdstCopyInfo;
|
||
|
||
typedef NetLib_tdeErrorStatus(_NET_CALLING_CONV_ *tdfn_eNetSysMsgHandle)(tdstNetMessage *,tdeNetProtocol,tduwNetChannel);
|
||
typedef NetLib_tdeErrorStatus(_NET_CALLING_CONV_ *tdfn_eNetSysMsgSwapLittleBigEndian)(tdstNetMessage*,tdeNetProtocol,tduwNetChannel);
|
||
|
||
/*
|
||
------------------------------------------------------------------------------------------
|
||
DEFINITION OF INTERNAL VARIABLES:
|
||
------------------------------------------------------------------------------------------
|
||
*/
|
||
|
||
/* array of functions handling netlib sys messages :*/
|
||
static tdfn_eNetSysMsgHandle *gs_pfn_eSysMsgMap;
|
||
/* array of functions swaping message from little/big endian to big/little endian*/
|
||
static tdfn_eNetSysMsgSwapLittleBigEndian *gs_pfn_eSysMsgSwapMap;
|
||
|
||
/* sets of function that must be called inside the vNetEngine */
|
||
static tdstNetList2 gs_stEngineFunction; /* The list */
|
||
|
||
static char gs_cIsNetlibInitialised = 0;
|
||
static NetLib_tduwMode gs_uwMode;
|
||
static short gs_wBroadcastIpx;
|
||
|
||
/* Informations about the current game : */
|
||
static NetLib_tdstSessionInfo gs_stCurrentSession;
|
||
|
||
|
||
/* array of time lags for each player in the session */
|
||
static tdstNetTimeDelta *gs_d_stTimeDeltas;
|
||
/* do I have to handle calibration replies that arrived ? */
|
||
static unsigned char gs_b_ucDeltaCalibrationIsEnabled;
|
||
|
||
/* Does a listen must be done before accepting a player ?*/
|
||
static unsigned char gs_ucAcceptWithoutListening;
|
||
/* Informations about a player who want to join the Session*/
|
||
static NetLib_tdstPlayerInfo *gs_p_stPreSessionPlayerInfo;
|
||
static tdeNetConnectReceptionStatus gs_tdePreSessionPlayerStatus;
|
||
static NetLib_tdulTimeInfo gs_tm_ulPreSessionPlayerTimer;
|
||
static NetLib_tdulTimeInfo gs_tm_ulPreSessionPlayerMaxWaitingTime;
|
||
/* Callback for connection request filter*/
|
||
NetLib_tdeErrorStatus (_NET_CALLING_CONV_*g_pfn_ePlayerConnectionRequestFilter)(NetLib_tdstPlayerInfo*,long*);
|
||
|
||
/* list of sessions :*/
|
||
static NetLib_tdstSessionInfo *gs_dstSessions;
|
||
static unsigned char *gs_dpucWaitForReply;
|
||
static tdeNetListeningMode gs_eListeningMode;
|
||
static NetLib_tdulTimeInfo gs_tm_ulGetActiveSessionsFreq;
|
||
static NetLib_tdulTimeInfo gs_tm_ulPrevGetActiveSessions;
|
||
static NetLib_tduxDescriptionLength gs_uxMaxPlayerInfo;
|
||
static unsigned short gs_uwNumberOfSessionsExpected;
|
||
static unsigned short gs_c_uwNumberOfSessionsDetected;
|
||
/* Callback for session filter */
|
||
NetLib_tdeErrorStatus (_NET_CALLING_CONV_*g_pfn_eSessionFilter)(NetLib_tdstSessionInfo*);
|
||
|
||
/* For connection :*/
|
||
static NetLib_tdstSessionInfo *gs_p_stConnectRequestSessionInfo;
|
||
static long gs_lConDenyParam;
|
||
static tdeNetConnectRequestStatus *gs_d_tdeConnectRequestStatusArray;
|
||
|
||
/* Callback for disconnection :*/
|
||
void (_NET_CALLING_CONV_*g_pfn_vDisconnectCallBack)(NetLib_tduxPlayerId);
|
||
/* Pointer to a random function :*/
|
||
unsigned long (_NET_CALLING_CONV_*g_pfn_ulNetRandom)(void);
|
||
/* Pointer to a timer function : */
|
||
NetLib_tdfnulGetTimeInfo g_pfn_ulNetGetTimeInfo;
|
||
/* how far goes the timer function in 1 second ? */
|
||
unsigned long gs_ulLocalTimeScale;
|
||
|
||
/* for internet simulation :*/
|
||
static tdstNetList2 gs_stPlayerSendingList;
|
||
static NetLib_tdulTimeInfo gs_ulInternetDelay;
|
||
static NetLib_tdulTimeInfo gs_ulInternetRandom;
|
||
static int gs_ArtificialLatency;
|
||
|
||
/* for handling read receipt :*/
|
||
static tdstNetList2 gs_stReadReceiptList;
|
||
|
||
/*
|
||
------------------------------------------------------------------------------------------
|
||
INITIALISATION FUNCTIONS :
|
||
------------------------------------------------------------------------------------------
|
||
*/
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_eSetBroadcastState
|
||
Set the broadcast state.
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
void _NET_CALLING_CONV_ NetLib_eSetBroadcastState(short BroadcastIpx)
|
||
{
|
||
gs_wBroadcastIpx=BroadcastIpx;
|
||
vLevel1SetBroadcastState(BroadcastIpx);
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_eInitializeGlobalData
|
||
Initialize global variables
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_NoError
|
||
NetLib_E_es_NotEnoughMemory if there was not enough memory to complete the function
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : April 3, 96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ NetLib_eInitializeGlobalData(unsigned long ulBufferSize, char* pPointerArea,NetLib_tduwMode uwMode,short BroadcastIpx)
|
||
{
|
||
NetLib_tdeErrorStatus eErrorReturned;
|
||
NetLib_tduxPlayerId ulNewPlayerId;
|
||
|
||
#if defined(NET_USE_DEBUG)
|
||
|
||
vDebugClear(Net_C_Debug_NetSer);
|
||
/*
|
||
vDebugActiv(Net_C_Debug_NetSer);
|
||
*/
|
||
vDebugS(Net_C_Debug_NetSer,"Netlib - NetSer : Log file");
|
||
#endif /* NET_USE_DEBUG */
|
||
|
||
/* If netlib has already been initialised*/
|
||
if(gs_cIsNetlibInitialised) return NetLib_E_es_NoError;
|
||
|
||
gs_cIsNetlibInitialised = 1;
|
||
gs_uwMode=uwMode;
|
||
gs_wBroadcastIpx=BroadcastIpx;
|
||
|
||
/* Gives memory to the netlib :*/
|
||
uxInitMalloc(ulBufferSize,pPointerArea);
|
||
|
||
/* Initialise netlib sys message map*/
|
||
if((eErrorReturned = eNetBuildMessageMap())!=NetLib_E_es_NoError)
|
||
{
|
||
gs_cIsNetlibInitialised = 0;
|
||
return eErrorReturned;
|
||
}
|
||
if((eErrorReturned=eNetBuildMessageSwapLittleBigEndianMap())!=NetLib_E_es_NoError)
|
||
{
|
||
gs_cIsNetlibInitialised = 0;
|
||
return eErrorReturned;
|
||
}
|
||
if((eErrorReturned = eNetBuildEngineFunctionsList())!=NetLib_E_es_NoError)
|
||
{
|
||
gs_cIsNetlibInitialised = 0;
|
||
return eErrorReturned;
|
||
}
|
||
|
||
/* Callback for disconnection :*/
|
||
NetLib_vRegisterDisconnectCallback((NetLib_tdfnvDisconnectCallback)C_pNull);
|
||
|
||
#ifndef _NO_USE_DEFAULT_NET_FUNCTIONS_
|
||
NetLib_vInitializeGetTimeInfoFunction(fn_ulDefaultNetGetTimeInfo,1000);
|
||
#else
|
||
NetLib_vInitializeGetTimeInfoFunction((NetLib_tdulTimeInfo(_NET_CALLING_CONV_*)(void))C_pNull,0);
|
||
#endif /*_NO_USE_DEFAULT_NET_FUNCTIONS_*/
|
||
|
||
/* Pointer to a random function :*/
|
||
#ifndef _NO_USE_DEFAULT_NET_FUNCTIONS_
|
||
srand((unsigned)g_pfn_ulNetGetTimeInfo());
|
||
NetLib_vInitializeRandomFunction(fn_ulDefaultNetRandom);
|
||
#else
|
||
NetLib_vInitializeRandomFunction((NetLib_tdfnulRandom)C_pNull);
|
||
#endif /*_NO_USE_DEFAULT_NET_FUNCTIONS_*/
|
||
|
||
/* Pointer to a memcpy function :*/
|
||
NetLib_vInitializeMemcopyFunction((td_pfn_vNetMemcpy)memcpy);
|
||
|
||
NetLib_vRegisterFilterSessionCallback((NetLib_tdfneFilterSessionCallback)C_pNull);
|
||
|
||
NetLib_vRegisterPlayerConnectionRequestFilter((NetLib_tdfnePlayerConnectionRequestFilterCallback)C_pNull);
|
||
|
||
/* no time deltas allocated yet */
|
||
gs_d_stTimeDeltas = (tdstNetTimeDelta *) C_pNull;
|
||
/* time delta calibration is not enabled */
|
||
gs_b_ucDeltaCalibrationIsEnabled = 0;
|
||
|
||
/* Initialize level 1 :*/
|
||
eErrorReturned = eLevel1GlobalSetup(gs_uwMode,gs_wBroadcastIpx);
|
||
|
||
/* Informations about the current game : */
|
||
gs_stCurrentSession.uxSessionDescriptionLength = 0;
|
||
gs_stCurrentSession.pSessionDescriptionData = (tdpPointer)C_pNull;
|
||
gs_stCurrentSession.uwMaxNumberOfPlayers = 0;
|
||
gs_stCurrentSession.uwNumberOfPlayers = 0;
|
||
gs_stCurrentSession.uwIndexOfLocalPlayer = 0;
|
||
gs_stCurrentSession.GameOptions=NULL;
|
||
|
||
/* Allocate one cell in the array for the local player :*/
|
||
gs_stCurrentSession.d_stPlayerInfo =(NetLib_tdstPlayerInfo*)pMalloc(sizeof(NetLib_tdstPlayerInfo));
|
||
if(gs_stCurrentSession.d_stPlayerInfo /*!= (NetLib_tdstPlayerInfo*)C_pNull*/)
|
||
{
|
||
gs_stCurrentSession.uwMaxNumberOfPlayers = 1;
|
||
gs_stCurrentSession.uwNumberOfPlayers = 1;
|
||
/* getting an id : */
|
||
if (gs_uwMode==NetLib_Mode_Direct) ulNewPlayerId = ulNetGetNewPlayerId();
|
||
else ulNewPlayerId = 0;
|
||
vNetSetOwnPlayerId(ulNewPlayerId);
|
||
gs_stCurrentSession.d_stPlayerInfo[gs_stCurrentSession.uwIndexOfLocalPlayer].uxPlayerDescriptionLength = 0;
|
||
gs_stCurrentSession.d_stPlayerInfo[gs_stCurrentSession.uwIndexOfLocalPlayer].pPlayerDescriptionData = (tdpPointer)C_pNull;
|
||
gs_stCurrentSession.d_stPlayerInfo[gs_stCurrentSession.uwIndexOfLocalPlayer].m_ucLittleBigEndian = NetLib_ucGetLittleBigEndian();
|
||
gs_stCurrentSession.d_stPlayerInfo[gs_stCurrentSession.uwIndexOfLocalPlayer].wNewPlayer = 0;
|
||
gs_stCurrentSession.d_stPlayerInfo[gs_stCurrentSession.uwIndexOfLocalPlayer].Options = NULL;
|
||
|
||
vNetSetSessionId(ulNewPlayerId);
|
||
}
|
||
else
|
||
{
|
||
gs_cIsNetlibInitialised = 0;
|
||
vNetSetSessionId(C_uxNetInvalidId);
|
||
eErrorReturned = NetLib_E_es_NotEnoughMemory;
|
||
}
|
||
|
||
/* accept without listening ?*/
|
||
gs_ucAcceptWithoutListening = NetLib_C_ucListenForAccept;
|
||
/* Informations about a player who want to join the Session*/
|
||
gs_p_stPreSessionPlayerInfo = (NetLib_tdstPlayerInfo *)C_pNull;
|
||
gs_tdePreSessionPlayerStatus = E_Net_ConRecSta_NONE;
|
||
gs_tm_ulPreSessionPlayerTimer = 0;
|
||
gs_tm_ulPreSessionPlayerMaxWaitingTime = 0;
|
||
|
||
/* list of sessions :*/
|
||
gs_dstSessions = (NetLib_tdstSessionInfo *)C_pNull;
|
||
gs_eListeningMode = E_Net_LisMod_INVALID;
|
||
gs_c_uwNumberOfSessionsDetected = 0;
|
||
gs_uwNumberOfSessionsExpected = 0;
|
||
gs_tm_ulGetActiveSessionsFreq = 0;
|
||
gs_tm_ulPrevGetActiveSessions = 0;
|
||
|
||
/* For connection :*/
|
||
gs_p_stConnectRequestSessionInfo = (NetLib_tdstSessionInfo *)C_pNull;
|
||
gs_d_tdeConnectRequestStatusArray = (tdeNetConnectRequestStatus *)C_pNull;
|
||
gs_lConDenyParam= 0;
|
||
|
||
|
||
/* For internet simul :*/
|
||
gs_ulInternetDelay=0;
|
||
gs_ulInternetRandom=0;
|
||
gs_ArtificialLatency=0;
|
||
iNetList2Init(&gs_stPlayerSendingList);
|
||
|
||
/* For read/receipt handling :*/
|
||
iNetList2Init(&gs_stReadReceiptList);
|
||
|
||
vNetLibInitSynchro();
|
||
|
||
return eErrorReturned;
|
||
}
|
||
|
||
/*
|
||
------------------------------------------------------------------------------------------
|
||
ADDING NEW PLAYERS:
|
||
------------------------------------------------------------------------------------------
|
||
*/
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_eAddNewPlayer
|
||
Add a new player
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : October , 96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ NetLib_eAddNewPlayer(NetLib_tdstAddPlayerDesc *p_stAddPlayerDesc)
|
||
{
|
||
NetLib_tdstPlayerInfo *p_stNewPlayerSlot;
|
||
NetLib_tdeErrorStatus eErrorReturned;
|
||
|
||
/* First of all, check if the library has been initialised*/
|
||
if(!gs_cIsNetlibInitialised) return NetLib_E_es_NotInitialized;
|
||
if (p_stAddPlayerDesc->IsYou)
|
||
{
|
||
vNetSetOwnPlayerId(p_stAddPlayerDesc->m_tduxPlayerId);
|
||
p_stNewPlayerSlot=pstNetGetOwnPlayerSlot();
|
||
p_stNewPlayerSlot->wNewPlayer=0;
|
||
}
|
||
else
|
||
{
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_NetSer, "AddNewPlayer: remote player %lx", p_stAddPlayerDesc->m_tduxPlayerId);
|
||
#endif
|
||
/* Get a new slot for the player :*/
|
||
p_stNewPlayerSlot = pstNetGetPlayerSlot(C_uxNetInvalidId);
|
||
if(!p_stNewPlayerSlot) return NetLib_E_es_AlreadyTooMuchPlayers;
|
||
|
||
/* The player can be correctly added to the level 2:*/
|
||
M_ulNetPlayerIdSlot(p_stNewPlayerSlot) = p_stAddPlayerDesc->m_tduxPlayerId;
|
||
p_stNewPlayerSlot->uxPlayerDescriptionLength=0;
|
||
p_stNewPlayerSlot->pPlayerDescriptionData=NULL;
|
||
if((eErrorReturned = eLevel1AddNewPlayer(p_stAddPlayerDesc->m_tduxPlayerId,&(p_stAddPlayerDesc->m_stL1AddPlayerDesc)))!=NetLib_E_es_NoError)
|
||
{
|
||
M_ulNetPlayerIdSlot(p_stNewPlayerSlot) = C_uxNetInvalidId;
|
||
return eErrorReturned;
|
||
}
|
||
p_stNewPlayerSlot->m_ucLittleBigEndian = NetLib_ucGetLittleBigEndian();
|
||
p_stNewPlayerSlot->wNewPlayer=1;
|
||
|
||
gs_stCurrentSession.uwNumberOfPlayers++;
|
||
}
|
||
if (p_stNewPlayerSlot->pPlayerDescriptionData) vFree((tdpPointer)p_stNewPlayerSlot->pPlayerDescriptionData);
|
||
p_stNewPlayerSlot->pPlayerDescriptionData=NULL;
|
||
p_stNewPlayerSlot->uxPlayerDescriptionLength=p_stAddPlayerDesc->m_uxPlayerDesciptionLength;
|
||
/*Alloc a player description if necessary:*/
|
||
if ((p_stAddPlayerDesc->m_pPlayerDescriptionData) &&
|
||
((p_stNewPlayerSlot->pPlayerDescriptionData=pMalloc(p_stAddPlayerDesc->m_uxPlayerDesciptionLength))!=0))
|
||
{
|
||
g_pfn_vNetMemcpy(p_stNewPlayerSlot->pPlayerDescriptionData,p_stAddPlayerDesc->m_pPlayerDescriptionData,
|
||
p_stAddPlayerDesc->m_uxPlayerDesciptionLength);
|
||
}
|
||
|
||
p_stNewPlayerSlot->JoinType=p_stAddPlayerDesc->JoinType;
|
||
|
||
if( p_stAddPlayerDesc->Options != C_pNull
|
||
&& (p_stNewPlayerSlot->Options=pMalloc(strlen(p_stAddPlayerDesc->Options)+1)) != C_pNull)
|
||
strcpy(p_stNewPlayerSlot->Options,p_stAddPlayerDesc->Options);
|
||
else
|
||
p_stNewPlayerSlot->Options=C_pNull;
|
||
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_NetSer, "AddNewPlayer: OK for %lx", p_stAddPlayerDesc->m_tduxPlayerId);
|
||
#endif
|
||
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/*
|
||
------------------------------------------------------------------------------------------
|
||
SETTING CALLBACK FUNCTIONS :
|
||
------------------------------------------------------------------------------------------
|
||
*/
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_vInitializeGetTimeInfoFunction
|
||
Initialize a function that can give an information of time...
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : pfn_ulFunc : a pointer to a functions that returns an unsigned short and takes
|
||
no parameter
|
||
ulTicksPerSec: number of ticks per second this function returns
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : None
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : April 4, 96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
void _NET_CALLING_CONV_ NetLib_vInitializeGetTimeInfoFunction(NetLib_tdfnulGetTimeInfo pfn_ulFunc, unsigned long ulTicksPerSec)
|
||
{
|
||
g_pfn_ulNetGetTimeInfo = pfn_ulFunc;
|
||
gs_ulLocalTimeScale = ulTicksPerSec;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_vInitializeMemcopyFunction(void * (*pfn_vMemcpy)( void *dest, const void *src, size_t count ))
|
||
Initialize a memcpy function
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : pfn_vMemcpy: a pointer to a memcpy function
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : None
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : April 3, 96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
void _NET_CALLING_CONV_ NetLib_vInitializeMemcopyFunction(td_pfn_vNetMemcpy pfn_vMemcpy)
|
||
{
|
||
g_pfn_vNetMemcpy = pfn_vMemcpy;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_vInitializeRandomFunction(unsigned long (*pfn_ulFunc)(void))
|
||
Initialize a random function
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : pfn_ulFunc : a pointer to a functions that returns an unsigned long and takes
|
||
no parameter
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : None
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : April 3, 96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
void _NET_CALLING_CONV_ NetLib_vInitializeRandomFunction(NetLib_tdfnulRandom pfn_ulFunc)
|
||
{
|
||
g_pfn_ulNetRandom = pfn_ulFunc;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description :NetLib_vRegisterDisconnectCallback
|
||
Initialise the callback for disconnection
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : a pointer to a functions that takes an NetLib_tduxPlayerId for parameter and returns
|
||
nothing
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : None
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : April 4,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
void _NET_CALLING_CONV_ NetLib_vRegisterDisconnectCallback(NetLib_tdfnvDisconnectCallback pfn_vDisconnectCallback)
|
||
{
|
||
g_pfn_vDisconnectCallBack = pfn_vDisconnectCallback;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_vRegisterFilterSessionCallback
|
||
Registers the FilterSession callback
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : a pointer to a function that returns a NetLib_tdeErrorStatus and takes a pointer to a
|
||
NetLib_tdstSessionInfo variable
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : None
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : June 11,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
void _NET_CALLING_CONV_ NetLib_vRegisterFilterSessionCallback(NetLib_tdfneFilterSessionCallback eSessionFilter)
|
||
{
|
||
g_pfn_eSessionFilter = eSessionFilter;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_vRegisterPlayerConnectionRequestFilter
|
||
Registers the PlayerConnectionRequestFilter callback
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : a pointer to a function that returns a NetLib_tdeErrorStatus and takes a pointer to a
|
||
NetLib_tdstPlayerInfo variable
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : None
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : June 11,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
void _NET_CALLING_CONV_ NetLib_vRegisterPlayerConnectionRequestFilter(NetLib_tdfnePlayerConnectionRequestFilterCallback ePlayerConnectionRequestFilter)
|
||
{
|
||
g_pfn_ePlayerConnectionRequestFilter = ePlayerConnectionRequestFilter;
|
||
}
|
||
|
||
/*
|
||
------------------------------------------------------------------------------------------
|
||
SETTING NETLIB PARAMETERS:
|
||
------------------------------------------------------------------------------------------
|
||
*/
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : vNetSetSessionId
|
||
Sets a new session id
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : A new session id
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : None
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : September 17,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
void vNetSetSessionId(NetLib_tduxSessionId ulNewSessionId)
|
||
{
|
||
gs_stCurrentSession.uxSessionId = ulNewSessionId;
|
||
vLevel1SetSessionId(ulNewSessionId);
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description :vNetSetOwnPlayerId
|
||
Sets a new player id
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : The new player id
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : None
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : September 16,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
void vNetSetOwnPlayerId(NetLib_tduxPlayerId ulNewPlayerId)
|
||
{
|
||
M_ulNetPlayerIdSlot(pstNetGetOwnPlayerSlot()) = ulNewPlayerId;
|
||
/* Informs the level 1 of the index of the local player :*/
|
||
vLevel1SetPlayerId(ulNewPlayerId);
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : eNetCopyPlayerInfoFromId
|
||
Copy players info
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : a player id and a pointer to a netlib_tdstplayerinfo
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_NoError if no error occures
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : September,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eNetCopyPlayerInfoFromId(NetLib_tduxPlayerId ulPlayerId,long lParam)
|
||
{
|
||
tdstCopyInfo *p_stCopyInfo;
|
||
|
||
p_stCopyInfo = (tdstCopyInfo *)lParam;
|
||
p_stCopyInfo->uwCurrentPlayerSlot++;
|
||
return NetLib_eCopystPlayerInfo(&p_stCopyInfo->p_stPlayerInfoArray[p_stCopyInfo->uwCurrentPlayerSlot-1],pstNetGetPlayerSlot(ulPlayerId));
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : eNetInternalChangeMaxNbrOfPlayers
|
||
Changes the maximum number of players in the session (internal function)
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : uwNewMaxPlayers : the new value for the maximum players
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_NoError if no error occures
|
||
NetLib_E_es_AlreadyTooMuchPlayers if the new value is lower than the number
|
||
of players in the session : the value is not changed
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : October 28,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus eNetInternalChangeMaxNbrOfPlayers(unsigned short uwNewMaxPlayers)
|
||
{
|
||
unsigned short c_uwCurrentPlayer;
|
||
NetLib_tdstPlayerInfo *d_stNewPlayerInfo;
|
||
NetLib_tdstPlayerInfo stInvalidPlayer;
|
||
NetLib_tdstDoForAllDesc stForAllDesc;
|
||
tdstCopyInfo stCopyInfo;
|
||
NetLib_tdeErrorStatus eErrorReturned;
|
||
|
||
if(uwNewMaxPlayers <gs_stCurrentSession.uwNumberOfPlayers)
|
||
/* the number of players in the session is greater than the new max number of player specified*/
|
||
return NetLib_E_es_AlreadyTooMuchPlayers;
|
||
|
||
if(uwNewMaxPlayers == gs_stCurrentSession.uwMaxNumberOfPlayers) return NetLib_E_es_NoError;
|
||
|
||
eErrorReturned = eLevel1SetMaxNumberOfRemotePlayers((unsigned short)(uwNewMaxPlayers-1));
|
||
if(eErrorReturned != NetLib_E_es_NoError) return eErrorReturned;
|
||
|
||
d_stNewPlayerInfo = (NetLib_tdstPlayerInfo*)pMalloc(uwNewMaxPlayers*sizeof(NetLib_tdstPlayerInfo));
|
||
if(!d_stNewPlayerInfo)
|
||
{
|
||
eLevel1SetMaxNumberOfRemotePlayers((unsigned short)(gs_stCurrentSession.uwMaxNumberOfPlayers-1));
|
||
return NetLib_E_es_NotEnoughMemory;
|
||
}
|
||
|
||
stCopyInfo.p_stPlayerInfoArray = d_stNewPlayerInfo;
|
||
stCopyInfo.uwCurrentPlayerSlot = 0;
|
||
stForAllDesc.m_pfn_eForAll = eNetCopyPlayerInfoFromId;
|
||
stForAllDesc.m_lParameter = (long)&stCopyInfo;
|
||
stForAllDesc.m_eGoOnCondition = NetLib_E_es_NoError;
|
||
stForAllDesc.m_ucIncludeLocal = NetLib_C_ucIncludeLocalPlayer;
|
||
NetLib_eDoForAllPlayers(&stForAllDesc);
|
||
|
||
M_ulNetPlayerIdSlot(&stInvalidPlayer) = C_uxNetInvalidId;
|
||
stInvalidPlayer.uxPlayerDescriptionLength = 0;
|
||
stInvalidPlayer.pPlayerDescriptionData = C_pNull;
|
||
stInvalidPlayer.m_ucLittleBigEndian = 0;
|
||
stInvalidPlayer.Options =NULL;
|
||
|
||
for(c_uwCurrentPlayer=gs_stCurrentSession.uwNumberOfPlayers;c_uwCurrentPlayer<uwNewMaxPlayers;c_uwCurrentPlayer++)
|
||
{
|
||
NetLib_eCopystPlayerInfo(&d_stNewPlayerInfo[c_uwCurrentPlayer],&stInvalidPlayer);
|
||
}
|
||
|
||
vFree((tdpPointer)gs_stCurrentSession.d_stPlayerInfo);
|
||
gs_stCurrentSession.d_stPlayerInfo = d_stNewPlayerInfo;
|
||
/* Since DoForAllPlayers begins with the local player :*/
|
||
gs_stCurrentSession.uwIndexOfLocalPlayer = 0;
|
||
gs_stCurrentSession.uwMaxNumberOfPlayers = uwNewMaxPlayers;
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_eSetMaxNumberOfPlayers
|
||
Sets the maximum number of players in the session.
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : uwNewMaxPlayers : the new value for the maximum players
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_NoError if no error occures
|
||
NetLib_E_es_AlreadyTooMuchPlayers if the new value is lower than the number
|
||
of players in the session : the value is not changed
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : October 28,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ NetLib_eSetMaxNumberOfPlayers(unsigned short uwNewMaxPlayers)
|
||
{
|
||
NetLib_tdeErrorStatus eErrorReturned;
|
||
NetLib_tdstSendDesc stSendDesc;
|
||
tdpPointer pMsg;
|
||
|
||
eErrorReturned = eNetInternalChangeMaxNbrOfPlayers(uwNewMaxPlayers);
|
||
if(eErrorReturned != NetLib_E_es_NoError) return eErrorReturned;
|
||
if (gs_stCurrentSession.uwNumberOfPlayers>1)
|
||
{
|
||
/* Informs other players :*/
|
||
/* Sends a disconnection message to all the players :*/
|
||
stSendDesc.m_tduxRecipientId = C_uxNetBroadcastId;
|
||
stSendDesc.m_ulMaxWaitingTime = 0;
|
||
pMsg = pMalloc(sizeof(unsigned short));
|
||
if(!pMsg) return NetLib_E_es_PlayersNotInformed;
|
||
*((unsigned short *)pMsg) = uwNewMaxPlayers;
|
||
stSendDesc.m_pMessageData = pMsg;
|
||
stSendDesc.m_uwMessageLength = sizeof(unsigned short);
|
||
stSendDesc.m_uxPriority = NetLib_C_uxNoPriority;
|
||
stSendDesc.m_uxReplaceType = 0;
|
||
stSendDesc.m_uxReplaceFlag = 0;
|
||
stSendDesc.m_ucReadReceiptFlag = NetLib_C_ucReadReceiptRequired;
|
||
stSendDesc.m_ulMaxWaitingTime = gs_ulLocalTimeScale*2;
|
||
stSendDesc.m_stReadReceiptDesc.m_ulReemitFreq = gs_ulLocalTimeScale/2;
|
||
stSendDesc.m_stReadReceiptDesc.m_uxReadReceiptId = E_Net_mt_MaxNbrOfPlayers;
|
||
stSendDesc.m_stReadReceiptDesc.p_fnv_ReadReceiptCallback = (NetLib_tdfnvReadReceiptCallback)C_pNull;
|
||
|
||
eNetInternalSendMessage(&stSendDesc,E_Net_mt_MaxNbrOfPlayers);
|
||
vFree(pMsg);
|
||
}
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_eSetSessionDescription
|
||
Initialize the SessionDescriptor.
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : ucBufferLength : the length of the session descriptor.
|
||
pSessionDescrData : a buffer from which the session desriptor will be copied
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_NoError if no error occured
|
||
NetLib_E_es_NotEnoughMemory if the necessary memory couldn't be allocated.
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : April 1,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ NetLib_eSetSessionDescription(NetLib_tduxDescriptionLength uxBufferLength,tdpPointer pSessionDescrData,char b_InformOtherPlayers)
|
||
{
|
||
NetLib_tdstSendDesc stSendDesc;
|
||
tdpPointer pMsgBody;
|
||
tdpPointer pOriginData;
|
||
NetLib_tdeErrorStatus eErrorReturned;
|
||
|
||
if(gs_stCurrentSession.pSessionDescriptionData /*!= (tdpPointer)C_pNull*/)
|
||
{
|
||
vFree((tdpPointer)gs_stCurrentSession.pSessionDescriptionData);
|
||
gs_stCurrentSession.pSessionDescriptionData = C_pNull;
|
||
gs_stCurrentSession.uxSessionDescriptionLength = 0;
|
||
}
|
||
|
||
if(uxBufferLength)
|
||
{
|
||
gs_stCurrentSession.pSessionDescriptionData = (tdpPointer)pMalloc(uxBufferLength);
|
||
if(gs_stCurrentSession.pSessionDescriptionData /*!=(tdpPointer)C_pNull*/)
|
||
{
|
||
gs_stCurrentSession.uxSessionDescriptionLength = uxBufferLength;
|
||
g_pfn_vNetMemcpy(gs_stCurrentSession.pSessionDescriptionData,pSessionDescrData,uxBufferLength);
|
||
}
|
||
else
|
||
{
|
||
gs_stCurrentSession.pSessionDescriptionData = C_pNull;
|
||
gs_stCurrentSession.uxSessionDescriptionLength = 0;
|
||
return NetLib_E_es_NotEnoughMemory;
|
||
}
|
||
}
|
||
|
||
if(!b_InformOtherPlayers) return NetLib_E_es_NoError;
|
||
|
||
stSendDesc.m_tduxRecipientId = C_uxNetBroadcastId;
|
||
stSendDesc.m_ulMaxWaitingTime = 0;
|
||
pMsgBody=pMalloc(gs_stCurrentSession.uxSessionDescriptionLength+sizeof(NetLib_tduxDescriptionLength));
|
||
if(!pMsgBody) return NetLib_E_es_NotEnoughMemory;
|
||
|
||
pOriginData = pMsgBody;
|
||
|
||
*((NetLib_tduxDescriptionLength *)pOriginData)=gs_stCurrentSession.uxSessionDescriptionLength;
|
||
pOriginData = (tdpPointer)((NetLib_tduxDescriptionLength *)pOriginData + 1);
|
||
if(gs_stCurrentSession.uxSessionDescriptionLength)
|
||
g_pfn_vNetMemcpy(pOriginData,gs_stCurrentSession.pSessionDescriptionData,gs_stCurrentSession.uxSessionDescriptionLength);
|
||
|
||
stSendDesc.m_pMessageData = pMsgBody;
|
||
stSendDesc.m_uwMessageLength=gs_stCurrentSession.uxSessionDescriptionLength+sizeof(NetLib_tduxDescriptionLength);
|
||
|
||
stSendDesc.m_uxPriority = NetLib_C_uxNoPriority;
|
||
stSendDesc.m_uxReplaceType = 0;
|
||
stSendDesc.m_uxReplaceFlag = 0;
|
||
if (gs_uwMode==NetLib_Mode_Direct)
|
||
{
|
||
stSendDesc.m_ucReadReceiptFlag = NetLib_C_ucReadReceiptRequired;
|
||
stSendDesc.m_stReadReceiptDesc.m_ulMaxWaitingTime = 2*gs_ulLocalTimeScale;
|
||
stSendDesc.m_stReadReceiptDesc.m_ulReemitFreq = gs_ulLocalTimeScale/2;
|
||
stSendDesc.m_stReadReceiptDesc.m_uxReadReceiptId = E_Net_mt_SysSessionDescriptorChanged;
|
||
stSendDesc.m_stReadReceiptDesc.p_fnv_ReadReceiptCallback = (NetLib_tdfnvReadReceiptCallback)C_pNull;
|
||
}
|
||
else stSendDesc.m_ucReadReceiptFlag = NetLib_C_ucNoReadReceipt;
|
||
|
||
eErrorReturned = eNetInternalSendMessage(&stSendDesc,E_Net_mt_SysSessionDescriptorChanged);
|
||
vFree(pMsgBody);
|
||
return eErrorReturned;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_eSetLocalPlayerDescription
|
||
Initialize the Player descriptor of the local player.
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : ucBufferLength : the length of the player descriptor.
|
||
pPlayerDescrData : a buffer from which the player desriptor will be copied
|
||
b_InformOtherPlayers : if non zero, sends a message to all other players that the
|
||
local player description has changed...
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_NoError if no error occured
|
||
NetLib_E_es_NotEnoughMemory if the necessary memory couldn't be allocated.
|
||
NetLib_E_es_PlayersNotInformed if all the players couldn't be informed (can be due
|
||
either to a lack of memory or because the sending file of one player is full).
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : April 2,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ NetLib_eSetLocalPlayerDescription(NetLib_tduxDescriptionLength ucBufferLength,tdpPointer pPlayerDescrData,char b_InformOtherPlayers)
|
||
{
|
||
return NetLib_eSetPlayerDescription(NetLib_uxGetOwnPlayerId(),ucBufferLength,
|
||
pPlayerDescrData,b_InformOtherPlayers);
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_eSetPlayerDescription
|
||
Initialize the Player descriptor of the player specified by the first argument.
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : ulIdPlayer : the id of the player concerned
|
||
ucBufferLength : the length of the player descriptor.
|
||
pPlayerDescrData : a buffer from which the player desriptor will be copied
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_NoError if no error occured
|
||
NetLib_E_es_NotEnoughMemory if the necessary memory couldn't be allocated.
|
||
NetLib_E_es_UnknownPlayerId if the id is not in the session player list
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : April 9,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ NetLib_eSetPlayerDescription(NetLib_tduxPlayerId ulPlayerId,NetLib_tduxDescriptionLength ucBufferLength,tdpPointer pPlayerDescrData,char b_InformOtherPlayers)
|
||
{
|
||
NetLib_tdstPlayerInfo *p_stTheConcernedPlayer;
|
||
NetLib_tdstSendDesc stSendDesc;
|
||
tdpPointer pMsgBody;
|
||
tdpPointer pOriginData;
|
||
NetLib_tdeErrorStatus eErrorReturned;
|
||
|
||
p_stTheConcernedPlayer = pstNetGetPlayerSlot(ulPlayerId);
|
||
if(!p_stTheConcernedPlayer)
|
||
/* No player has been found*/
|
||
return NetLib_E_es_UnknownPlayerId;
|
||
|
||
if(p_stTheConcernedPlayer->pPlayerDescriptionData /*!= (tdpPointer)C_pNull*/)
|
||
{
|
||
/* if it allready has a descriptor, it must be destroyed : */
|
||
vFree((tdpPointer)p_stTheConcernedPlayer->pPlayerDescriptionData);
|
||
p_stTheConcernedPlayer->pPlayerDescriptionData = C_pNull;
|
||
p_stTheConcernedPlayer->uxPlayerDescriptionLength = 0;
|
||
}
|
||
|
||
if(ucBufferLength)
|
||
{
|
||
p_stTheConcernedPlayer->pPlayerDescriptionData = (tdpPointer)pMalloc(ucBufferLength);
|
||
if(p_stTheConcernedPlayer->pPlayerDescriptionData /*!= (tdpPointer)C_pNull*/)
|
||
{
|
||
p_stTheConcernedPlayer->uxPlayerDescriptionLength = ucBufferLength;
|
||
g_pfn_vNetMemcpy(p_stTheConcernedPlayer->pPlayerDescriptionData,pPlayerDescrData,ucBufferLength);
|
||
}
|
||
else
|
||
{
|
||
p_stTheConcernedPlayer->pPlayerDescriptionData = C_pNull;
|
||
p_stTheConcernedPlayer->uxPlayerDescriptionLength = 0;
|
||
return NetLib_E_es_NotEnoughMemory;
|
||
}
|
||
}
|
||
|
||
if(!b_InformOtherPlayers) return NetLib_E_es_NoError;
|
||
|
||
stSendDesc.m_tduxRecipientId = C_uxNetBroadcastId;
|
||
stSendDesc.m_ulMaxWaitingTime = 0;
|
||
pMsgBody=pMalloc(p_stTheConcernedPlayer->uxPlayerDescriptionLength+sizeof(NetLib_tduxDescriptionLength)
|
||
+sizeof(NetLib_tduxPlayerId));
|
||
|
||
if(!pMsgBody) return NetLib_E_es_NotEnoughMemory;
|
||
|
||
pOriginData = pMsgBody;
|
||
|
||
*((NetLib_tduxPlayerId *)pOriginData) = M_ulNetPlayerIdSlot(p_stTheConcernedPlayer);
|
||
pOriginData = (tdpPointer)((NetLib_tduxPlayerId*)pOriginData+1);
|
||
|
||
*((NetLib_tduxDescriptionLength *)pOriginData)=p_stTheConcernedPlayer->uxPlayerDescriptionLength;
|
||
pOriginData = (tdpPointer)((NetLib_tduxDescriptionLength *)pOriginData + 1);
|
||
|
||
if(p_stTheConcernedPlayer->uxPlayerDescriptionLength)
|
||
g_pfn_vNetMemcpy(pOriginData,p_stTheConcernedPlayer->pPlayerDescriptionData,
|
||
p_stTheConcernedPlayer->uxPlayerDescriptionLength);
|
||
|
||
stSendDesc.m_pMessageData=pMsgBody;
|
||
stSendDesc.m_uwMessageLength=p_stTheConcernedPlayer->uxPlayerDescriptionLength+
|
||
sizeof(NetLib_tduxDescriptionLength)+sizeof(NetLib_tduxPlayerId);
|
||
|
||
stSendDesc.m_uxPriority = NetLib_C_uxNoPriority;
|
||
stSendDesc.m_uxReplaceType = 0;
|
||
stSendDesc.m_uxReplaceFlag = 0;
|
||
if (gs_uwMode==NetLib_Mode_Direct)
|
||
{
|
||
stSendDesc.m_ucReadReceiptFlag = NetLib_C_ucReadReceiptRequired;
|
||
stSendDesc.m_stReadReceiptDesc.m_ulMaxWaitingTime = 2*gs_ulLocalTimeScale;
|
||
stSendDesc.m_stReadReceiptDesc.m_ulReemitFreq = gs_ulLocalTimeScale/2;
|
||
stSendDesc.m_stReadReceiptDesc.m_uxReadReceiptId = E_Net_mt_SysSessionDescriptorChanged;
|
||
stSendDesc.m_stReadReceiptDesc.p_fnv_ReadReceiptCallback = (NetLib_tdfnvReadReceiptCallback)C_pNull;
|
||
}
|
||
else stSendDesc.m_ucReadReceiptFlag = NetLib_C_ucNoReadReceipt;
|
||
|
||
eErrorReturned = eNetInternalSendMessage(&stSendDesc,E_Net_mt_SysPlayerDescriptorChanged);
|
||
vFree(pMsgBody);
|
||
return eErrorReturned;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_vSetAcceptWithoutListening
|
||
Sets the flag gs_ucAcceptWithoutListening
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : NetLib_C_ucAcceptWithoutListening a connection is accepted without a listening
|
||
call occured
|
||
NetLib_C_ucListenForAccept a connection is accepted only after a listening call
|
||
occured
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : none
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : July 9, 96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
void _NET_CALLING_CONV_ NetLib_vSetAcceptWithoutListening(unsigned char ucParam)
|
||
{
|
||
gs_ucAcceptWithoutListening = ucParam;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_eSetInternetSimulDelay
|
||
Sets the internet simulation delay
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : a Netlib_tdulTimeInfo
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : a NetLib_tdeErrorStatus code
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : September 16,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ NetLib_eSetInternetSimulDelay(NetLib_tdulTimeInfo ulTimeToWait,NetLib_tdulTimeInfo ulRandom)
|
||
{
|
||
if ((gs_ulInternetDelay || gs_ulInternetRandom) && !(ulTimeToWait || ulRandom))
|
||
{
|
||
eNetRemoveEngineFunction(iNetEngineInternetSimulation);
|
||
}
|
||
|
||
if (!(gs_ulInternetDelay || gs_ulInternetRandom) && (ulTimeToWait || ulRandom))
|
||
{
|
||
eNetAddEngineFunction(iNetEngineInternetSimulation);
|
||
}
|
||
|
||
if (ulTimeToWait || ulRandom) gs_ArtificialLatency=1;
|
||
else gs_ArtificialLatency=0;
|
||
|
||
gs_ulInternetDelay = ulTimeToWait;
|
||
gs_ulInternetRandom = ulRandom;
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_vSetPreSessionPlayerMaxWaitingTime
|
||
Initialize the maximum time the information about a player who
|
||
want to join the session must be kept...
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : ulMaxDeltaTime : a NetLib_tdulTimeInfo
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : None
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : April 4, 96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
void _NET_CALLING_CONV_ NetLib_vSetPreSessionPlayerMaxWaitingTime(NetLib_tdulTimeInfo ulMaxDeltaTime)
|
||
{
|
||
gs_tm_ulPreSessionPlayerMaxWaitingTime = ulMaxDeltaTime;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_vSetReemissionMode
|
||
Sets the reemission mode
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : 0 if the message is not resent after a full sys msg
|
||
1 if the message is resent after a full sys msg
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : None
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : June 18,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
void _NET_CALLING_CONV_ NetLib_vSetReemissionMode(unsigned char ucNewReemissionMode)
|
||
{
|
||
vLevel1SetReemissionMode(ucNewReemissionMode);
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : eNetInitLagsAndLatencies
|
||
Init lags and latencies procedure.
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : A player id
|
||
a long
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_NoError if no error occured
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : June 20,96
|
||
Author : Benoit Germain
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eNetInitLagsAndLatencies(NetLib_tduxPlayerId ulPlayerId, long lParam)
|
||
{
|
||
static unsigned short uwPlayerCount;
|
||
if(ulPlayerId == C_uxNetInvalidId) uwPlayerCount = 0;
|
||
else
|
||
{
|
||
gs_d_stTimeDeltas[uwPlayerCount].ulPlayerId = ulPlayerId;
|
||
gs_d_stTimeDeltas[uwPlayerCount].NumberOfRetries = 0;
|
||
gs_d_stTimeDeltas[uwPlayerCount].LastRetries = 0;
|
||
gs_d_stTimeDeltas[uwPlayerCount].ulLatency = 0;
|
||
gs_d_stTimeDeltas[uwPlayerCount].dDeltaWithLocal = 0.0;
|
||
gs_d_stTimeDeltas[uwPlayerCount].ulScaleOfRecipient = 0;
|
||
uwPlayerCount++;
|
||
}
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_eSampleLagsAndLatencies
|
||
Builds an internal table of approximate time lags and latencies between the machines. Each
|
||
machine is queried ucNumberOfRetries times, and answers are expected until ulTimeOut
|
||
is spent in the function or all answers are received.
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : number of times to retry the evaluation for each remote player
|
||
timeout to interrupt the calibration before all replies are received if this is the case
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_NoError if no error occured
|
||
NetLib_E_es_ShouldNotReach the message should not reach this function
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : June 20,96
|
||
Author : Benoit Germain
|
||
Modification : David Fournier
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ NetLib_eSampleLagsAndLatencies(unsigned short ucNumberOfRetries, unsigned long ulTimeOut)
|
||
{
|
||
NetLib_tdfnePlayerConnectionRequestFilterCallback pfn_eOldPlayerConnectionRequestFilter;
|
||
unsigned short uwCurrentPlayer, uwPlayerCount;
|
||
tdstNetMessage *p_stTimeMessage;
|
||
unsigned long ulInitialDateOfOperation;
|
||
NetLib_tdeErrorStatus eReturnValue;
|
||
NetLib_tdstDoForAllDesc stForAllDesc;
|
||
tdstNetPingMessage *pPingMes;
|
||
unsigned short countPing=0;
|
||
tdstNetTimeDelta *pTimeDelta;
|
||
short notFinish;
|
||
unsigned long LastTime=0,CurTime,Wait=50,MaxWait,iWait;
|
||
|
||
/* remember the time to handle timeouts */
|
||
ulInitialDateOfOperation = g_pfn_ulNetGetTimeInfo();
|
||
|
||
/* free any lingering array of deltas */
|
||
if(gs_d_stTimeDeltas) vFree((tdpPointer) gs_d_stTimeDeltas);
|
||
|
||
gs_d_stTimeDeltas = (tdstNetTimeDelta *) pMalloc(sizeof(tdstNetTimeDelta) * gs_stCurrentSession.uwMaxNumberOfPlayers);
|
||
|
||
/* if we could allocate the array and the message */
|
||
if (!gs_d_stTimeDeltas) return NetLib_E_es_NotEnoughMemory;
|
||
uwPlayerCount = gs_stCurrentSession.uwNumberOfPlayers;
|
||
|
||
/* remember the old function pointer */
|
||
pfn_eOldPlayerConnectionRequestFilter = g_pfn_ePlayerConnectionRequestFilter;
|
||
/* point to a function that always denies incoming player access while we sample the delays */
|
||
NetLib_vRegisterPlayerConnectionRequestFilter(eNetDenyPlayerAccess);
|
||
|
||
/* scan the player list of the current session */
|
||
eNetInitLagsAndLatencies(C_uxNetInvalidId,0l);
|
||
stForAllDesc.m_pfn_eForAll = eNetInitLagsAndLatencies;
|
||
stForAllDesc.m_lParameter = (long)&gs_d_stTimeDeltas;
|
||
stForAllDesc.m_eGoOnCondition = NetLib_E_es_NoError;
|
||
stForAllDesc.m_ucIncludeLocal = NetLib_C_ucIncludeLocalPlayer;
|
||
NetLib_eDoForAllPlayers(&stForAllDesc);
|
||
|
||
/* now we handle incoming delta reply messages */
|
||
gs_b_ucDeltaCalibrationIsEnabled = 1;
|
||
|
||
do
|
||
{
|
||
CurTime=GetTickCount();
|
||
if (CurTime>LastTime+50)
|
||
{
|
||
/* create a new message */
|
||
p_stTimeMessage=(tdstNetMessage *)pMalloc(sizeof(tdstNetMessage)+sizeof(tdstNetPingMessage));
|
||
if (p_stTimeMessage)
|
||
{
|
||
/* session and sender id, type of message */
|
||
p_stTimeMessage->uxSessionId = gs_stCurrentSession.uxSessionId;
|
||
p_stTimeMessage->uxRecipientId=C_uxNetBroadcastId;
|
||
p_stTimeMessage->uxSenderId=NetLib_uxGetOwnPlayerId();
|
||
p_stTimeMessage->eMessageType = E_Net_mt_SysTimeDeltaRequest;
|
||
p_stTimeMessage->uxPriority = NetLib_C_uxMaxPriority;
|
||
p_stTimeMessage->uxReplaceType = 0;
|
||
p_stTimeMessage->uxReplace = 1;
|
||
p_stTimeMessage->m_uxReadReceiptId = NetLib_C_ucNoReadReceipt;
|
||
/* we store our time in the message, and put room in it so that
|
||
* the recipient just has to fill it before replying. */
|
||
p_stTimeMessage->uwMessageSizeInBytes = sizeof(tdstNetPingMessage);
|
||
|
||
/* what time is it, expressed in universal lag units ? */
|
||
pPingMes=(tdstNetPingMessage *) (p_stTimeMessage + 1);
|
||
pPingMes->ulTimeOfSender = ulTimeInfoToLagUnits(g_pfn_ulNetGetTimeInfo(), gs_ulLocalTimeScale);
|
||
pPingMes->numPing=countPing++;
|
||
/* try to send the message */
|
||
if(gs_ArtificialLatency)
|
||
eReturnValue=eInternetSimuSendMessage(C_uxNetBroadcastId,p_stTimeMessage);
|
||
else
|
||
eReturnValue=eLevel1SendMessage(p_stTimeMessage,E_Net_pr_InvalidProtocol,C_uwNetInvalidChannel);
|
||
}
|
||
LastTime=CurTime;
|
||
}
|
||
NetLib_vEngine();
|
||
notFinish=0;
|
||
/* compute if all answer are arrived. */
|
||
MaxWait=0;
|
||
for (uwCurrentPlayer=0;uwCurrentPlayer<uwPlayerCount;uwCurrentPlayer++)
|
||
{
|
||
pTimeDelta=gs_d_stTimeDeltas+uwCurrentPlayer;
|
||
if (pTimeDelta->ulPlayerId!=NetLib_uxGetOwnPlayerId())
|
||
{
|
||
if (pTimeDelta->NumberOfRetries < ucNumberOfRetries) notFinish=1;
|
||
if (pTimeDelta->NumberOfRetries)
|
||
{
|
||
iWait=pTimeDelta->ulLatency/pTimeDelta->NumberOfRetries;
|
||
}
|
||
else iWait=50;
|
||
if (iWait>MaxWait) MaxWait=iWait;
|
||
}
|
||
}
|
||
Wait=MaxWait;
|
||
}while ((notFinish) && (g_pfn_ulNetGetTimeInfo() < ulInitialDateOfOperation + ulTimeOut));
|
||
|
||
/* restore the old function pointer */
|
||
NetLib_vRegisterPlayerConnectionRequestFilter(pfn_eOldPlayerConnectionRequestFilter);
|
||
|
||
/* now we no longer handle incoming delta reply messages */
|
||
gs_b_ucDeltaCalibrationIsEnabled = 0;
|
||
|
||
/* compute the average time delta and latency for each remote player. Note that each player keeps
|
||
* its own ucNumberOfRetries because we cannot be sure that all answers will arrive. Only the
|
||
* local player has no answer because we know the delta and latency with ourself are zero. */
|
||
for (uwCurrentPlayer=0;uwCurrentPlayer<uwPlayerCount;uwCurrentPlayer ++)
|
||
{
|
||
if (gs_d_stTimeDeltas[uwCurrentPlayer].NumberOfRetries)
|
||
{
|
||
/* note that the delta is expressed in C_ulUniversalLagUnit th of second */
|
||
gs_d_stTimeDeltas[uwCurrentPlayer].dDeltaWithLocal/=gs_d_stTimeDeltas[uwCurrentPlayer].NumberOfRetries;
|
||
gs_d_stTimeDeltas[uwCurrentPlayer].ulLatency/=gs_d_stTimeDeltas[uwCurrentPlayer].NumberOfRetries;
|
||
|
||
#if defined(NET_USE_DEBUG)
|
||
vDebugSISISISI(Net_C_Debug_NetSer,"Player",gs_d_stTimeDeltas[uwCurrentPlayer].ulPlayerId,
|
||
"Number of retries",gs_d_stTimeDeltas[uwCurrentPlayer].NumberOfRetries,
|
||
"Delta",(long)gs_d_stTimeDeltas[uwCurrentPlayer].dDeltaWithLocal,
|
||
"Latency",gs_d_stTimeDeltas[uwCurrentPlayer].ulLatency);
|
||
#endif /* NET_USE_DEBUG */
|
||
}
|
||
}
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/*
|
||
------------------------------------------------------------------------------------------
|
||
GETTING INFORMATION:
|
||
------------------------------------------------------------------------------------------
|
||
*/
|
||
NetLib_tducBigLittleEndian _NET_CALLING_CONV_ NetLib_ucGetPlayerLittleBigEndian(NetLib_tduxPlayerId ulPlayerId)
|
||
{
|
||
NetLib_tdstPlayerInfo *p_stPlayerConcerned;
|
||
p_stPlayerConcerned = pstNetGetPlayerSlot(ulPlayerId);
|
||
if(!p_stPlayerConcerned) return NetLib_ucGetLittleBigEndian();
|
||
else return p_stPlayerConcerned->m_ucLittleBigEndian;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_eIsPlayerOverInternet
|
||
returns the id of the session
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : A player Id
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_True if the player is over internet,
|
||
NetLib_E_es_False if not,
|
||
and if player id is C_InvalidPlayerId, the return value is true iff at least one
|
||
of the players is over internet
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : December 17, 96
|
||
Author : Christophe Roguet
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ NetLib_eIsPlayerOverInternet(NetLib_tduxPlayerId ulPlayerId)
|
||
{
|
||
unsigned short uwCount;
|
||
|
||
NetLib_tdstPlayerInfo *p_stPlayerConcerned;
|
||
|
||
if(ulPlayerId==C_uxNetInvalidId)
|
||
{ /* is there any one over internet ? */
|
||
for(uwCount = 0; uwCount <gs_stCurrentSession.uwNumberOfPlayers; uwCount++)
|
||
if(gs_stCurrentSession.d_stPlayerInfo[uwCount].m_bOverInternet)
|
||
return NetLib_E_es_True;
|
||
return NetLib_E_es_False;
|
||
}
|
||
else
|
||
{ /* is this particular player over internet ? */
|
||
p_stPlayerConcerned = pstNetGetPlayerSlot(ulPlayerId);
|
||
if(p_stPlayerConcerned)
|
||
if(p_stPlayerConcerned->m_bOverInternet)
|
||
return NetLib_E_es_True;
|
||
else
|
||
return NetLib_E_es_False;
|
||
|
||
return NetLib_E_es_UnknownPlayerId;
|
||
}
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_uxGetSessionId
|
||
returns the id of the session
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : None
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : the Id of the session
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : April 2,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tduxSessionId _NET_CALLING_CONV_ NetLib_uxGetSessionId(void)
|
||
{
|
||
return gs_stCurrentSession.uxSessionId;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_eGetSessionDescription
|
||
Retrieves the SessionDescriptor.
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : p_ucBufferLength : the length of the maximum session descriptor to be read
|
||
pSessionDescrData : a buffer in which the session desriptor will be copied
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_NoError : if no errors occured.
|
||
NetLib_E_es_NotEnoughMemory : if the buffer given was too short to contain the descriptor
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : April 1,96
|
||
Author : Albert Pais
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Comment :
|
||
Be aware to allocate the pSessionDescrData buffer with enough size
|
||
(see ucGetSessionDescriptorLength). If it does not have enough size, only
|
||
the number of bytes given by the first parameter are copied to the buffer.
|
||
When the functions returns, p_ucBufferLength contains the number of
|
||
bytes effectively read.
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ NetLib_eGetSessionDescription(NetLib_tduxDescriptionLength *p_ucBufferLength,tdpPointer pSessionDescrData)
|
||
{
|
||
NetLib_tdeErrorStatus eErrorReturned;
|
||
if(gs_stCurrentSession.uxSessionDescriptionLength<=*p_ucBufferLength)
|
||
{
|
||
*p_ucBufferLength = gs_stCurrentSession.uxSessionDescriptionLength;
|
||
eErrorReturned = NetLib_E_es_NoError;
|
||
}
|
||
else
|
||
{
|
||
eErrorReturned = NetLib_E_es_NotEnoughMemory;
|
||
}
|
||
|
||
if(*p_ucBufferLength)
|
||
{
|
||
g_pfn_vNetMemcpy(pSessionDescrData,gs_stCurrentSession.pSessionDescriptionData,*p_ucBufferLength);
|
||
}
|
||
return eErrorReturned;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_uxGetSessionDescriptionLength
|
||
Returns the length of the Session descriptor.
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : None
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : The length of the session descriptor
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : April 2,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tduxDescriptionLength _NET_CALLING_CONV_ NetLib_uxGetSessionDescriptionLength(void)
|
||
{
|
||
return gs_stCurrentSession.uxSessionDescriptionLength;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_uwGetMaxNumberOfPlayers
|
||
Returns the maximum number of players in the session
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : None
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : the maximum number of players in the session
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : April 3,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
unsigned short _NET_CALLING_CONV_ NetLib_uwGetMaxNumberOfPlayers(void)
|
||
{
|
||
return gs_stCurrentSession.uwMaxNumberOfPlayers;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_uwGetTotalNumberPlayer
|
||
Returns the number of players in the session including the local player
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : None
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : the number of players in the session, including the local player
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : April 2,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
unsigned short _NET_CALLING_CONV_ NetLib_uwGetTotalNumberPlayer(void)
|
||
{
|
||
return gs_stCurrentSession.uwNumberOfPlayers;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_uxGetOwnPlayerId
|
||
returns the id of the local player
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : None
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : the Id of the local player
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : April 2,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tduxPlayerId _NET_CALLING_CONV_ NetLib_uxGetOwnPlayerId(void)
|
||
{
|
||
return M_ulNetPlayerIdSlot(&gs_stCurrentSession.d_stPlayerInfo[gs_stCurrentSession.uwIndexOfLocalPlayer]);
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_eGetPlayersIdFromSession
|
||
Returns the players Id in the session including the local player
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : d_ulListPlayersId : an array that will containt the list of the Id
|
||
uwNumberOfPlayers : the number of players expected
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_NoError if no error occured
|
||
NetLib_E_es_NumberOfPlayerLarger : if the number of player contained in the session is
|
||
larger thant the one specified in the function parameter
|
||
NetLib_E_es_NumberOfPlayerSmaller : if the number of player contained in the session is
|
||
smaller thant the one specified in the function parameter
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : April 2,96
|
||
Author : Albert Pais
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Comment :
|
||
Be carreful to send the correct uwNumberOfPlayers and to alloc enough for
|
||
the d_ulListPlayersId. see uwGetTotalNumberPlayer()
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ NetLib_eGetPlayersIdFromSession(NetLib_tduxPlayerId *d_ulListPlayersId,unsigned short *p_uwNumberOfPlayers)
|
||
{
|
||
NetLib_tdeErrorStatus eErrorReturned;
|
||
unsigned short c_uwCurPlay;
|
||
unsigned short c_uwCount;
|
||
|
||
eErrorReturned = NetLib_E_es_NoError;
|
||
if(*p_uwNumberOfPlayers < gs_stCurrentSession.uwNumberOfPlayers)
|
||
{
|
||
eErrorReturned = NetLib_E_es_NumberOfPlayerLarger;
|
||
}
|
||
else if(*p_uwNumberOfPlayers > gs_stCurrentSession.uwNumberOfPlayers)
|
||
{
|
||
*p_uwNumberOfPlayers = gs_stCurrentSession.uwNumberOfPlayers;
|
||
eErrorReturned = NetLib_E_es_NumberOfPlayerSmaller;
|
||
}
|
||
|
||
/* Then build and return the list of Ids*/
|
||
d_ulListPlayersId[0] = NetLib_uxGetOwnPlayerId();
|
||
c_uwCurPlay = NetLib_uwGetFirstRemotePlayerIdPosition();
|
||
c_uwCount = 1;
|
||
while ((c_uwCount < *p_uwNumberOfPlayers) && (c_uwCurPlay != NetLib_C_uwInvalidPosition))
|
||
{
|
||
d_ulListPlayersId[c_uwCount] = NetLib_uxGetNextRemotePlayerId(&c_uwCurPlay);
|
||
c_uwCount++;
|
||
}
|
||
|
||
if(c_uwCount>=*p_uwNumberOfPlayers) eErrorReturned = NetLib_E_es_NumberOfPlayerSmaller;
|
||
|
||
return eErrorReturned;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_uwGetFirstRemotePlayerIdPosition
|
||
Returns the index of the first remote player
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : None
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : The index of the first remote player, if there is remote player
|
||
the function returns -1
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : April 29,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
unsigned short _NET_CALLING_CONV_ NetLib_uwGetFirstRemotePlayerIdPosition(void)
|
||
{
|
||
unsigned short uwIndexReturned;
|
||
|
||
uwIndexReturned =0;
|
||
while ((uwIndexReturned < gs_stCurrentSession.uwMaxNumberOfPlayers) &&
|
||
((M_ulNetPlayerIdSlot(&gs_stCurrentSession.d_stPlayerInfo[uwIndexReturned]) == C_uxNetInvalidId)
|
||
||(uwIndexReturned == gs_stCurrentSession.uwIndexOfLocalPlayer)))
|
||
uwIndexReturned ++;
|
||
if(uwIndexReturned >= gs_stCurrentSession.uwMaxNumberOfPlayers)
|
||
uwIndexReturned = NetLib_C_uwInvalidPosition ;
|
||
|
||
return uwIndexReturned;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_ulGetNextRemotePlayerId
|
||
Returns the player id which position is given by the argument
|
||
and increase the argument to the next position where there is a remote
|
||
player
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : p_uwStartPosition a pointer to the starting position. When the function returns,
|
||
it contains the next position to the players array of the current session that
|
||
contains information about a remote player. If there is no next position, it is
|
||
set to -1
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : the id of the player at the uwStartPosition if it is a remote player,
|
||
otherwise returns C_uxNetInvalidId
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : April 29,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tduxPlayerId _NET_CALLING_CONV_ NetLib_uxGetNextRemotePlayerId(unsigned short*p_uwStartPosition)
|
||
{
|
||
NetLib_tduxPlayerId ulPlayerIdReturned;
|
||
|
||
if(*p_uwStartPosition >=gs_stCurrentSession.uwMaxNumberOfPlayers)
|
||
{
|
||
*p_uwStartPosition = NetLib_C_uwInvalidPosition;
|
||
return C_uxNetInvalidId;
|
||
}
|
||
|
||
if(*p_uwStartPosition == gs_stCurrentSession.uwIndexOfLocalPlayer)
|
||
ulPlayerIdReturned = C_uxNetInvalidId;
|
||
else
|
||
ulPlayerIdReturned = M_ulNetPlayerIdSlot(&gs_stCurrentSession.d_stPlayerInfo[*p_uwStartPosition]);
|
||
|
||
*p_uwStartPosition = *p_uwStartPosition +1;
|
||
while ((*p_uwStartPosition < gs_stCurrentSession.uwMaxNumberOfPlayers)
|
||
&&((M_ulNetPlayerIdSlot(&gs_stCurrentSession.d_stPlayerInfo[*p_uwStartPosition]) == C_uxNetInvalidId)
|
||
||(*p_uwStartPosition == gs_stCurrentSession.uwIndexOfLocalPlayer)))
|
||
(*p_uwStartPosition)++;
|
||
if(*p_uwStartPosition >= gs_stCurrentSession.uwMaxNumberOfPlayers)
|
||
*p_uwStartPosition = NetLib_C_uwInvalidPosition ;
|
||
|
||
return ulPlayerIdReturned;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_eGetPlayerDescription
|
||
Retrieves the Player descriptor of the local player.
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : p_ucBufferLength : the length of the maximum player descriptor to be read
|
||
pPlayerDescrData : a buffer in which the player desriptor will be copied
|
||
ulPlayerId : the player concerned
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_NoError : if no errors occured.
|
||
NetLib_E_es_NotEnoughMemory : if the buffer given was too short to contain the descriptor
|
||
NetLib_E_es_UnknownPlayerId : if the player id specified is unknown
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : April 2,96
|
||
Author : Albert Pais
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Comment :
|
||
Be aware to allocate the pPlayerDescrData buffer with enough size
|
||
(see ucGetPlayerDescriptorLength). If it does not have enough size, only
|
||
the number of bytes given by the first parameter are copied to the buffer.
|
||
When the functions returns, p_ucBufferLength contains the number of
|
||
bytes effectively read.
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ NetLib_eGetPlayerDescription(NetLib_tduxDescriptionLength *p_ucBufferLength,tdpPointer pPlayerDescrData,NetLib_tduxPlayerId ulPlayerId)
|
||
{
|
||
NetLib_tdeErrorStatus eErrorReturned;
|
||
NetLib_tdstPlayerInfo *p_stThePlayer;
|
||
|
||
if (ulPlayerId==C_uxNetInvalidId) return NetLib_E_es_UnknownPlayerId;
|
||
|
||
if((p_stThePlayer = pstNetGetPlayerSlot(ulPlayerId))==0)
|
||
return NetLib_E_es_UnknownPlayerId;
|
||
|
||
if(p_stThePlayer->uxPlayerDescriptionLength<=*p_ucBufferLength)
|
||
{
|
||
*p_ucBufferLength = p_stThePlayer->uxPlayerDescriptionLength;
|
||
eErrorReturned = NetLib_E_es_NoError;
|
||
}
|
||
else eErrorReturned = NetLib_E_es_NotEnoughMemory;
|
||
|
||
if(*p_ucBufferLength)
|
||
g_pfn_vNetMemcpy(pPlayerDescrData,p_stThePlayer->pPlayerDescriptionData,*p_ucBufferLength);
|
||
|
||
return eErrorReturned;
|
||
}
|
||
|
||
/*///////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_uxGetPlayerDescriptionLength
|
||
Returns the length of the Player 's descriptor specified by the parameter
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : ulPlayerId : the player concerned
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : The length of the session descriptor
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : April 2,96
|
||
Author : Albert Pais
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Comment :
|
||
If the player given in parameter is not found, the function returns 0. be careful
|
||
because if the player does not have a player descriptor, it also returns 0
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tduxDescriptionLength _NET_CALLING_CONV_ NetLib_uxGetPlayerDescriptionLength(NetLib_tduxPlayerId ulPlayerId)
|
||
{
|
||
NetLib_tdstPlayerInfo *p_stThePlayer;
|
||
p_stThePlayer = pstNetGetPlayerSlot(ulPlayerId);
|
||
if(p_stThePlayer) return p_stThePlayer->uxPlayerDescriptionLength;
|
||
else return 0;
|
||
}
|
||
|
||
/* Get a parameter in a string. */
|
||
static void getStringParam(char *string,char *clef,char *valor,unsigned short sizeval)
|
||
{
|
||
char *deb,*fin;
|
||
unsigned short s;
|
||
if (string)
|
||
{
|
||
deb=strstr(string,clef);
|
||
if (deb)
|
||
{
|
||
deb=strchr(deb+1,'\'');
|
||
if (deb++)
|
||
{
|
||
fin=strchr(deb+1,'\'');
|
||
if (fin)
|
||
{
|
||
s=fin-deb;
|
||
if (s>sizeval-1) s=sizeval-1;
|
||
memcpy(valor,deb,s);
|
||
valor[s]=0;
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
*valor=0;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_eGetPlayerName
|
||
Retrieves the player name.
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : ulPlayerId : the player concerned
|
||
Output : NULL : if errors occured.
|
||
adress of options otherwise.
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
void _NET_CALLING_CONV_ NetLib_eGetPlayerName(NetLib_tduxPlayerId ulPlayerId,char *Name,unsigned short SizeMaxName)
|
||
{
|
||
NetLib_tdstPlayerInfo *p_stThePlayer;
|
||
if ((p_stThePlayer=pstNetGetPlayerSlot(ulPlayerId))==NULL) return;
|
||
getStringParam(p_stThePlayer->Options,"name",Name,SizeMaxName);
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_eGetGameName
|
||
Retrieves the game name.
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : none.
|
||
Output : NULL : if errors occured.
|
||
adress of options otherwise.
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
void _NET_CALLING_CONV_ NetLib_eGetGameName(char *Name,unsigned short SizeMaxName)
|
||
{
|
||
getStringParam(gs_stCurrentSession.GameOptions,"name",Name,SizeMaxName);
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_ulTellRemoteTimerValue
|
||
gives the estimated value of a remote player's timer for a given local time.
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : ulRemoteId: the remote player's id
|
||
ulLocalTimerValue: the local time
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : 0 if the remote player is unknown
|
||
the local time if the specified player is the local player
|
||
else another time
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : July 2,1996
|
||
Author : Benoit Germain
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdulTimeInfo _NET_CALLING_CONV_ NetLib_ulTellRemoteTimerValue(NetLib_tduxPlayerId ulRemoteId, NetLib_tdulTimeInfo ulLocalTimerValue)
|
||
{
|
||
unsigned short c_uwCurrentIndex;
|
||
|
||
if (ulRemoteId == C_uxNetInvalidId || !gs_d_stTimeDeltas) return 0;
|
||
else if (ulRemoteId == NetLib_uxGetOwnPlayerId()) return ulLocalTimerValue;
|
||
else
|
||
{
|
||
/* Retrieves the index of the remote player:*/
|
||
c_uwCurrentIndex = 0;
|
||
while ((c_uwCurrentIndex < gs_stCurrentSession.uwMaxNumberOfPlayers)
|
||
&& (gs_d_stTimeDeltas[c_uwCurrentIndex].ulPlayerId != ulRemoteId))
|
||
{
|
||
c_uwCurrentIndex ++;
|
||
}
|
||
/* if we found a corresponding player in our database */
|
||
if (c_uwCurrentIndex < gs_stCurrentSession.uwMaxNumberOfPlayers)
|
||
{
|
||
NetLib_tdulTimeInfo res=ulLagUnitsToTimeInfo(ulTimeInfoToLagUnits(ulLocalTimerValue, gs_ulLocalTimeScale)
|
||
- (long)gs_d_stTimeDeltas[c_uwCurrentIndex].dDeltaWithLocal,
|
||
gs_d_stTimeDeltas[c_uwCurrentIndex].ulScaleOfRecipient);
|
||
#if defined(NET_USE_DEBUG)
|
||
vDebugSI(Net_C_Debug_NetSer,"Estimate",res);
|
||
#endif /* NET_USE_DEBUG */
|
||
|
||
return res;
|
||
}
|
||
else return 0;
|
||
}
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_ulTellRemotePlayerLag
|
||
gives the estimated value of a remote player's latency in local time info value
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : ulRemoteId: the remote player's id
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : 0 if the remote player is unknown or the local player
|
||
else another time
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : July 4,1996
|
||
Author : Benoit Germain
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdulTimeInfo _NET_CALLING_CONV_ NetLib_ulTellRemotePlayerLag(NetLib_tduxPlayerId ulRemoteId,unsigned short *pNumberOfReplies)
|
||
{
|
||
unsigned short c_uwCurrentIndex;
|
||
|
||
if (pNumberOfReplies) *pNumberOfReplies=0;
|
||
if ((ulRemoteId==C_uxNetInvalidId) || (ulRemoteId==NetLib_uxGetOwnPlayerId()) ||
|
||
!gs_d_stTimeDeltas) return 0;
|
||
|
||
c_uwCurrentIndex = 0;
|
||
while ((c_uwCurrentIndex<gs_stCurrentSession.uwMaxNumberOfPlayers)
|
||
&& (gs_d_stTimeDeltas[c_uwCurrentIndex].ulPlayerId != ulRemoteId))
|
||
{
|
||
c_uwCurrentIndex ++;
|
||
}
|
||
/* if we found a corresponding player in our database */
|
||
if (c_uwCurrentIndex < gs_stCurrentSession.uwMaxNumberOfPlayers)
|
||
{
|
||
if (pNumberOfReplies) *pNumberOfReplies=gs_d_stTimeDeltas[c_uwCurrentIndex].NumberOfRetries;
|
||
return ulLagUnitsToTimeInfo(gs_d_stTimeDeltas[c_uwCurrentIndex].ulLatency, gs_ulLocalTimeScale);
|
||
}
|
||
else return 0;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_eAcceptWithoutListening
|
||
Gets the flag gs_ucAcceptWithoutListening
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : None
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_C_ucAcceptWithoutListening: a connection is accepted without a listening
|
||
call occured
|
||
NetLib_C_ucListenForAccept: a connection is accepted only after a listening call
|
||
occured
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : July 9, 96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ NetLib_eAcceptWithoutListening(void)
|
||
{
|
||
switch(gs_ucAcceptWithoutListening)
|
||
{
|
||
case NetLib_C_ucAcceptWithoutListening:
|
||
return NetLib_E_es_True;
|
||
|
||
case NetLib_C_ucListenForAccept:
|
||
return NetLib_E_es_False;
|
||
|
||
default :
|
||
return NetLib_E_es_UnknownError;
|
||
}
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : uwNetGetPlayerIndex
|
||
retrieves the index of a player
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : A player id
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : An index if the player is found
|
||
otherwise NetLib_C_uwInvalidPosition
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : September 6, 96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
unsigned short _NET_CALLING_CONV_ uwNetGetPlayerIndex(NetLib_tduxPlayerId ulPlayerId)
|
||
{
|
||
unsigned short c_uwCount;
|
||
c_uwCount = gs_stCurrentSession.uwMaxNumberOfPlayers-1;
|
||
while ((c_uwCount!=NetLib_C_uwInvalidPosition)
|
||
&&(M_ulNetPlayerIdSlot(&gs_stCurrentSession.d_stPlayerInfo[c_uwCount])!=ulPlayerId))
|
||
c_uwCount--;
|
||
|
||
return c_uwCount;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : pstNetGetPlayerSlot
|
||
Returns a pointer to the slot of the player
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : A player id
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : a pointer if the player is found
|
||
otherwise Null
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : September 6, 96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdstPlayerInfo * _NET_CALLING_CONV_ pstNetGetPlayerSlot(NetLib_tduxPlayerId ulPlayerId)
|
||
{
|
||
unsigned short c_uwCount;
|
||
if((c_uwCount = uwNetGetPlayerIndex(ulPlayerId))!=NetLib_C_uwInvalidPosition)
|
||
return &(gs_stCurrentSession.d_stPlayerInfo[c_uwCount]);
|
||
else
|
||
return (NetLib_tdstPlayerInfo * )C_pNull;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : pstNetGetOwnPlayerSlot
|
||
Returns a pointer to the slot of the local player
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : None
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : a pointer if the player is found
|
||
otherwise Null
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : September 23, 96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdstPlayerInfo * _NET_CALLING_CONV_ pstNetGetOwnPlayerSlot(void)
|
||
{
|
||
if(gs_stCurrentSession.uwIndexOfLocalPlayer<=gs_stCurrentSession.uwMaxNumberOfPlayers)
|
||
return &gs_stCurrentSession.d_stPlayerInfo[gs_stCurrentSession.uwIndexOfLocalPlayer];
|
||
else
|
||
return (NetLib_tdstPlayerInfo * )C_pNull;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description :NetLib_eCopystPlayerInfo
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : a dest and a source
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : A NetLib_tdeErrorStatus
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : September 16,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus NetLib_eCopystPlayerInfo(NetLib_tdstPlayerInfo *p_stDest,NetLib_tdstPlayerInfo *p_stSrc)
|
||
{
|
||
memcpy(p_stDest,p_stSrc,sizeof(NetLib_tdstPlayerInfo));
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : void vNetClearSessionInfo
|
||
Clear differents pointer of the object given in parameter
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : pSessionToClear : a pointer to the session to clear
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : None
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : April 3,96
|
||
Author : Albert Pais
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Comment :
|
||
This function frees the memory used for :
|
||
-> the session information
|
||
-> the player information for each player
|
||
-> the player information array.
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
void vNetClearSessionInfo(NetLib_tdstSessionInfo *pSessionToClear)
|
||
{
|
||
unsigned short c_uwCount;
|
||
|
||
if(pSessionToClear /*!=(NetLib_tdstSessionInfo*)C_pNull*/)
|
||
{
|
||
pSessionToClear->uxSessionId=C_uxNetInvalidId;
|
||
pSessionToClear->uxSessionDescriptionLength = 0;
|
||
|
||
if(pSessionToClear->pSessionDescriptionData /*!=(tdpPointer)C_pNull*/)
|
||
{
|
||
vFree((tdpPointer)pSessionToClear->pSessionDescriptionData);
|
||
pSessionToClear->pSessionDescriptionData = (tdpPointer)C_pNull;
|
||
}/* End of if(pSessionToClear->pSessionDescriptionData !=C_pNull)*/
|
||
if(pSessionToClear->d_stPlayerInfo /*!=(NetLib_tdstPlayerInfo*)C_pNull*/)
|
||
{
|
||
/* Clear players informations*/
|
||
/* First Player descriptions*/
|
||
for(c_uwCount = 0; c_uwCount < pSessionToClear->uwMaxNumberOfPlayers; c_uwCount++)
|
||
{
|
||
pSessionToClear->d_stPlayerInfo[c_uwCount].uxPlayerDescriptionLength = 0;
|
||
if(pSessionToClear->d_stPlayerInfo[c_uwCount].pPlayerDescriptionData /*!=(tdpPointer)C_pNull*/)
|
||
{
|
||
vFree((tdpPointer)pSessionToClear->d_stPlayerInfo[c_uwCount].pPlayerDescriptionData);
|
||
pSessionToClear->d_stPlayerInfo[c_uwCount].pPlayerDescriptionData = (tdpPointer)C_pNull;
|
||
}/* End of if(pSessionToClear.d_stPlayerInfo[c_uwCount]...*/
|
||
}/* end of for */
|
||
/* Now clear the array of playerInfo :*/
|
||
vFree((tdpPointer)pSessionToClear->d_stPlayerInfo);
|
||
pSessionToClear->d_stPlayerInfo = (NetLib_tdstPlayerInfo*)C_pNull;
|
||
}/* end of if(pSessionToClear.d_stPlayerInfo != C_pNull) */
|
||
pSessionToClear->uwNumberOfPlayers = 0;
|
||
pSessionToClear->uwMaxNumberOfPlayers = 0;
|
||
pSessionToClear->uwIndexOfLocalPlayer = (unsigned short)-1;
|
||
}/* End of if(pSessionToClear != C_pNull) */
|
||
}/* End of function */
|
||
|
||
/*
|
||
------------------------------------------------------------------------------------------
|
||
GETTING SESSIONS :
|
||
------------------------------------------------------------------------------------------
|
||
*/
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_eOpenGetActiveSessions
|
||
Opens the request session mode
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : uwNumberOfSessionWaited : the number of session expected
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : An error code or NetLib_E_es_NoError if no error occured
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : August 19,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ NetLib_eOpenGetActiveSessions(unsigned short uwNumberOfSessionWaited,
|
||
NetLib_tdulTimeInfo ulFreq,NetLib_tduxDescriptionLength ucMaxPlayerInfo)
|
||
{
|
||
unsigned short c_uwCount;
|
||
|
||
if(!uwNumberOfSessionWaited) return NetLib_E_es_ShouldNotReach;
|
||
|
||
/* Erase previous data :*/
|
||
/* Previous sessions found :*/
|
||
NetLib_eCloseAndResetGetActiveSessions();
|
||
|
||
/* Reinit :*/
|
||
gs_eListeningMode = E_Net_LisMod_ON;
|
||
if(eNetAddEngineFunction(iNetEngineGetActiveSession)!=NetLib_E_es_NoError)
|
||
{
|
||
NetLib_eCloseAndResetGetActiveSessions();
|
||
return NetLib_E_es_NotEnoughMemory;
|
||
}
|
||
|
||
gs_dstSessions = (NetLib_tdstSessionInfo *)pMalloc(sizeof(NetLib_tdstSessionInfo)*uwNumberOfSessionWaited);
|
||
gs_dpucWaitForReply = (unsigned char *)pMalloc(sizeof(unsigned char)*uwNumberOfSessionWaited);
|
||
|
||
if (!(gs_dstSessions /*!=(NetLib_tdstSessionInfo*)C_pNull*/) ||
|
||
!(gs_dpucWaitForReply /*!= (unsigned char**)C_pNull*/))
|
||
{
|
||
NetLib_eCloseAndResetGetActiveSessions();
|
||
return NetLib_E_es_NotEnoughMemory;
|
||
}
|
||
|
||
gs_uwNumberOfSessionsExpected = uwNumberOfSessionWaited;
|
||
|
||
/* there was enough memory :*/
|
||
/* Initialize the array :*/
|
||
for(c_uwCount = 0; c_uwCount < uwNumberOfSessionWaited;c_uwCount++)
|
||
{
|
||
gs_dstSessions[c_uwCount].uxSessionId=C_uxNetInvalidId;
|
||
gs_dstSessions[c_uwCount].uxSessionDescriptionLength=0;
|
||
gs_dstSessions[c_uwCount].pSessionDescriptionData=(tdpPointer)C_pNull;
|
||
gs_dstSessions[c_uwCount].uwMaxNumberOfPlayers = 0;
|
||
gs_dstSessions[c_uwCount].uwNumberOfPlayers = 0;
|
||
gs_dstSessions[c_uwCount].d_stPlayerInfo = (NetLib_tdstPlayerInfo*)C_pNull;
|
||
gs_dstSessions[c_uwCount].uwIndexOfLocalPlayer = (unsigned short)-1;
|
||
gs_dpucWaitForReply[c_uwCount] = 0;
|
||
}
|
||
|
||
gs_uxMaxPlayerInfo=ucMaxPlayerInfo;
|
||
eLevel1SendSessionRequestMsg(gs_uxMaxPlayerInfo);
|
||
gs_tm_ulGetActiveSessionsFreq = ulFreq;
|
||
gs_tm_ulPrevGetActiveSessions = g_pfn_ulNetGetTimeInfo();
|
||
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_eGetSessionsFound
|
||
Checks for the sessions found
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : *p_uwNumberOfSessionWaited : the number of session expected
|
||
**pd_stSessionInfoFound : pointer to an array of session description containing
|
||
the sessions found.
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : An error code or NetLib_E_es_NoError if no error occured
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : August 19,96
|
||
Author : Albert Pais
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Comment :
|
||
The pointer may be temporary and should not be stored for later use...
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ NetLib_eGetSessionsFound(unsigned short *p_uwNumberOfSessionWaited,NetLib_tdstSessionInfo **pd_stSessionInfoFound)
|
||
{
|
||
unsigned short c_uwCount;
|
||
|
||
if (!gs_dpucWaitForReply || !gs_dstSessions)
|
||
{
|
||
*p_uwNumberOfSessionWaited = 0;
|
||
*pd_stSessionInfoFound = (NetLib_tdstSessionInfo*)C_pNull;
|
||
return NetLib_E_es_UnknownError;
|
||
}
|
||
|
||
*p_uwNumberOfSessionWaited = 0;
|
||
for(c_uwCount = 0;c_uwCount <gs_c_uwNumberOfSessionsDetected;c_uwCount++)
|
||
{
|
||
if(gs_dpucWaitForReply[c_uwCount])
|
||
{
|
||
(*p_uwNumberOfSessionWaited)++;
|
||
}
|
||
}
|
||
|
||
*pd_stSessionInfoFound = gs_dstSessions;
|
||
|
||
/* if(*p_uwNumberOfSessionWaited<gs_uwNumberOfSessionsExpected)
|
||
{*/
|
||
if(*p_uwNumberOfSessionWaited==gs_c_uwNumberOfSessionsDetected)
|
||
return NetLib_E_es_FoundLessThanRequest;
|
||
else
|
||
{
|
||
*p_uwNumberOfSessionWaited=gs_c_uwNumberOfSessionsDetected;
|
||
return NetLib_E_es_ShouldWait;
|
||
}
|
||
/* }
|
||
else return NetLib_E_es_NoError;*/
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_eCloseGetActiveSessions
|
||
Closes the GetActiveSessions Process. Does not erase the array of the sessions
|
||
found.
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : None
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_NoError if no error occured
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : August 30,96
|
||
Author : Albert Pa<50>s
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ NetLib_eCloseGetActiveSessions(void)
|
||
{
|
||
tdeNetMessageType eMsgType;
|
||
|
||
/* Stop listening */
|
||
eNetRemoveEngineFunction(iNetEngineGetActiveSession);
|
||
gs_eListeningMode = E_Net_LisMod_OFF;
|
||
/*Clear data:*/
|
||
if(gs_dpucWaitForReply)
|
||
{
|
||
vFree((tdpPointer)gs_dpucWaitForReply);
|
||
gs_dpucWaitForReply = C_pNull;
|
||
}
|
||
gs_uwNumberOfSessionsExpected = 0;
|
||
/* if sending and receiving lists contains previous msgs, clear them*/
|
||
eMsgType = E_Net_mt_SysRequestActiveSessions;
|
||
eNetLevel1EraseAllMessages(C_uxNetSystemId,C_GetNbrMsg_OUTGOING,eNetIsMessageType,(void*)(&eMsgType));
|
||
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/*///////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_eCloseAndResetGetActiveSessions
|
||
Closes the GetActiveSessions Process. Erase the array of the sessions
|
||
found.
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : None
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_NoError if no error occured
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : August 30,96
|
||
Author : Albert Pa<50>s
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ NetLib_eCloseAndResetGetActiveSessions(void)
|
||
{
|
||
unsigned short c_uwCount;
|
||
tdeNetMessageType eMsgType;
|
||
if(gs_dstSessions)
|
||
{
|
||
for(c_uwCount = 0; c_uwCount <gs_c_uwNumberOfSessionsDetected; c_uwCount++)
|
||
vNetClearSessionInfo(gs_dstSessions+c_uwCount);
|
||
vLevel1DestroySessionCellList();
|
||
vFree((tdpPointer)gs_dstSessions);
|
||
gs_dstSessions = (NetLib_tdstSessionInfo *)C_pNull;
|
||
}
|
||
NetLib_eCloseGetActiveSessions();
|
||
eMsgType = E_Net_mt_SysRequestActiveSessionsReply;
|
||
eNetLevel1EraseAllMessages(C_uxNetSystemId,C_GetNbrMsg_INCOMING,eNetIsMessageType,(void*)(&eMsgType));
|
||
gs_c_uwNumberOfSessionsDetected = 0;
|
||
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : eNetGetActiveSessions
|
||
Returns the number of Sessions found in the net and an array of
|
||
NetLib_tdstSessionInfo containing information about each game.
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : p_uwNumberOfSessionWaited : the maximum number of session expected. When the
|
||
functions returns, it contains the number of session effectively found.
|
||
pd_stSessionInfoFound : a pointer to an array of NetLib_tdstSessionInfo that contains
|
||
for each session informations about it.
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_NoError if no error occured
|
||
NetLib_E_es_TimeOut if time out
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : April 2,96
|
||
Author : Albert Pa<50>s
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Comment : The pointer may be temporary and should not be stored for later use...
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ NetLib_eGetActiveSessions(unsigned short *p_uwNumberOfSessionWaited,NetLib_tdstSessionInfo **pd_stSessionInfoFound,
|
||
NetLib_tdulTimeInfo ulMaxWaitingTime,NetLib_tduxDescriptionLength ucMaxPlayerInfo)
|
||
{
|
||
NetLib_tdeErrorStatus eErrorReturned;
|
||
tdstNetBlockingLoopDescription stLoopDesc;
|
||
tdstNetGetActiveLoopDesc stGetActiveLoopDesc;
|
||
|
||
/* Open the getactive session processus*/
|
||
eErrorReturned = NetLib_eOpenGetActiveSessions(*p_uwNumberOfSessionWaited,500,ucMaxPlayerInfo);
|
||
|
||
/* Init return values :*/
|
||
*p_uwNumberOfSessionWaited = 0;
|
||
*pd_stSessionInfoFound = (NetLib_tdstSessionInfo*)C_pNull;
|
||
|
||
/* If an error occured, close the processus */
|
||
if(eErrorReturned !=NetLib_E_es_NoError)
|
||
{
|
||
NetLib_eCloseAndResetGetActiveSessions();
|
||
return eErrorReturned;
|
||
}
|
||
|
||
/* Now waiting for either *p_uwNumberOfSessionWaited session or time out :*/
|
||
stLoopDesc.m_ulMaxWaitingTime = ulMaxWaitingTime;
|
||
stLoopDesc.m_eGoOnCondition = NetLib_E_es_FoundLessThanRequest;
|
||
stLoopDesc.m_pfn_eEvaluation = eNetGetActiveSessionsCompleted;
|
||
|
||
stGetActiveLoopDesc.m_pd_stSessionInfoFound = pd_stSessionInfoFound;
|
||
stGetActiveLoopDesc.m_p_uwNumberOfSessionWaited =p_uwNumberOfSessionWaited;
|
||
|
||
stLoopDesc.m_lParam = (long)&stGetActiveLoopDesc;
|
||
|
||
eErrorReturned = NetLib_eBlockingLoop(&stLoopDesc);
|
||
|
||
NetLib_eGetSessionsFound(p_uwNumberOfSessionWaited,pd_stSessionInfoFound);
|
||
/*
|
||
Stop listening mode:
|
||
*/
|
||
NetLib_eCloseGetActiveSessions();
|
||
return eErrorReturned;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : eNetGetActiveSessionsCompleted
|
||
Check if a get active sessions operation is completed or not
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : a pointer to a tdstNetGetActiveLoopDesc cast in void *
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : the return value of NetLib_eGetSessionsFound
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : August 30,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eNetGetActiveSessionsCompleted(long lParam)
|
||
{
|
||
tdstNetGetActiveLoopDesc *p_stGetActiveLoopDesc;
|
||
unsigned short nbrSession;
|
||
NetLib_tdeErrorStatus eErrorReturned;
|
||
p_stGetActiveLoopDesc = (tdstNetGetActiveLoopDesc *)lParam;
|
||
nbrSession=*(p_stGetActiveLoopDesc->m_p_uwNumberOfSessionWaited);
|
||
eErrorReturned=NetLib_eGetSessionsFound(&nbrSession,p_stGetActiveLoopDesc->m_pd_stSessionInfoFound);
|
||
if (gs_c_uwNumberOfSessionsDetected==gs_uwNumberOfSessionsExpected)
|
||
{
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
else return NetLib_E_es_FoundLessThanRequest;
|
||
}
|
||
|
||
/*
|
||
------------------------------------------------------------------------------------------
|
||
CONNECTING TO A SESSION :
|
||
------------------------------------------------------------------------------------------
|
||
*/
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_tdeErrorStatus eNetConnectToSession
|
||
Ask a session for a connection
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input :
|
||
ulIdSessionWanted : the id of the session to witch the connection is wanted
|
||
uwMaxWaitingTime
|
||
d_ucWaitForListen : an array of NumberOfPlayer size, if the slot iSlot is set to
|
||
a non zero value, the connection wait for a listen of the corresponding player
|
||
Otherwise if the slot is 0, the connection does not wait for a listen, and the
|
||
remote player take considers the new player as a playe of the session
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output :
|
||
NetLib_E_es_NoError if no error occured
|
||
NetLib_E_es_UnknownSessionId if the Id specified is unknown
|
||
NetLib_E_es_ServiceNotYetProvided if the number of player in the current session is greater
|
||
than one.
|
||
NetLib_E_es_NotEnoughMemory if there was not enough memory to finish the function. In
|
||
that case, some data in the sessio description may be lost...
|
||
NetLib_E_es_ConnectionFailure if the connection fails. In that case, some data in
|
||
the session description are lost. Must ask for sessions avaible
|
||
before starting a new connection
|
||
NetLib_E_es_TimeOut : a time out occured
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : April 3-4,96
|
||
Author : Albert Pais
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Comment :
|
||
This function makes a connection between the player and the session specified
|
||
by the argument. If it succeed, some changes occurs :
|
||
-> the id of the local session is set to the one to witch the connection is done
|
||
-> the session description length is set to the one to witch the connection is done
|
||
-> the session description data is set to the one to witch the connection is done
|
||
-> the max number of players is set to the one to witch the connection is done
|
||
-> the effective number of players is set to the one to witch the connection is done +1
|
||
-> the id of the local player may change
|
||
-> the index of the local player is correctly set.
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
WARNING :
|
||
This functions only provides connection from a session of one player to a session
|
||
of n players. It does not yet provide connection from a session of m players
|
||
to a session of n players. This will may be done later...
|
||
Such a protocol can be developped by the program.
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Modification date : April 9,96
|
||
Author : Alber Pa<50>s
|
||
Modification : Adding time out managing
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ NetLib_eConnectToSession(NetLib_tdstConnectDesc *p_stConnectDesc)
|
||
{
|
||
NetLib_tdeErrorStatus eErrorReturned;
|
||
unsigned short c_uwSessionChosen;
|
||
unsigned short c_uwCount;
|
||
NetLib_tduxPlayerId ulNewPlayerId;
|
||
|
||
tdstNetConnectLoopDesc stConnLoopDesc;
|
||
tdstNetBlockingLoopDescription stLoopDesc;
|
||
|
||
NetLib_eCloseGetActiveSessions();
|
||
|
||
/* Search for the session concerned :*/
|
||
c_uwSessionChosen = gs_c_uwNumberOfSessionsDetected;
|
||
for(c_uwCount = 0; c_uwCount <gs_c_uwNumberOfSessionsDetected; c_uwCount++)
|
||
{
|
||
if(gs_dstSessions[c_uwCount].uxSessionId ==p_stConnectDesc->m_uxSessionId)
|
||
c_uwSessionChosen = c_uwCount;
|
||
else vNetClearSessionInfo(&gs_dstSessions [c_uwCount]);
|
||
}/* End for */
|
||
|
||
if(c_uwSessionChosen >= gs_c_uwNumberOfSessionsDetected)
|
||
{
|
||
/* Destroy information in level 1 since they have been destroyed in level 2*/
|
||
vLevel1DestroySessionCellList();
|
||
vFree((tdpPointer)gs_dstSessions);
|
||
gs_dstSessions = (NetLib_tdstSessionInfo *)C_pNull;
|
||
return NetLib_E_es_UnknownSessionId;
|
||
}
|
||
|
||
/* A session has been found :*/
|
||
if(gs_stCurrentSession.uwNumberOfPlayers > 1)
|
||
{/* we do not still ensure this service */
|
||
vNetClearSessionInfo(&gs_dstSessions[c_uwSessionChosen]);
|
||
vFree((tdpPointer)gs_dstSessions);
|
||
gs_dstSessions = (NetLib_tdstSessionInfo *)C_pNull;
|
||
vLevel1DestroySessionCellList();
|
||
return NetLib_E_es_ServiceNotYetProvided;
|
||
}
|
||
|
||
/*Initialize global object for the connection :*/
|
||
/* First the tstSessionInfo object : gs_stConnectRequestSessionInfo */
|
||
/* if it contains some thing : clear it*/
|
||
if(gs_p_stConnectRequestSessionInfo /*!= (NetLib_tdstSessionInfo*)C_pNull*/)
|
||
{/* Should not occured but...*/
|
||
vNetClearSessionInfo(gs_p_stConnectRequestSessionInfo);
|
||
vFree((tdpPointer)gs_p_stConnectRequestSessionInfo);
|
||
gs_p_stConnectRequestSessionInfo = (NetLib_tdstSessionInfo*)C_pNull;
|
||
}/* End of if(gs_p_stConnectRequestSessionInfo != C_pNull)*/
|
||
|
||
/* Builds a new Session info object :*/
|
||
gs_p_stConnectRequestSessionInfo = (NetLib_tdstSessionInfo*)pMalloc(sizeof(NetLib_tdstSessionInfo));
|
||
|
||
if(!gs_p_stConnectRequestSessionInfo)
|
||
{/*there was not enouth memory to create gs_p_stConnectRequestSessionInfo */
|
||
vNetClearSessionInfo(&gs_dstSessions[c_uwSessionChosen]);
|
||
vFree((tdpPointer)gs_dstSessions);
|
||
gs_dstSessions = (NetLib_tdstSessionInfo *)C_pNull;
|
||
vLevel1DestroySessionCellList();
|
||
return NetLib_E_es_NotEnoughMemory;
|
||
}
|
||
/* the id of the session : */
|
||
gs_p_stConnectRequestSessionInfo->uxSessionId=gs_dstSessions[c_uwSessionChosen].uxSessionId ;
|
||
/* the session information length :*/
|
||
gs_p_stConnectRequestSessionInfo->uxSessionDescriptionLength=gs_dstSessions[c_uwSessionChosen].uxSessionDescriptionLength;
|
||
/* the session information data*/
|
||
gs_p_stConnectRequestSessionInfo->pSessionDescriptionData=gs_dstSessions[c_uwSessionChosen].pSessionDescriptionData;
|
||
/* the max number of players :*/
|
||
gs_p_stConnectRequestSessionInfo->uwMaxNumberOfPlayers=gs_dstSessions[c_uwSessionChosen].uwMaxNumberOfPlayers;
|
||
/* the number of effective players */
|
||
gs_p_stConnectRequestSessionInfo->uwNumberOfPlayers=gs_dstSessions[c_uwSessionChosen].uwNumberOfPlayers;
|
||
/* the array of player information :*/
|
||
gs_p_stConnectRequestSessionInfo->d_stPlayerInfo=gs_dstSessions[c_uwSessionChosen].d_stPlayerInfo;
|
||
/* the index of the local player : normaly at -1 */
|
||
gs_p_stConnectRequestSessionInfo->uwIndexOfLocalPlayer=gs_dstSessions[c_uwSessionChosen].uwIndexOfLocalPlayer;
|
||
|
||
/* Now erase the gs_dstSessions array :
|
||
The pointers d_stPlayerInfo and pSessionDescriptionData of the
|
||
gs_dstSessions[c_uwSessionChosen] are not deleted since
|
||
the gs_p_stConnectRequestSessionInfo uses them */
|
||
vFree((tdpPointer)gs_dstSessions );
|
||
gs_dstSessions = (NetLib_tdstSessionInfo*)C_pNull;
|
||
|
||
/* Redraw a new player id if necessary */
|
||
ulNewPlayerId=NetLib_uxGetOwnPlayerId();
|
||
|
||
c_uwCount = 0;
|
||
while(c_uwCount < gs_p_stConnectRequestSessionInfo->uwNumberOfPlayers)
|
||
{
|
||
while ((c_uwCount<gs_p_stConnectRequestSessionInfo->uwNumberOfPlayers) &&
|
||
(M_ulNetPlayerIdSlot(&gs_p_stConnectRequestSessionInfo->d_stPlayerInfo[c_uwCount])
|
||
!=ulNewPlayerId)) c_uwCount++;
|
||
|
||
if(c_uwCount < gs_p_stConnectRequestSessionInfo->uwNumberOfPlayers)
|
||
{
|
||
/* It means that the id is the same with one of the players in the session :*/
|
||
ulNewPlayerId = ulNetGetNewPlayerId();
|
||
vNetSetOwnPlayerId(ulNewPlayerId);
|
||
c_uwCount = 0;
|
||
}/* End if(c_uwCount..*/
|
||
}/*while(b_ucDone < 2)*/
|
||
|
||
/* Initialize gs_d_tdeConnectRequestStatusArray :*/
|
||
if(gs_d_tdeConnectRequestStatusArray /*!= (tdeConnectRequestStatus*)C_pNull*/)
|
||
/* It is not set to null because it is reallocated just after :*/
|
||
vFree((tdpPointer)gs_d_tdeConnectRequestStatusArray);
|
||
gs_d_tdeConnectRequestStatusArray=(tdeNetConnectRequestStatus*)
|
||
pMalloc(sizeof(tdeNetConnectRequestStatus)*gs_p_stConnectRequestSessionInfo->uwNumberOfPlayers);
|
||
if(!gs_d_tdeConnectRequestStatusArray)
|
||
{ /* There was not enough memory to create gs_d_tdeConnectRequestStatusArray */
|
||
/* Cancel the connection*/
|
||
vNetClearSessionInfo(gs_p_stConnectRequestSessionInfo);
|
||
vFree((tdpPointer)gs_p_stConnectRequestSessionInfo);
|
||
gs_p_stConnectRequestSessionInfo = (NetLib_tdstSessionInfo*)C_pNull;
|
||
gs_c_uwNumberOfSessionsDetected = 0;
|
||
vLevel1DestroySessionCellList();
|
||
return NetLib_E_es_NotEnoughMemory;
|
||
}
|
||
|
||
for(c_uwCount=0;c_uwCount<gs_p_stConnectRequestSessionInfo->uwNumberOfPlayers;c_uwCount++)
|
||
gs_d_tdeConnectRequestStatusArray[c_uwCount] = E_Net_ConReqSta_Todo;
|
||
|
||
/* Update level 1 informations */
|
||
eLevel1StripSessionList(p_stConnectDesc->m_uxSessionId);
|
||
|
||
/* FIRST STEP :*/
|
||
/* Wait for all remote players reply to a connection request */
|
||
stLoopDesc.m_ulMaxWaitingTime = p_stConnectDesc->m_ulMaxWaitingTime;
|
||
stLoopDesc.m_eGoOnCondition = NetLib_E_es_OperationInProgress;
|
||
stLoopDesc.m_pfn_eEvaluation = eNetConnectionCompleted;
|
||
|
||
stConnLoopDesc.m_ulPrevTimeInfo = 0;
|
||
stConnLoopDesc.m_ulFreq = p_stConnectDesc->m_ulMaxWaitingTime/REPEAT_COUNT;
|
||
|
||
stLoopDesc.m_lParam = (long)&stConnLoopDesc;
|
||
|
||
eErrorReturned = NetLib_eBlockingLoop(&stLoopDesc);
|
||
|
||
if(eErrorReturned==NetLib_E_es_NoError)
|
||
{
|
||
/* SECOND STEP :*/
|
||
/* Wait for all remote players make a listen */
|
||
stLoopDesc.m_ulMaxWaitingTime = p_stConnectDesc->m_ulMaxWaitingTime;
|
||
stLoopDesc.m_eGoOnCondition = NetLib_E_es_OperationInProgress;
|
||
stLoopDesc.m_pfn_eEvaluation = eNetListeningCompleted;
|
||
|
||
stConnLoopDesc.m_ulPrevTimeInfo = 0;
|
||
stConnLoopDesc.m_ulFreq = p_stConnectDesc->m_ulMaxWaitingTime/REPEAT_COUNT;
|
||
|
||
stLoopDesc.m_lParam = (long)&stConnLoopDesc;
|
||
|
||
eErrorReturned = NetLib_eBlockingLoop(&stLoopDesc);
|
||
|
||
if(eErrorReturned == NetLib_E_es_NoError)
|
||
{
|
||
/* LAST STEP :*/
|
||
/* Connection succedd : Set data : */
|
||
/* Initialise local player informations :*/
|
||
NetLib_eCopystPlayerInfo(&gs_p_stConnectRequestSessionInfo->d_stPlayerInfo[gs_p_stConnectRequestSessionInfo->uwNumberOfPlayers],
|
||
pstNetGetPlayerSlot(NetLib_uxGetOwnPlayerId()));
|
||
|
||
/* initialize the "internet mark" for the local player */
|
||
gs_p_stConnectRequestSessionInfo->d_stPlayerInfo[gs_p_stConnectRequestSessionInfo->uwNumberOfPlayers].m_bOverInternet=0;
|
||
|
||
vNetSetSessionId(gs_p_stConnectRequestSessionInfo->uxSessionId);
|
||
|
||
gs_stCurrentSession.uxSessionDescriptionLength=gs_p_stConnectRequestSessionInfo->uxSessionDescriptionLength;
|
||
if(gs_stCurrentSession.pSessionDescriptionData!=(tdpPointer)C_pNull) vFree(gs_stCurrentSession.pSessionDescriptionData);
|
||
gs_stCurrentSession.pSessionDescriptionData = gs_p_stConnectRequestSessionInfo->pSessionDescriptionData;
|
||
gs_stCurrentSession.uwMaxNumberOfPlayers = gs_p_stConnectRequestSessionInfo->uwMaxNumberOfPlayers;
|
||
gs_stCurrentSession.uwNumberOfPlayers = gs_p_stConnectRequestSessionInfo->uwNumberOfPlayers + 1;
|
||
|
||
/* List of player info*/
|
||
vFree((tdpPointer)gs_stCurrentSession.d_stPlayerInfo);
|
||
gs_stCurrentSession.d_stPlayerInfo = gs_p_stConnectRequestSessionInfo->d_stPlayerInfo;
|
||
/* Index of local player :*/
|
||
gs_stCurrentSession.uwIndexOfLocalPlayer = gs_p_stConnectRequestSessionInfo->uwNumberOfPlayers;
|
||
/* Clear all that must be cleared :*/
|
||
vFree((tdpPointer)gs_p_stConnectRequestSessionInfo);
|
||
gs_p_stConnectRequestSessionInfo = (NetLib_tdstSessionInfo*)C_pNull;
|
||
vFree((tdpPointer)gs_d_tdeConnectRequestStatusArray);
|
||
gs_d_tdeConnectRequestStatusArray = (tdeNetConnectRequestStatus*)C_pNull;
|
||
gs_c_uwNumberOfSessionsDetected = 0;
|
||
|
||
eNetSendTCPAddress(); /* Send TCPAddress. */
|
||
|
||
return eErrorReturned;
|
||
}
|
||
}
|
||
|
||
if(eErrorReturned != NetLib_E_es_NoError)
|
||
{
|
||
/* Cancel the connection :*/
|
||
eNetCancelConnection();
|
||
/* Send message :*/
|
||
NetLib_eFlushSendingList(p_stConnectDesc->m_ulMaxWaitingTime);
|
||
/* Clear all that must be cleared :*/
|
||
for(c_uwCount=0;c_uwCount<gs_p_stConnectRequestSessionInfo->uwNumberOfPlayers;c_uwCount++)
|
||
{
|
||
vFree((tdpPointer)gs_p_stConnectRequestSessionInfo->d_stPlayerInfo[c_uwCount].pPlayerDescriptionData);
|
||
/* It is no used since all will be destroyed :
|
||
gs_p_stConnectRequestSessionInfo->d_stPlayerInfo[c_uwCount].pPlayerDescriptionData = (tdpPointer)C_pNull; */
|
||
eLevel1DisconnectRemotePlayer(M_ulNetPlayerIdSlot(&gs_p_stConnectRequestSessionInfo->d_stPlayerInfo[c_uwCount]));
|
||
}
|
||
vFree((tdpPointer)gs_p_stConnectRequestSessionInfo->pSessionDescriptionData);
|
||
/* Not necessary : gs_p_stConnectRequestSessionInfo->pSessionDescriptionData = (tdpPointer)C_pNull; */
|
||
vFree((tdpPointer)gs_p_stConnectRequestSessionInfo->d_stPlayerInfo);
|
||
/* Not necessary : gs_p_stConnectRequestSessionInfo->d_stPlayerInfo = (NetLib_tdstPlayerInfo*)C_pNull; */
|
||
vFree((tdpPointer)gs_p_stConnectRequestSessionInfo);
|
||
gs_p_stConnectRequestSessionInfo = (NetLib_tdstSessionInfo*)C_pNull;
|
||
vFree((tdpPointer)gs_d_tdeConnectRequestStatusArray);
|
||
gs_d_tdeConnectRequestStatusArray = (tdeNetConnectRequestStatus*)C_pNull;
|
||
gs_c_uwNumberOfSessionsDetected = 0;
|
||
|
||
/* the param deny :*/
|
||
p_stConnectDesc->m_lConDenyParam = gs_lConDenyParam;
|
||
gs_lConDenyParam = 0;
|
||
|
||
vLevel1DestroySessionCellList();
|
||
}/*End of if(eErrorReturned != NetLib_E_es_NoError)*/
|
||
return eErrorReturned;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_tdeErrorStatus eNetSendAcknowledgementMessage(void)
|
||
Sends an agreement msg to all remote players that have not still reply
|
||
with a LISTENED msg.
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : None
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_NoError if no error occured
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : August 14,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus eNetSendAcknowledgementMessage(void)
|
||
{
|
||
unsigned short c_uwCount;
|
||
tdstNetMessage *p_stConnectRequestMessage;
|
||
NetLib_tdeErrorStatus eErrorReturned;
|
||
|
||
c_uwCount = 0;
|
||
|
||
while(c_uwCount < gs_p_stConnectRequestSessionInfo->uwNumberOfPlayers)
|
||
{
|
||
if ((M_ulNetPlayerIdSlot(&(gs_p_stConnectRequestSessionInfo->d_stPlayerInfo[c_uwCount]))
|
||
!= C_uxNetInvalidId) &&
|
||
(gs_d_tdeConnectRequestStatusArray[c_uwCount]!=E_Net_ConReqSta_Listened))
|
||
{
|
||
p_stConnectRequestMessage=(tdstNetMessage*)pMalloc(sizeof(tdstNetMessage)+1);
|
||
if(p_stConnectRequestMessage)
|
||
{
|
||
p_stConnectRequestMessage->uxRecipientId=M_ulNetPlayerIdSlot(&gs_p_stConnectRequestSessionInfo->d_stPlayerInfo[c_uwCount]);
|
||
p_stConnectRequestMessage->uxSenderId=NetLib_uxGetOwnPlayerId();
|
||
p_stConnectRequestMessage->eMessageType = E_Net_mt_SysConnectAcknowledgement;
|
||
p_stConnectRequestMessage->uwMessageSizeInBytes = 1;
|
||
p_stConnectRequestMessage->uxPriority = NetLib_C_uxMaxPriority;
|
||
p_stConnectRequestMessage->uxReplaceType = 0;
|
||
p_stConnectRequestMessage->uxReplace = 0;
|
||
*((char *)(p_stConnectRequestMessage+1))=0; /* Flag for direct route.*/
|
||
|
||
if(gs_ArtificialLatency)
|
||
eErrorReturned=eInternetSimuSendMessage(M_ulNetPlayerIdSlot(&gs_p_stConnectRequestSessionInfo->d_stPlayerInfo[c_uwCount]),
|
||
p_stConnectRequestMessage);
|
||
else eErrorReturned=eLevel1SendMessage(p_stConnectRequestMessage,E_Net_pr_InvalidProtocol,C_uwNetInvalidChannel);
|
||
|
||
if(eErrorReturned ==NetLib_E_es_NoError) c_uwCount++;
|
||
else vFree((tdpPointer)p_stConnectRequestMessage);
|
||
}
|
||
}
|
||
else c_uwCount++;
|
||
}/* End of while*/
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/*////////////////////////////////////////////////////////////////////////////////
|
||
Description : eNetSendConnectionRequestMessage
|
||
Sends an connect request msg to all remote players that have neither still reply
|
||
with a LISTENED msg nor with an agreement msg
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : None
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_NoError if no error occured
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : August 14,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus eNetSendConnectionRequestMessage(void)
|
||
{
|
||
unsigned short c_uwCount;
|
||
tdstNetMessage *p_stConnectRequestMessage;
|
||
NetLib_tdeErrorStatus eErrorReturned;
|
||
tdpPointer pOriginData;
|
||
|
||
c_uwCount = 0;
|
||
while(c_uwCount < gs_p_stConnectRequestSessionInfo->uwNumberOfPlayers)
|
||
{
|
||
if ((M_ulNetPlayerIdSlot(&(gs_p_stConnectRequestSessionInfo->d_stPlayerInfo[c_uwCount]))
|
||
!= C_uxNetInvalidId)
|
||
&&(gs_d_tdeConnectRequestStatusArray[c_uwCount]!=E_Net_ConReqSta_Done)
|
||
&&(gs_d_tdeConnectRequestStatusArray[c_uwCount]!=E_Net_ConReqSta_Listened))
|
||
{
|
||
p_stConnectRequestMessage = (tdstNetMessage*)pMalloc(
|
||
sizeof(tdstNetMessage)
|
||
+gs_stCurrentSession.d_stPlayerInfo[gs_stCurrentSession.uwIndexOfLocalPlayer].uxPlayerDescriptionLength
|
||
+sizeof(NetLib_tduxDescriptionLength)
|
||
+sizeof(NetLib_tducBigLittleEndian)
|
||
+sizeof(char)); /* the "via internet" mark */
|
||
|
||
if(p_stConnectRequestMessage)
|
||
{
|
||
p_stConnectRequestMessage->eMessageType = E_Net_mt_SysConnectRequest;
|
||
p_stConnectRequestMessage->uxRecipientId=M_ulNetPlayerIdSlot(&gs_p_stConnectRequestSessionInfo->d_stPlayerInfo[c_uwCount]);
|
||
p_stConnectRequestMessage->uxSenderId=NetLib_uxGetOwnPlayerId();
|
||
p_stConnectRequestMessage->uwMessageSizeInBytes =
|
||
gs_stCurrentSession.d_stPlayerInfo[gs_stCurrentSession.uwIndexOfLocalPlayer].uxPlayerDescriptionLength
|
||
+sizeof(NetLib_tduxDescriptionLength)+sizeof(NetLib_tducBigLittleEndian)+sizeof(char) /* the "via internet" mark */;
|
||
|
||
p_stConnectRequestMessage->uxPriority = NetLib_C_uxMaxPriority;
|
||
p_stConnectRequestMessage->uxReplaceType = 0;
|
||
p_stConnectRequestMessage->uxReplace = 0;
|
||
/* Body :*/
|
||
pOriginData = (tdpPointer)(p_stConnectRequestMessage + 1);
|
||
/* The length of the player desription :*/
|
||
*((NetLib_tduxDescriptionLength*)pOriginData) =
|
||
gs_stCurrentSession.d_stPlayerInfo[gs_stCurrentSession.uwIndexOfLocalPlayer].uxPlayerDescriptionLength;
|
||
pOriginData = (tdpPointer)((NetLib_tduxDescriptionLength*)pOriginData + 1);
|
||
if(gs_stCurrentSession.d_stPlayerInfo[gs_stCurrentSession.uwIndexOfLocalPlayer].uxPlayerDescriptionLength)
|
||
{
|
||
/* The player description : */
|
||
g_pfn_vNetMemcpy(pOriginData,
|
||
gs_stCurrentSession.d_stPlayerInfo[gs_stCurrentSession.uwIndexOfLocalPlayer].pPlayerDescriptionData,
|
||
gs_stCurrentSession.d_stPlayerInfo[gs_stCurrentSession.uwIndexOfLocalPlayer].uxPlayerDescriptionLength);
|
||
}
|
||
pOriginData+=gs_stCurrentSession.d_stPlayerInfo[gs_stCurrentSession.uwIndexOfLocalPlayer].uxPlayerDescriptionLength;
|
||
|
||
*((NetLib_tducBigLittleEndian*)pOriginData) = NetLib_ucGetLittleBigEndian();
|
||
pOriginData = (tdpPointer) ( pOriginData+ sizeof(NetLib_tducBigLittleEndian) );
|
||
|
||
/* set the "via internet" mark */
|
||
|
||
if(eLevel1GoesToIP(M_ulNetPlayerIdSlot(&gs_p_stConnectRequestSessionInfo->d_stPlayerInfo[c_uwCount])))
|
||
*((char *)pOriginData)=1;
|
||
else
|
||
*((char *)pOriginData)=0;
|
||
|
||
/* send the message */
|
||
|
||
if(gs_ArtificialLatency)
|
||
eErrorReturned=eInternetSimuSendMessage(M_ulNetPlayerIdSlot(&gs_p_stConnectRequestSessionInfo->d_stPlayerInfo[c_uwCount]),
|
||
p_stConnectRequestMessage);
|
||
else
|
||
eErrorReturned=eLevel1SendMessage(p_stConnectRequestMessage,E_Net_pr_InvalidProtocol,C_uwNetInvalidChannel);
|
||
|
||
if(eErrorReturned !=NetLib_E_es_NoError)
|
||
vFree((tdpPointer)p_stConnectRequestMessage);
|
||
}
|
||
}
|
||
c_uwCount++;
|
||
}
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : eNetConnectionCompleted
|
||
Check if all the remote players answered to the connection request.
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : a pointer to a tdstNetConnectLoopDesc casted into a void*
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_NoError if completed
|
||
NetLib_E_es_OperationInProgress if not completed
|
||
NetLib_E_es_UnknownError if an error occured
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : September 1,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eNetConnectionCompleted(long lParam)
|
||
{
|
||
unsigned short c_uwCount;
|
||
tdstNetConnectLoopDesc *p_stDescLoop;
|
||
|
||
p_stDescLoop = (tdstNetConnectLoopDesc *)lParam;
|
||
|
||
/* Ask for connection if necessary :*/
|
||
if(g_pfn_ulNetGetTimeInfo()-p_stDescLoop->m_ulPrevTimeInfo >= p_stDescLoop->m_ulFreq)
|
||
{
|
||
eNetSendConnectionRequestMessage();
|
||
p_stDescLoop->m_ulPrevTimeInfo = g_pfn_ulNetGetTimeInfo();
|
||
}
|
||
|
||
/* Check if it is not finished :*/
|
||
c_uwCount = 0;
|
||
while((c_uwCount < gs_p_stConnectRequestSessionInfo->uwNumberOfPlayers)&&
|
||
((gs_d_tdeConnectRequestStatusArray[c_uwCount]==E_Net_ConReqSta_Done)||
|
||
(gs_d_tdeConnectRequestStatusArray[c_uwCount]==E_Net_ConReqSta_Listened)))
|
||
c_uwCount++;
|
||
|
||
/* Check if it is finished :*/
|
||
if(c_uwCount >=gs_p_stConnectRequestSessionInfo->uwNumberOfPlayers) return NetLib_E_es_NoError;
|
||
|
||
/* Check if no error occured :*/
|
||
switch(gs_d_tdeConnectRequestStatusArray[c_uwCount])
|
||
{
|
||
case E_Net_ConReqSta_Invalid:
|
||
return NetLib_E_es_UnknownError;
|
||
case E_Net_ConReqSta_Refused:
|
||
return NetLib_E_es_ConnectionRemoteRefused;
|
||
case E_Net_ConReqSta_SessionChanged :
|
||
return NetLib_E_es_ConnectionSessionChanged;
|
||
case E_Net_ConReqSta_WaitBusy :
|
||
return NetLib_E_es_ConnectionWaitBusy;
|
||
};
|
||
|
||
return NetLib_E_es_OperationInProgress;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : eNetListeningCompleted
|
||
Check if all the remote players have listened the player
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : a pointer to a tdstNetConnectLoopDesc casted into a void*
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_NoError if completed
|
||
NetLib_E_es_OperationInProgress if not completed
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : September 1,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eNetListeningCompleted(long lParam)
|
||
{
|
||
unsigned short c_uwCount;
|
||
tdstNetConnectLoopDesc *p_stDescLoop;
|
||
|
||
p_stDescLoop = (tdstNetConnectLoopDesc *)lParam;
|
||
|
||
c_uwCount = 0;
|
||
while ((c_uwCount < gs_p_stConnectRequestSessionInfo->uwNumberOfPlayers)&&
|
||
(gs_d_tdeConnectRequestStatusArray[c_uwCount]==E_Net_ConReqSta_Listened))
|
||
c_uwCount++;
|
||
|
||
if(c_uwCount >= gs_p_stConnectRequestSessionInfo->uwNumberOfPlayers)
|
||
return NetLib_E_es_NoError;
|
||
|
||
if(g_pfn_ulNetGetTimeInfo()-p_stDescLoop->m_ulPrevTimeInfo>=p_stDescLoop->m_ulFreq)
|
||
{
|
||
eNetSendAcknowledgementMessage();
|
||
p_stDescLoop->m_ulPrevTimeInfo = g_pfn_ulNetGetTimeInfo();
|
||
}
|
||
return NetLib_E_es_OperationInProgress;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description :eNetCancelConnection
|
||
Cancel a connection
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : None
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_NoError if no error occured
|
||
An NetLib_tdeErrorStatus if an error occured
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : June 13,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus eNetCancelConnection(void)
|
||
{
|
||
unsigned short c_uwCount;
|
||
tdstNetMessage *p_stCancelMsg;
|
||
|
||
if(gs_p_stConnectRequestSessionInfo)
|
||
{
|
||
for(c_uwCount = 0; c_uwCount <gs_p_stConnectRequestSessionInfo->uwNumberOfPlayers;c_uwCount++)
|
||
{
|
||
p_stCancelMsg = (tdstNetMessage*)pMalloc(sizeof(tdstNetMessage));
|
||
if(p_stCancelMsg)
|
||
{
|
||
if ((gs_d_tdeConnectRequestStatusArray)&&
|
||
(gs_d_tdeConnectRequestStatusArray[c_uwCount]==E_Net_ConReqSta_Listened))
|
||
p_stCancelMsg->eMessageType = E_Net_mt_SysDisconnection;
|
||
else p_stCancelMsg->eMessageType = E_Net_mt_SysConnectCancel;
|
||
p_stCancelMsg->uxRecipientId=M_ulNetPlayerIdSlot(&gs_p_stConnectRequestSessionInfo->d_stPlayerInfo[c_uwCount]);
|
||
p_stCancelMsg->uxSenderId=NetLib_uxGetOwnPlayerId();
|
||
p_stCancelMsg->uxPriority = NetLib_C_uxMaxPriority;
|
||
p_stCancelMsg->uxReplaceType = 0;
|
||
p_stCancelMsg->uxReplace = 0;
|
||
p_stCancelMsg->uwMessageSizeInBytes = 0;
|
||
|
||
if (gs_ArtificialLatency)
|
||
eInternetSimuSendMessage(M_ulNetPlayerIdSlot(&gs_p_stConnectRequestSessionInfo->d_stPlayerInfo[c_uwCount]),
|
||
p_stCancelMsg);
|
||
else
|
||
eLevel1SendMessage(p_stCancelMsg,E_Net_pr_InvalidProtocol,C_uwNetInvalidChannel);
|
||
}
|
||
}
|
||
}
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/*
|
||
------------------------------------------------------------------------------------------
|
||
LISTENING A PLAYER :
|
||
------------------------------------------------------------------------------------------
|
||
*/
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description :NetLib_eListenForRequest
|
||
Listen for a request of connection
|
||
When the functions returns, the parameter contain information about a new player
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : a pointer to listening description structure
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_NoError if no error occured
|
||
An error code otherwise
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : August 29,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ NetLib_eListenForRequest(NetLib_tdstListenDesc*p_stListenDesc)
|
||
{
|
||
tdstNetBlockingLoopDescription stListenLoopDesc;
|
||
NetLib_tdeErrorStatus eErrorReturned;
|
||
NetLib_tdstPlayerInfo *p_stNewPlayerSlot;
|
||
NetLib_tdstSendDesc stSendDesc;
|
||
unsigned short c_uwCount;
|
||
char flagDirect=0; /* Direct route flag.*/
|
||
|
||
if (gs_uwMode==NetLib_Mode_Direct)
|
||
{
|
||
if(p_stListenDesc->m_ulMaxWaitingTime)
|
||
{
|
||
stListenLoopDesc.m_ulMaxWaitingTime = p_stListenDesc->m_ulMaxWaitingTime;
|
||
stListenLoopDesc.m_eGoOnCondition = NetLib_E_es_NoNewPlayer;
|
||
stListenLoopDesc.m_pfn_eEvaluation = eNetListenCompleted;
|
||
stListenLoopDesc.m_lParam = (long)C_pNull;
|
||
|
||
eErrorReturned = NetLib_eBlockingLoop(&stListenLoopDesc);
|
||
}
|
||
else eErrorReturned = eNetListenCompleted((long)C_pNull);
|
||
|
||
if(eErrorReturned != NetLib_E_es_NoError) return eErrorReturned;
|
||
|
||
p_stNewPlayerSlot = pstNetGetPlayerSlot(C_uxNetInvalidId);
|
||
if(!p_stNewPlayerSlot) return NetLib_E_es_ShouldNotReach;
|
||
|
||
/* Here we have a new player :*/
|
||
stSendDesc.m_tduxRecipientId = M_ulNetPlayerIdSlot(gs_p_stPreSessionPlayerInfo);
|
||
stSendDesc.m_ulMaxWaitingTime = 0;
|
||
stSendDesc.m_pMessageData = &flagDirect;
|
||
stSendDesc.m_uwMessageLength =1;
|
||
stSendDesc.m_uxPriority = NetLib_C_uxNoPriority;
|
||
stSendDesc.m_uxReplaceType = 0;
|
||
stSendDesc.m_uxReplaceFlag = 0;
|
||
stSendDesc.m_ucReadReceiptFlag = NetLib_C_ucNoReadReceipt;
|
||
|
||
eErrorReturned = eNetInternalSendMessage(&stSendDesc,E_Net_mt_SysConnectListened);
|
||
if(eErrorReturned !=NetLib_E_es_NoError) return eErrorReturned;
|
||
|
||
M_ulNetPlayerIdSlot(p_stNewPlayerSlot)=M_ulNetPlayerIdSlot(gs_p_stPreSessionPlayerInfo);
|
||
NetLib_eCopystPlayerInfo(p_stNewPlayerSlot,gs_p_stPreSessionPlayerInfo);
|
||
gs_stCurrentSession.uwNumberOfPlayers ++;
|
||
|
||
/* free memory :*/
|
||
vFree((tdpPointer)gs_p_stPreSessionPlayerInfo);
|
||
gs_p_stPreSessionPlayerInfo = (NetLib_tdstPlayerInfo*)C_pNull;
|
||
gs_tdePreSessionPlayerStatus = E_Net_ConRecSta_NONE;
|
||
}
|
||
else
|
||
{
|
||
p_stNewPlayerSlot=NULL;
|
||
for (c_uwCount=0;c_uwCount<gs_stCurrentSession.uwMaxNumberOfPlayers;c_uwCount++)
|
||
{
|
||
if (M_ulNetPlayerIdSlot(&gs_stCurrentSession.d_stPlayerInfo[c_uwCount])!=C_uxNetInvalidId)
|
||
{
|
||
if (gs_stCurrentSession.d_stPlayerInfo[c_uwCount].wNewPlayer)
|
||
{
|
||
p_stNewPlayerSlot = &gs_stCurrentSession.d_stPlayerInfo[c_uwCount];
|
||
p_stNewPlayerSlot->wNewPlayer=0;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
if (p_stNewPlayerSlot==NULL) return NetLib_E_es_NoNewPlayer;
|
||
}
|
||
|
||
/* fill the parameter :*/
|
||
p_stListenDesc->m_uxPlayerId = M_ulNetPlayerIdSlot(p_stNewPlayerSlot);
|
||
p_stListenDesc->m_uxPlayerDescriptionLength = p_stNewPlayerSlot->uxPlayerDescriptionLength;
|
||
if ((p_stNewPlayerSlot->uxPlayerDescriptionLength) && (p_stListenDesc->m_pPlayerDescriptionData))
|
||
g_pfn_vNetMemcpy(p_stListenDesc->m_pPlayerDescriptionData,
|
||
p_stNewPlayerSlot->pPlayerDescriptionData,
|
||
p_stNewPlayerSlot->uxPlayerDescriptionLength);
|
||
else p_stListenDesc->m_pPlayerDescriptionData = C_pNull;
|
||
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : eNetCheckTimeOutOfPlayerConnected
|
||
Check if the timeout on a player who asked for a connection has run out
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : None
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : None
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : April 4,96
|
||
Author : Albert Pais
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Comment : If the time out has run out, then the gs_p_stPreSessionPlayerInfo is cleared
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus eNetCheckTimeOutOfPlayerConnected(unsigned char b_ClearInfo)
|
||
{
|
||
if(gs_p_stPreSessionPlayerInfo /*!=(NetLib_tdstPlayerInfo*)C_pNull*/)
|
||
{
|
||
if ((g_pfn_ulNetGetTimeInfo) && (gs_tm_ulPreSessionPlayerMaxWaitingTime) &&
|
||
(gs_tm_ulPreSessionPlayerTimer + gs_tm_ulPreSessionPlayerMaxWaitingTime < (*g_pfn_ulNetGetTimeInfo)()))
|
||
{
|
||
if(b_ClearInfo)
|
||
{
|
||
/* time out occured, so close connection with player and free memory :*/
|
||
eLevel1DisconnectRemotePlayer(M_ulNetPlayerIdSlot(gs_p_stPreSessionPlayerInfo));
|
||
/* Free memory :*/
|
||
vFree((tdpPointer)gs_p_stPreSessionPlayerInfo->pPlayerDescriptionData);
|
||
/* Not necessary :
|
||
gs_p_stPreSessionPlayerInfo->pPlayerDescriptionData = (tdpPointer)C_pNull;
|
||
*/
|
||
vFree((tdpPointer)gs_p_stPreSessionPlayerInfo);
|
||
gs_p_stPreSessionPlayerInfo = (NetLib_tdstPlayerInfo*)C_pNull;
|
||
gs_tdePreSessionPlayerStatus = E_Net_ConRecSta_NONE;
|
||
}
|
||
return NetLib_E_es_TimeOutExpired;
|
||
}
|
||
return NetLib_E_es_TimeOutNotExpired;
|
||
}
|
||
return NetLib_E_es_NoNewPlayer;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description :eNetListenCompleted
|
||
Test if a connection request is completed.
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : None
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_NoError if there is a player waiting for a connectio,n
|
||
NetLib_E_es_NoNewPlayer if there was no player waiting for a connection
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : August 29,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eNetListenCompleted(long lParam)
|
||
{
|
||
if(gs_tdePreSessionPlayerStatus == E_Net_ConRecSta_DONE)
|
||
return NetLib_E_es_NoError;
|
||
else
|
||
return NetLib_E_es_NoNewPlayer;
|
||
}
|
||
|
||
/*
|
||
------------------------------------------------------------------------------------------
|
||
DISCONNECTION :
|
||
------------------------------------------------------------------------------------------
|
||
*/
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description :NetLib_eDisconnectRemotePlayer
|
||
Close connection with the player specified by the parameter
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : ulOldIdPlayer : a player id representing the player disconnected
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : None
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : April 4,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ NetLib_eDisconnectRemotePlayer(NetLib_tduxPlayerId ulOldPlayerId)
|
||
{
|
||
NetLib_tdeErrorStatus eErrorReturned;
|
||
tdpPointer pMsg;
|
||
NetLib_tdstSendDesc stSendDesc;
|
||
|
||
/* test whether the disconnected player is the local player */
|
||
|
||
if(NetLib_uxGetOwnPlayerId()==ulOldPlayerId)
|
||
return NetLib_E_es_InvalidHandle;
|
||
|
||
/* test whether the disconnected player exists */
|
||
|
||
if(uwNetGetPlayerIndex(ulOldPlayerId)==NetLib_C_uwInvalidPosition)
|
||
return NetLib_E_es_UnknownPlayerId;
|
||
|
||
/* Inform all other players :*/
|
||
/* Sends a disconnection message to all the players :*/
|
||
stSendDesc.m_tduxRecipientId = C_uxNetBroadcastId;
|
||
stSendDesc.m_ulMaxWaitingTime = 0;
|
||
pMsg = pMalloc(sizeof(NetLib_tduxPlayerId));
|
||
if(!pMsg) return NetLib_E_es_NotEnoughMemory;
|
||
|
||
*((NetLib_tduxPlayerId*)pMsg) = ulOldPlayerId;
|
||
stSendDesc.m_pMessageData = pMsg;
|
||
stSendDesc.m_uwMessageLength =sizeof(NetLib_tduxPlayerId);
|
||
stSendDesc.m_uxPriority = NetLib_C_uxNoPriority;
|
||
stSendDesc.m_uxReplaceType = 0;
|
||
stSendDesc.m_uxReplaceFlag = 0;
|
||
stSendDesc.m_ucReadReceiptFlag = NetLib_C_ucNoReadReceipt;
|
||
|
||
eErrorReturned = eNetInternalSendMessage(&stSendDesc,E_Net_mt_SysDisconnectRemotePlayer);
|
||
vFree((tdpPointer)pMsg);
|
||
|
||
if(eErrorReturned==NetLib_E_es_NoError)
|
||
/* call the disconnection callback and erase the player from local tables */
|
||
eErrorReturned = eNetDisconnectPlayer(ulOldPlayerId, 1);
|
||
|
||
return eErrorReturned;
|
||
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description :NetLib_vDisconnectAllRemotePlayers
|
||
Close connection with all the players of the session
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : None
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : None
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : April 4,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
void _NET_CALLING_CONV_ NetLib_vDisconnectAllRemotePlayers(void)
|
||
{
|
||
NetLib_tdstDoForAllDesc stDoForAllDesc;
|
||
|
||
stDoForAllDesc.m_pfn_eForAll = eNetDisconnectPlayer;
|
||
stDoForAllDesc.m_lParameter = 0;
|
||
stDoForAllDesc.m_eGoOnCondition = NetLib_E_es_NoError;
|
||
stDoForAllDesc.m_ucIncludeLocal = NetLib_C_ucNotIncludeLocalPlayer;
|
||
NetLib_eDoForAllPlayers(&stDoForAllDesc);
|
||
|
||
if (gs_uwMode==NetLib_Mode_Direct) vNetSetSessionId(M_ulNetPlayerIdSlot(&gs_stCurrentSession.d_stPlayerInfo[gs_stCurrentSession.uwIndexOfLocalPlayer]));
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description :NetLib_vDisconnectFromSession
|
||
Disconnect the player from the session
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : None
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : None
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : April,15 96
|
||
Author : Albert Pais
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Comment : Since the function must send disconnection messages before closing the connection,
|
||
it may take some time to process it.
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
void _NET_CALLING_CONV_ NetLib_vDisconnectFromSession(void)
|
||
{
|
||
NetLib_tdstSendDesc stSendDesc;
|
||
/* Sends a disconnection message to all the players :*/
|
||
stSendDesc.m_tduxRecipientId = C_uxNetBroadcastId;
|
||
stSendDesc.m_ulMaxWaitingTime = 0;
|
||
stSendDesc.m_pMessageData = C_pNull;
|
||
stSendDesc.m_uwMessageLength =0;
|
||
stSendDesc.m_uxPriority = NetLib_C_uxNoPriority;
|
||
stSendDesc.m_uxReplaceType = 0;
|
||
stSendDesc.m_uxReplaceFlag = 0;
|
||
stSendDesc.m_ucReadReceiptFlag = NetLib_C_ucNoReadReceipt;
|
||
|
||
eNetInternalSendMessage(&stSendDesc,E_Net_mt_SysDisconnection);
|
||
|
||
NetLib_eFlushSendingList(500);
|
||
|
||
/* Close the connections :*/
|
||
NetLib_vDisconnectAllRemotePlayers();
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : eNetDisconnectPlayer
|
||
Disconnect a player and invoke the callback
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : A player id and a param
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : An error code
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : September 16, 96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eNetDisconnectPlayer(NetLib_tduxPlayerId ulPlayerId,long lParam)
|
||
{
|
||
if(lParam && g_pfn_vDisconnectCallBack) g_pfn_vDisconnectCallBack(ulPlayerId);
|
||
|
||
return eNetRemoveRemotePlayer(ulPlayerId);
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : eNetRemoveRemotePlayer
|
||
Close connection with the player specified by the parameter
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : ulOldIdPlayer : a player id representing the player disconnected
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : None
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : April 4,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eNetRemoveRemotePlayer(NetLib_tduxPlayerId ulOldPlayerId)
|
||
{
|
||
NetLib_tdstPlayerInfo *p_stPlayer;
|
||
/* Update the broadcast table. */
|
||
vLevel1SupBroadcastDest(ulOldPlayerId);
|
||
vLevel1SupBroadcastSource(ulOldPlayerId);
|
||
|
||
p_stPlayer = pstNetGetPlayerSlot(ulOldPlayerId);
|
||
if ((ulOldPlayerId!=NetLib_uxGetOwnPlayerId())&&(p_stPlayer))
|
||
{
|
||
/* Erase the description of the player :*/
|
||
if(p_stPlayer->pPlayerDescriptionData) vFree(p_stPlayer->pPlayerDescriptionData);
|
||
if(p_stPlayer->Options) vFree(p_stPlayer->Options);
|
||
p_stPlayer->pPlayerDescriptionData = (tdpPointer)C_pNull;
|
||
p_stPlayer->uxPlayerDescriptionLength = 0;
|
||
M_ulNetPlayerIdSlot(p_stPlayer) = C_uxNetInvalidId;
|
||
|
||
gs_stCurrentSession.uwNumberOfPlayers --;
|
||
|
||
eLevel1DisconnectRemotePlayer(ulOldPlayerId);
|
||
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
else return NetLib_E_es_UnknownPlayerId;
|
||
}
|
||
|
||
/*
|
||
------------------------------------------------------------------------------------------
|
||
SENDING MESSAGES:
|
||
------------------------------------------------------------------------------------------
|
||
*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eNetInternalSendMessage(NetLib_tdstSendDesc *p_stSendDesc,tdeNetMessageType eMessageType)
|
||
{
|
||
/* Local vars :*/
|
||
tdstNetMessage *pstMessage;
|
||
tdpPointer pOriginData;
|
||
NetLib_tdeErrorStatus eErrorReturned;
|
||
tdstNetBlockingLoopDescription stLoopDesc;
|
||
tdstNetInternalReadReceiptDesc *p_stInternalReadReceiptDesc;
|
||
NetLib_tdstDoForAllDesc stDoForAllDesc;
|
||
long a2_lParam[2];
|
||
tdstNetIter stIter;
|
||
|
||
/* Builds a tdstNetMessage object : */
|
||
pstMessage = (tdstNetMessage *)pMalloc(sizeof(tdstNetMessage)+p_stSendDesc->m_uwMessageLength);
|
||
if(pstMessage /*!=(tdstNetMessage*)C_pNull*/)
|
||
{
|
||
if(p_stSendDesc->m_uwMessageLength)
|
||
{
|
||
pOriginData = (tdpPointer)(pstMessage + 1);
|
||
g_pfn_vNetMemcpy(pOriginData,p_stSendDesc->m_pMessageData,p_stSendDesc->m_uwMessageLength);
|
||
}
|
||
|
||
pstMessage->eMessageType = eMessageType;
|
||
pstMessage->uwMessageSizeInBytes = p_stSendDesc->m_uwMessageLength;
|
||
pstMessage->uxPriority = p_stSendDesc->m_uxPriority;
|
||
pstMessage->uxReplaceType = p_stSendDesc->m_uxReplaceType;
|
||
pstMessage->uxReplace=p_stSendDesc->m_uxReplaceFlag;
|
||
pstMessage->uxRecipientId=p_stSendDesc->m_tduxRecipientId;
|
||
pstMessage->uxSenderId=NetLib_uxGetOwnPlayerId();
|
||
|
||
if(p_stSendDesc->m_ucReadReceiptFlag==NetLib_C_ucReadReceiptRequired)
|
||
{
|
||
pstMessage->m_uxReadReceiptId = p_stSendDesc->m_stReadReceiptDesc.m_uxReadReceiptId;
|
||
pstMessage->uxRecipientId = p_stSendDesc->m_tduxRecipientId;
|
||
eNetAddEngineFunction(iNetEngineReadReceipt);
|
||
|
||
if(pstMessage->uxRecipientId!=C_uxNetBroadcastId)
|
||
{/* build a internal read-receipt structure :*/
|
||
pNetList2IterInit(&stIter,&gs_stReadReceiptList);
|
||
vNetList2ToEnd(&stIter);
|
||
p_stInternalReadReceiptDesc=(tdstNetInternalReadReceiptDesc*)
|
||
pNetList2ReservElem(&stIter,sizeof(tdstNetInternalReadReceiptDesc));
|
||
if (p_stInternalReadReceiptDesc)
|
||
{
|
||
eErrorReturned=eNetBuildInternalReadReceiptDesc(p_stInternalReadReceiptDesc,pstMessage,&(p_stSendDesc->m_stReadReceiptDesc));
|
||
if(eErrorReturned != NetLib_E_es_NoError)
|
||
{
|
||
vFree((tdpPointer)pstMessage);
|
||
return eErrorReturned;
|
||
}
|
||
}
|
||
else return NetLib_E_es_NotEnoughMemory;
|
||
}
|
||
else
|
||
{
|
||
stDoForAllDesc.m_eGoOnCondition = NetLib_E_es_NoError;
|
||
stDoForAllDesc.m_pfn_eForAll = eNetBuildAndAddReadReceipt;
|
||
a2_lParam[0] = (long)pstMessage;
|
||
a2_lParam[1] = (long)&(p_stSendDesc->m_stReadReceiptDesc);
|
||
stDoForAllDesc.m_lParameter = (long)a2_lParam;
|
||
stDoForAllDesc.m_ucIncludeLocal = NetLib_C_ucNotIncludeLocalPlayer;
|
||
eErrorReturned = NetLib_eDoForAllPlayers(&stDoForAllDesc);
|
||
}
|
||
}
|
||
else pstMessage->m_uxReadReceiptId = NetLib_C_ucNoReadReceipt;
|
||
|
||
/* Call the level 1 function to send the message : */
|
||
if(gs_ArtificialLatency) eErrorReturned = eInternetSimuSendMessage(p_stSendDesc->m_tduxRecipientId,pstMessage);
|
||
else eErrorReturned = eLevel1SendMessage(pstMessage,E_Net_pr_InvalidProtocol,C_uwNetInvalidChannel);
|
||
if(eErrorReturned != NetLib_E_es_NoError) vFree((tdpPointer)pstMessage);
|
||
}
|
||
else return NetLib_E_es_NotEnoughMemory;
|
||
|
||
if ((eErrorReturned == NetLib_E_es_NoError) && (p_stSendDesc->m_ulMaxWaitingTime))
|
||
{
|
||
/* A blocking send is request :*/
|
||
|
||
/* Init the description structure:*/
|
||
stLoopDesc.m_ulMaxWaitingTime = p_stSendDesc->m_ulMaxWaitingTime;
|
||
stLoopDesc.m_eGoOnCondition = NetLib_E_es_False;
|
||
stLoopDesc.m_pfn_eEvaluation = eNetSendCompleted;
|
||
stLoopDesc.m_lParam = (long)(p_stSendDesc->m_tduxRecipientId);
|
||
|
||
/* Call the blocking procedure :*/
|
||
return NetLib_eBlockingLoop(&stLoopDesc);
|
||
}
|
||
return eErrorReturned;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_eSendMessage
|
||
Sends a message to a specific player
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : a pointer to a structure used to intialise the sending operation
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : An error code
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : August 27, 96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ NetLib_eSendMessage(NetLib_tdstSendDesc *p_stSendDesc)
|
||
{
|
||
#if defined(NET_USE_DEBUG)
|
||
vDebugSISISISI(Net_C_Debug_NetSer,"Send message Dest",p_stSendDesc->m_tduxRecipientId,
|
||
"Size",p_stSendDesc->m_uwMessageLength,
|
||
"Replace flag",p_stSendDesc->m_uxReplaceFlag,
|
||
"Read receipt flag",p_stSendDesc->m_ucReadReceiptFlag);
|
||
#endif /* NET_USE_DEBUG */
|
||
return eNetInternalSendMessage(p_stSendDesc,E_Net_mt_EngineMessage);
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : eNetBuildAndAddReadReceipt
|
||
Loop function for read-reciept management
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : A lot of things
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : An error code
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : October 21, 96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eNetBuildAndAddReadReceipt(NetLib_tduxPlayerId ulPlayerId,long lParam)
|
||
{
|
||
NetLib_tdeErrorStatus eErrorReturned;
|
||
tdstNetInternalReadReceiptDesc *p_stInternalReadReceiptDesc;
|
||
long *a2_lParam;
|
||
NetLib_tduxPlayerId ulOldPlayerId;
|
||
tdstNetIter stIter;
|
||
|
||
a2_lParam = (long*)lParam;
|
||
ulOldPlayerId = ((tdstNetMessage*)(a2_lParam[0]))->uxRecipientId;
|
||
((tdstNetMessage*)(a2_lParam[0]))->uxRecipientId = ulPlayerId;
|
||
pNetList2IterInit(&stIter,&gs_stReadReceiptList);
|
||
vNetList2ToEnd(&stIter);
|
||
p_stInternalReadReceiptDesc=(tdstNetInternalReadReceiptDesc*)
|
||
pNetList2ReservElem(&stIter,sizeof(tdstNetInternalReadReceiptDesc));
|
||
if (p_stInternalReadReceiptDesc)
|
||
{
|
||
eErrorReturned=eNetBuildInternalReadReceiptDesc(p_stInternalReadReceiptDesc,(tdstNetMessage*)(a2_lParam[0]),(NetLib_tdstReadReceiptDesc *)(a2_lParam[1]));
|
||
}
|
||
else eErrorReturned=NetLib_E_es_NotEnoughMemory;
|
||
|
||
((tdstNetMessage*)(a2_lParam[0]))->uxRecipientId = ulOldPlayerId;
|
||
|
||
return eErrorReturned;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_eFlushSendingList
|
||
Empty sending list of all players, sending system list
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : Time out
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_NoError if the operation is completed
|
||
An error code if there is a problem
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : September 3, 96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ NetLib_eFlushSendingList(NetLib_tdulTimeInfo ulMaxWaitingTime)
|
||
{
|
||
tdstNetBlockingLoopDescription stLoopDesc;
|
||
|
||
stLoopDesc.m_ulMaxWaitingTime = ulMaxWaitingTime;
|
||
stLoopDesc.m_eGoOnCondition = NetLib_E_es_OperationInProgress;
|
||
stLoopDesc.m_pfn_eEvaluation = eNetFlushCompleted;
|
||
stLoopDesc.m_lParam = (long)C_pNull;
|
||
return NetLib_eBlockingLoop(&stLoopDesc);
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : eNetSendCompleted
|
||
Check if a sending operation is completed or not
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : void *vParam : a player id casted into a void*
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_False if the sending list of the player is ok but not empty
|
||
NetLib_E_es_NoError if the sending list is ok and empty
|
||
An error code if the sending list is not ok
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : August 27, 96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eNetSendCompleted(long lParam)
|
||
{
|
||
NetLib_tdeErrorStatus eErrorReturned;
|
||
if (((eErrorReturned = eLevel1IsSendingListOk((NetLib_tduxPlayerId)lParam))==NetLib_E_es_NoError)
|
||
&&(eLevel1IsSendingListEmpty((NetLib_tduxPlayerId)lParam)!=NetLib_E_es_True))
|
||
return NetLib_E_es_False;
|
||
|
||
return eErrorReturned;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_ePlayerFlushCompleted
|
||
Check if a flush operation is completed or not for a specific player
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : ulPlayerId the id of the player concerned
|
||
ulParameter : not used
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_NoError if the operation is completed
|
||
NetLib_E_es_OperationInProgress if the operation is not completed
|
||
An error code if there is a problem
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : September 3, 96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ NetLib_ePlayerFlushCompleted(NetLib_tduxPlayerId ulPlayerId,long lParameter)
|
||
{
|
||
NetLib_tdeErrorStatus eErrorReturned;
|
||
|
||
eErrorReturned = NetLib_E_es_NoError;
|
||
if ((eLevel1IsSendingListEmpty(ulPlayerId)!=NetLib_E_es_True)
|
||
&&((eErrorReturned = eLevel1IsSendingListOk(ulPlayerId))==NetLib_E_es_NoError))
|
||
return NetLib_E_es_OperationInProgress;
|
||
|
||
return eErrorReturned;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : eNetFlushCompleted
|
||
Check if a flush operation is completed or not
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : void *vParam : not used
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_NoError if the operation is completed
|
||
NetLib_E_es_OperationInProgress if the operation is not completed
|
||
An error code if there is a problem
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : September 3, 96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eNetFlushCompleted(long Param)
|
||
{
|
||
NetLib_tdeErrorStatus eErrorReturned;
|
||
NetLib_tdstDoForAllDesc stDoForAllDesc;
|
||
|
||
if((eErrorReturned = NetLib_ePlayerFlushCompleted(C_uxNetSystemId,0L))!=NetLib_E_es_NoError)
|
||
return eErrorReturned;
|
||
|
||
stDoForAllDesc.m_pfn_eForAll = NetLib_ePlayerFlushCompleted;
|
||
stDoForAllDesc.m_eGoOnCondition = NetLib_E_es_NoError;
|
||
stDoForAllDesc.m_lParameter = 0L;
|
||
stDoForAllDesc.m_ucIncludeLocal = NetLib_C_ucNotIncludeLocalPlayer;
|
||
|
||
return NetLib_eDoForAllPlayers(&stDoForAllDesc);
|
||
}
|
||
|
||
/*
|
||
------------------------------------------------------------------------------------------
|
||
GETTING MESSAGES :
|
||
------------------------------------------------------------------------------------------
|
||
*/
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : eLevel1SendReadReceiptMessage
|
||
Sends a read receipt msg
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : a message
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_NoError if no error occured
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eNetSendReadReceiptMessage(tdstNetMessage *p_stMsg)
|
||
{
|
||
tdstNetMessage *p_stNewMsg;
|
||
p_stNewMsg = (tdstNetMessage*)pMalloc(sizeof(tdstNetMessage)+sizeof(NetLib_uxReadReceiptId));
|
||
if(!p_stNewMsg) return NetLib_E_es_NotEnoughMemory;
|
||
|
||
/* initialise the msg header:*/
|
||
p_stNewMsg->eMessageType = E_Net_mt_ReadReceipt;
|
||
p_stNewMsg->uxRecipientId=p_stMsg->uxSenderId;
|
||
p_stNewMsg->uxSenderId=NetLib_uxGetOwnPlayerId();
|
||
p_stNewMsg->uxPriority = NetLib_C_uxMaxPriority;
|
||
p_stNewMsg->uxReplaceType = 0;
|
||
p_stNewMsg->uxReplace = 0;
|
||
p_stNewMsg->m_uxReadReceiptId = NetLib_C_ucNoReadReceipt;
|
||
p_stNewMsg->uwMessageSizeInBytes = sizeof(NetLib_uxReadReceiptId);
|
||
/* set the msg body :*/
|
||
*((NetLib_uxReadReceiptId*)(p_stNewMsg+1)) = p_stMsg->m_uxReadReceiptId;
|
||
|
||
return eLevel1SendMessage(p_stNewMsg,E_Net_pr_InvalidProtocol,C_uwNetInvalidChannel);
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_eReadMessage
|
||
Reads a message from a player.
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input :
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_NoError : if no errors occurs or an error code
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : August 27,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ NetLib_eReadMessage(NetLib_tdstReadDesc *p_stReadDesc)
|
||
{
|
||
/* Local vars :*/
|
||
tdstNetMessage *p_stReadMessage;
|
||
NetLib_tdeErrorStatus eErrorReturned;
|
||
tdpPointer pOriginData;
|
||
tdstNetBlockingLoopDescription stBlockingLoopDesc;
|
||
|
||
p_stReadMessage = (tdstNetMessage*)C_pNull;
|
||
if(p_stReadDesc->m_ulMaxWaitingTime)
|
||
{
|
||
/* a time-out is specified, so wait for a message :*/
|
||
stBlockingLoopDesc.m_ulMaxWaitingTime = p_stReadDesc->m_ulMaxWaitingTime;
|
||
stBlockingLoopDesc.m_eGoOnCondition = NetLib_E_es_FIFOIsEmpty;
|
||
stBlockingLoopDesc.m_pfn_eEvaluation = eNetReadCompleted;
|
||
stBlockingLoopDesc.m_lParam = p_stReadDesc->m_uxSenderId?(long)&p_stReadDesc->m_uxSenderId : (long)C_pNull;
|
||
|
||
if((eErrorReturned = NetLib_eBlockingLoop(&stBlockingLoopDesc))!=NetLib_E_es_NoError)
|
||
return eErrorReturned;
|
||
}
|
||
|
||
eErrorReturned = eLevel1ReadMessage(p_stReadDesc->m_uxSenderId,&p_stReadMessage,p_stReadDesc->m_bRemoveFromQueue);
|
||
|
||
if(eErrorReturned == NetLib_E_es_NoError)
|
||
{
|
||
/* It should not be C_pNull :*/
|
||
if(p_stReadMessage /*!=(tdstNetMessage*)C_pNull*/)
|
||
{
|
||
#if defined(NET_USE_DEBUG)
|
||
vDebugSISI(Net_C_Debug_NetSer,"Read message Source",p_stReadMessage->uxSenderId,
|
||
"Size",p_stReadMessage->uwMessageSizeInBytes);
|
||
#endif /* NET_USE_DEBUG */
|
||
p_stReadDesc->m_uxSenderId=p_stReadMessage->uxSenderId;
|
||
/* the data begins after the header of the message :*/
|
||
pOriginData = (tdpPointer)(p_stReadMessage + 1);
|
||
/* Determines wether the buffer given is enough : */
|
||
if(p_stReadMessage->uwMessageSizeInBytes <= p_stReadDesc->m_uwMessageLength)
|
||
p_stReadDesc->m_uwMessageLength = p_stReadMessage->uwMessageSizeInBytes; /* Sets the value of the bytes read */
|
||
else/* The message read is larger than the buffer given iin argument*/
|
||
eErrorReturned = p_stReadDesc->m_uwMessageLength?
|
||
NetLib_E_es_MessageTooLong:/* if not 0, the buffer specified is too short*/
|
||
NetLib_E_es_NoError;/* if 0 is specified, the data is not copied to the buffer*/
|
||
|
||
if ((p_stReadDesc->m_pMessageData) && (p_stReadDesc->m_uwMessageLength)) /* copy all the data to the buffer*/
|
||
g_pfn_vNetMemcpy(p_stReadDesc->m_pMessageData,pOriginData,p_stReadDesc->m_uwMessageLength);
|
||
|
||
/* Sets the original size of the message :*/
|
||
p_stReadDesc->m_uwOrigMsgLength = p_stReadMessage->uwMessageSizeInBytes;
|
||
/* if th emsg requires a read-receipt, send it :*/
|
||
if(p_stReadMessage->m_uxReadReceiptId!=NetLib_C_ucNoReadReceipt) eNetSendReadReceiptMessage(p_stReadMessage);
|
||
|
||
/* Frees the memory allocated : */
|
||
if(p_stReadDesc->m_bRemoveFromQueue) vFree((tdpPointer)p_stReadMessage);
|
||
|
||
return eErrorReturned;
|
||
}
|
||
p_stReadDesc->m_uwMessageLength = 0;
|
||
return NetLib_E_es_UnknownError;
|
||
}
|
||
return eErrorReturned;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : eNetReadCompleted
|
||
Check if a reading operation is completed or not
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : the player id casted in void*
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_FIFOIsEmpty if no message is available,
|
||
NetLib_E_es_NoError if no error occured; or a specific error code.
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : August 27,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eNetReadCompleted(long lParam)
|
||
{
|
||
tdstNetMessage *p_stReadMessage;
|
||
NetLib_tduxPlayerId ulPlayerId = (NetLib_tduxPlayerId)lParam;
|
||
|
||
return eLevel1ReadMessage(ulPlayerId,&p_stReadMessage,0);
|
||
}
|
||
|
||
/*
|
||
------------------------------------------------------------------------------------------
|
||
NETLIB ENGINE FUNCTIONS :
|
||
------------------------------------------------------------------------------------------
|
||
*/
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description :void NetLib_vEngine(void)
|
||
Engine of the net.
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : none
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : none
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : April 4,96
|
||
Author : Albert Pais
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Comment :
|
||
This function ensures the behavior of the net library.
|
||
It sends effectively messages.
|
||
It ensures incomming messages.
|
||
It processes system messages....
|
||
This function must be call in all loop where communication is required.
|
||
For example :
|
||
while(..)
|
||
{
|
||
// Calling for a net function or expecting a net callback :
|
||
...
|
||
// Must call vNetEngine :
|
||
vNetEngine();
|
||
...
|
||
}
|
||
It can also be called in a separated thread...
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
void _NET_CALLING_CONV_ NetLib_vEngine(void)
|
||
{
|
||
tdstNetIter stIter;
|
||
tdfn_vNetEngineFunc *ppfnEngine;
|
||
#if defined(NET_USE_DEBUG)
|
||
vDebugS(Net_C_Debug_NetSer,"vNetEngine");
|
||
#endif /* NET_USE_DEBUG */
|
||
|
||
ppfnEngine=(tdfn_vNetEngineFunc*)pNetList2IterInit(&stIter,&gs_stEngineFunction);
|
||
while (ppfnEngine)
|
||
{
|
||
if ((*ppfnEngine)()) ppfnEngine=(tdfn_vNetEngineFunc*)pNetList2DeleteElem(&stIter);
|
||
else ppfnEngine=(tdfn_vNetEngineFunc*)pNetList2Next(&stIter);
|
||
}
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : eNetBuildEngineFunctionsList
|
||
Builds the initial engine function list
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : None
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : A netLib_tdeErrorStatus code
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : September 16,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus eNetBuildEngineFunctionsList(void)
|
||
{
|
||
if (iNetList2Init(&gs_stEngineFunction)) return NetLib_E_es_NotEnoughMemory;
|
||
|
||
/* Add functions :*/
|
||
eNetAddEngineFunction(iNetEngineSysMsg);
|
||
eNetAddEngineFunction(iLevel1NetEngine);
|
||
eNetAddEngineFunction(iNetEngineTCPReconect);
|
||
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : eNetAddEngineFunction
|
||
Adds an engine function
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : a pointer to a function(void)(*)(void)
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : A netLib_tdeErrorStatus code
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : September 16,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus eNetAddEngineFunction(tdfn_vNetEngineFunc p_fn_vEngineFunc)
|
||
{
|
||
tdstNetIter stIter;
|
||
tdfn_vNetEngineFunc *ppfnEngine;
|
||
|
||
ppfnEngine=(tdfn_vNetEngineFunc*)pNetList2IterInit(&stIter,&gs_stEngineFunction);
|
||
while (ppfnEngine)
|
||
{
|
||
if (*ppfnEngine==p_fn_vEngineFunc) return NetLib_E_es_NoError;
|
||
else ppfnEngine=(tdfn_vNetEngineFunc*)pNetList2Next(&stIter);
|
||
}
|
||
if (pNetList2InsertElem(&stIter,&p_fn_vEngineFunc,sizeof(tdfn_vNetEngineFunc)))
|
||
return NetLib_E_es_NoError;
|
||
else return NetLib_E_es_NotEnoughMemory;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : eNetRemoveEngineFunction
|
||
Removes an engine function
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : a pointer to a function(void)(*)(void)
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : A netLib_tdeErrorStatus code
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : September 16,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus eNetRemoveEngineFunction(tdfn_vNetEngineFunc p_fn_vEngineFunc)
|
||
{
|
||
tdstNetIter stIter;
|
||
tdfn_vNetEngineFunc *ppfnEngine;
|
||
|
||
ppfnEngine=(tdfn_vNetEngineFunc*)pNetList2IterInit(&stIter,&gs_stEngineFunction);
|
||
while (ppfnEngine)
|
||
{
|
||
if (*ppfnEngine==p_fn_vEngineFunc)
|
||
{
|
||
pNetList2DeleteElem(&stIter);
|
||
break;
|
||
}
|
||
else ppfnEngine=(tdfn_vNetEngineFunc*)pNetList2Next(&stIter);
|
||
}
|
||
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : eNetEmptyEngineFunctionList
|
||
Empties the netengine function list
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : None
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : A netLib_tdeErrorStatus code
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : September 16,96
|
||
Author : Albert Pais
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Comment :
|
||
There is no free to the pointer returned by the getfirstcelldata function
|
||
since it is a function pointer
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus eNetEmptyEngineFunctionList(void)
|
||
{
|
||
tdstNetIter stIter;
|
||
pNetList2IterInit(&stIter,&gs_stEngineFunction);
|
||
vNetList2Clear(&stIter);
|
||
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : iNetEngineSysMsg
|
||
Engine function : handles sys msg.
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : none
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : none
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : September 16,96
|
||
Author : Albert Pais
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Comment : A call to vLevel1OutgoingNetEngine is done just after processing sys msg because
|
||
an answer could have been posted
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
int _NET_CALLING_CONV_ iNetEngineSysMsg(void)
|
||
{
|
||
NetLib_tdeErrorStatus eErrorReturned;
|
||
tdstNetMessage *pstMes;
|
||
tdeNetProtocol eProt;
|
||
tduwNetChannel uwChannel;
|
||
|
||
while(eLevel1GetSysMsg(&pstMes,&eProt,&uwChannel) != NetLib_E_es_FIFOIsEmpty)
|
||
{
|
||
if (pstMes && (pstMes->eMessageType > E_Net_mt_FirstSysMessage)
|
||
&& (pstMes->eMessageType < E_Net_mt_LastSysMsg)
|
||
&& (gs_pfn_eSysMsgMap[pstMes->eMessageType]))
|
||
{
|
||
if ((pstMes->uxBodyBigEndian!=NetLib_ucGetLittleBigEndian())
|
||
&&(gs_pfn_eSysMsgSwapMap[pstMes->eMessageType]))
|
||
gs_pfn_eSysMsgSwapMap[pstMes->eMessageType](pstMes,eProt,uwChannel);
|
||
|
||
eErrorReturned=gs_pfn_eSysMsgMap[pstMes->eMessageType](pstMes,eProt,uwChannel);
|
||
}
|
||
else
|
||
{
|
||
eErrorReturned = NetLib_E_es_ShouldNotReach;
|
||
vFree(pstMes);
|
||
}
|
||
}
|
||
|
||
vLevel1OutgoingNetEngine();
|
||
return 0;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : iNetEngineGetActiveSession
|
||
Engine function : Handles getactive sessions.
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : none
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : none
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : September 16,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
int _NET_CALLING_CONV_ iNetEngineGetActiveSession(void)
|
||
{
|
||
/*if we are in a listening mode, send a listening msg :*/
|
||
if ((gs_eListeningMode == E_Net_LisMod_ON)
|
||
&&(g_pfn_ulNetGetTimeInfo()-gs_tm_ulPrevGetActiveSessions >=gs_tm_ulGetActiveSessionsFreq)
|
||
&&(gs_uwNumberOfSessionsExpected > gs_c_uwNumberOfSessionsDetected)
|
||
&&(eLevel1SendSessionRequestMsg(gs_uxMaxPlayerInfo)==NetLib_E_es_NoError))
|
||
{
|
||
gs_tm_ulPrevGetActiveSessions = g_pfn_ulNetGetTimeInfo();
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : iNetEngineReadReceipt
|
||
Engine function : Handles read receipt message.
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : none
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : none
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : Octover 15,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
int _NET_CALLING_CONV_ iNetEngineReadReceipt(void)
|
||
{
|
||
NetLib_tdulTimeInfo ulCurrentTime;
|
||
tdstNetMessage *p_stNewMessage;
|
||
NetLib_tdeErrorStatus eErrorReturned;
|
||
tdstNetIter stIter;
|
||
tdstNetInternalReadReceiptDesc *p_stInternalReadReceiptDesc;
|
||
|
||
p_stInternalReadReceiptDesc=(tdstNetInternalReadReceiptDesc*)
|
||
pNetList2IterInit(&stIter,&gs_stReadReceiptList);
|
||
while (p_stInternalReadReceiptDesc)
|
||
{
|
||
ulCurrentTime = g_pfn_ulNetGetTimeInfo();
|
||
/* Check time:*/
|
||
if (p_stInternalReadReceiptDesc->m_ulFirstSending+
|
||
p_stInternalReadReceiptDesc->m_stReadReceiptDesc.m_ulMaxWaitingTime<ulCurrentTime)
|
||
{ /* too much time elapsed without receiving a read receipt*/
|
||
/* Call the callback with the failure flag*/
|
||
if(p_stInternalReadReceiptDesc->m_stReadReceiptDesc.p_fnv_ReadReceiptCallback)
|
||
{
|
||
p_stInternalReadReceiptDesc->m_stReadReceiptDesc.p_fnv_ReadReceiptCallback(
|
||
p_stInternalReadReceiptDesc->m_p_stMessage->uxRecipientId,
|
||
p_stInternalReadReceiptDesc->m_stReadReceiptDesc.m_uxReadReceiptId,
|
||
NetLib_C_ucReadReceiptFailure,
|
||
p_stInternalReadReceiptDesc->m_stReadReceiptDesc.m_lCallbackParam);
|
||
}
|
||
/* remove the message :*/
|
||
eNetEraseInternalReadReceiptDesc(p_stInternalReadReceiptDesc);
|
||
p_stInternalReadReceiptDesc=(tdstNetInternalReadReceiptDesc*)pNetList2DeleteElem(&stIter);
|
||
}
|
||
else
|
||
{/* check if it is time to send again*/
|
||
if ((p_stInternalReadReceiptDesc->m_stReadReceiptDesc.m_ulReemitFreq)
|
||
&&(p_stInternalReadReceiptDesc->m_ulPreviousSending+p_stInternalReadReceiptDesc->m_stReadReceiptDesc.m_ulReemitFreq
|
||
<=ulCurrentTime))
|
||
{/* it's time to resend*/
|
||
p_stNewMessage = (tdstNetMessage*)pMalloc(sizeof(tdstNetMessage)+p_stInternalReadReceiptDesc->m_p_stMessage->uwMessageSizeInBytes);
|
||
if(p_stNewMessage)
|
||
{
|
||
g_pfn_vNetMemcpy(p_stNewMessage,p_stInternalReadReceiptDesc->m_p_stMessage,
|
||
sizeof(tdstNetMessage)+p_stInternalReadReceiptDesc->m_p_stMessage->uwMessageSizeInBytes);
|
||
p_stNewMessage->uxSenderId=NetLib_uxGetOwnPlayerId();
|
||
/* Call the level 1 function to send the message : */
|
||
if(gs_ArtificialLatency) eErrorReturned = eInternetSimuSendMessage(p_stNewMessage->uxRecipientId,p_stNewMessage);
|
||
else eErrorReturned = eLevel1SendMessage(p_stNewMessage,E_Net_pr_InvalidProtocol,C_uwNetInvalidChannel);
|
||
if(eErrorReturned ==NetLib_E_es_NoError) p_stInternalReadReceiptDesc->m_ulPreviousSending = ulCurrentTime;
|
||
}
|
||
}
|
||
p_stInternalReadReceiptDesc=(tdstNetInternalReadReceiptDesc*)pNetList2Next(&stIter);
|
||
}
|
||
}
|
||
if (ulNetList2NbrElem(&gs_stReadReceiptList)==0) return 1;
|
||
else return 0;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : iNetEngineInternetSimulation
|
||
Engine function : Simulate internet delay.
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : none
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : none
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : September 16,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
int _NET_CALLING_CONV_ iNetEngineInternetSimulation(void)
|
||
{
|
||
/* If internet delay, send what must be sent :*/
|
||
if(gs_ArtificialLatency) eNetManageInternetDelay();
|
||
return 0;
|
||
}
|
||
|
||
/*
|
||
------------------------------------------------------------------------------------------
|
||
CLOSING THE LIBRARY:
|
||
------------------------------------------------------------------------------------------
|
||
*/
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_vCloseLibrary
|
||
Close definetively the library.
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : none
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : none
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : May 6,96
|
||
Author : Albert Pais
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Comment : before calling this function, make sure that no more connection exists
|
||
with remote players. if not, call the vDisconnectFromSession function.
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
void _NET_CALLING_CONV_ NetLib_vCloseLibrary(void)
|
||
{
|
||
unsigned short c_uwCount;
|
||
|
||
vNetLibFreeSynchro();
|
||
|
||
vNetList2Kill(&gs_stPlayerSendingList);
|
||
vNetList2Kill(&gs_stReadReceiptList);
|
||
|
||
/* dispose of time delta information */
|
||
if (gs_d_stTimeDeltas) vFree((tdpPointer) gs_d_stTimeDeltas);
|
||
gs_d_stTimeDeltas = (tdstNetTimeDelta *) C_pNull;
|
||
gs_ulLocalTimeScale = 0;
|
||
gs_b_ucDeltaCalibrationIsEnabled = 0;
|
||
|
||
/* Sets the session id to an invalid one :*/
|
||
vNetSetSessionId(C_uxNetInvalidId);
|
||
/* Sets the length of the description to zero :*/
|
||
gs_stCurrentSession.uxSessionDescriptionLength = 0;
|
||
/* Free the memory used for the session description :*/
|
||
if(gs_stCurrentSession.pSessionDescriptionData)
|
||
vFree((tdpPointer)gs_stCurrentSession.pSessionDescriptionData);
|
||
gs_stCurrentSession.pSessionDescriptionData = C_pNull;
|
||
/* Deleting informations about the current session :*/
|
||
for (c_uwCount=0;c_uwCount<gs_stCurrentSession.uwMaxNumberOfPlayers;c_uwCount++)
|
||
{/* For each player, free the memory used for the description data*/
|
||
if(gs_stCurrentSession.d_stPlayerInfo[c_uwCount].pPlayerDescriptionData)
|
||
vFree((tdpPointer)gs_stCurrentSession.d_stPlayerInfo[c_uwCount].pPlayerDescriptionData);
|
||
}
|
||
/* Free the memory used for the array of players*/
|
||
vFree((tdpPointer)gs_stCurrentSession.d_stPlayerInfo);
|
||
gs_stCurrentSession.d_stPlayerInfo = (NetLib_tdstPlayerInfo *)C_pNull;
|
||
/* Sets the max number of players to zero :*/
|
||
gs_stCurrentSession.uwMaxNumberOfPlayers = 0;
|
||
/* sets the number of players to zero :*/
|
||
gs_stCurrentSession.uwNumberOfPlayers = 0;
|
||
/* Sets the index of the local player to an invalid value*/
|
||
gs_stCurrentSession.uwIndexOfLocalPlayer = (unsigned short)-1;
|
||
|
||
if(gs_p_stPreSessionPlayerInfo) vFree((tdpPointer)gs_p_stPreSessionPlayerInfo);
|
||
gs_p_stPreSessionPlayerInfo = (NetLib_tdstPlayerInfo *)C_pNull;
|
||
gs_tdePreSessionPlayerStatus = E_Net_ConRecSta_NONE;
|
||
|
||
NetLib_eCloseAndResetGetActiveSessions();
|
||
gs_eListeningMode = E_Net_LisMod_INVALID;
|
||
|
||
if(gs_p_stConnectRequestSessionInfo)
|
||
vFree((tdpPointer)gs_p_stConnectRequestSessionInfo);
|
||
gs_p_stConnectRequestSessionInfo = (NetLib_tdstSessionInfo *)C_pNull;
|
||
|
||
if(gs_d_tdeConnectRequestStatusArray)
|
||
vFree((tdpPointer)gs_d_tdeConnectRequestStatusArray);
|
||
gs_d_tdeConnectRequestStatusArray = (tdeNetConnectRequestStatus *)C_pNull;
|
||
|
||
g_pfn_vDisconnectCallBack = (NetLib_tdfnvDisconnectCallback)C_pNull;
|
||
g_pfn_ulNetRandom = (NetLib_tdfnulRandom)C_pNull;
|
||
g_pfn_ulNetGetTimeInfo = (NetLib_tdfnulGetTimeInfo)C_pNull;
|
||
|
||
/* Empty engine function list:*/
|
||
eNetEmptyEngineFunctionList();
|
||
vNetList2Kill(&gs_stEngineFunction);
|
||
/* Clear message map :*/
|
||
eNetClearMessageMap();
|
||
eNetClearMessageSwapLittleBigEndianMap();
|
||
|
||
/* Calling level-1 closing function :*/
|
||
vLevel1CloseLibrary();
|
||
/* Frees the memory used for the library*/
|
||
vDoneMalloc();
|
||
gs_cIsNetlibInitialised = 0;
|
||
}
|
||
|
||
/*
|
||
------------------------------------------------------------------------------------------
|
||
OTHER FUNCTIONS :
|
||
------------------------------------------------------------------------------------------
|
||
*/
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_eDoForAllPlayers
|
||
Call a specific function for all the players in the library.
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : pfn_ucForAll pointer to the function called
|
||
ulParameter : parameter given to the function
|
||
ucIncludeLocal : if it is non-zero, the function is also called for the local player,
|
||
otherwise not.
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : the last value returned by the function
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : August 9,1996
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ NetLib_eDoForAllPlayers(NetLib_tdstDoForAllDesc *p_stDoForAllDesc)
|
||
{
|
||
unsigned short uwPosition;
|
||
NetLib_tdeErrorStatus eErrorReturned;
|
||
|
||
/* If the local player is included :*/
|
||
if(p_stDoForAllDesc->m_ucIncludeLocal == NetLib_C_ucIncludeLocalPlayer)
|
||
{
|
||
eErrorReturned=p_stDoForAllDesc->m_pfn_eForAll(NetLib_uxGetOwnPlayerId(),
|
||
p_stDoForAllDesc->m_lParameter);
|
||
}
|
||
else eErrorReturned = p_stDoForAllDesc->m_eGoOnCondition;
|
||
|
||
uwPosition = NetLib_uwGetFirstRemotePlayerIdPosition();
|
||
if(uwPosition == NetLib_C_uwInvalidPosition)
|
||
return NetLib_E_es_NoMorePlayers;
|
||
|
||
while ((uwPosition != NetLib_C_uwInvalidPosition)
|
||
&&(eErrorReturned == p_stDoForAllDesc->m_eGoOnCondition))
|
||
{
|
||
eErrorReturned = p_stDoForAllDesc->m_pfn_eForAll(NetLib_uxGetNextRemotePlayerId(&uwPosition),
|
||
p_stDoForAllDesc->m_lParameter);
|
||
}
|
||
|
||
return eErrorReturned;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_eBlockingLoop
|
||
Bloking loop function
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : a pointer to a tdstNetBlockingLoopDescription
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_TimeOut if a time out occured
|
||
Or an error code returned by the evaluation function
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : August 27,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ NetLib_eBlockingLoop(tdstNetBlockingLoopDescription *p_stLoopParam)
|
||
{
|
||
NetLib_tdeErrorStatus eErrorReturned;
|
||
NetLib_tdulTimeInfo ulWaitingTime;
|
||
|
||
if(g_pfn_ulNetGetTimeInfo) ulWaitingTime = g_pfn_ulNetGetTimeInfo();
|
||
else
|
||
{
|
||
if(p_stLoopParam->m_ulMaxWaitingTime)
|
||
return NetLib_E_es_TimeOutNotInitialised;
|
||
ulWaitingTime = 0;
|
||
}
|
||
|
||
/* Blocking loop :*/
|
||
do
|
||
{
|
||
NetLib_vEngine();
|
||
if ((g_pfn_ulNetGetTimeInfo)
|
||
&&(ulWaitingTime + p_stLoopParam->m_ulMaxWaitingTime < g_pfn_ulNetGetTimeInfo()))
|
||
eErrorReturned = NetLib_E_es_TimeOut;
|
||
else eErrorReturned = p_stLoopParam->m_pfn_eEvaluation(p_stLoopParam->m_lParam);
|
||
}while(eErrorReturned == p_stLoopParam->m_eGoOnCondition);
|
||
|
||
/* We leave the loop :*/
|
||
return eErrorReturned;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : eNetIsMessageType
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input :
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_True
|
||
NetLib_E_es_False
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : August 22,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eNetIsMessageType(tdstNetMessage *p_stMessage,void *p_vType)
|
||
{
|
||
if(p_stMessage->eMessageType == *((tdeNetMessageType*)p_vType)) return NetLib_E_es_True;
|
||
else return NetLib_E_es_False;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : unsigned long ulTimeInfoToLagUnits(NetLib_tdulTimeInfo ulTime, unsigned long ulTickForTimeInfo)
|
||
converts the value returned by the time info function to universal time units.
|
||
This is because time info functions may return values in different units on the
|
||
various platforms. This function is necessary to uniformize the values.
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : ulTime: the time to convert
|
||
ulTickForTimeInfo: ticks for one second in time info units
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : the converted time
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : July 30,96
|
||
Author : Benoit Germain
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
unsigned long ulTimeInfoToLagUnits(NetLib_tdulTimeInfo ulTime, unsigned long ulTickForTimeInfo)
|
||
{
|
||
return (unsigned long)(ulTime * (C_ulUniversalLagUnit / (double)ulTickForTimeInfo));
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : tdeErrorStatus eNetDenyPlayerAccess(NetLib_tdstPlayerInfo *p_stPlayerInfo)
|
||
returns always false. This is to be used in the g_pfn_ePlayerConnectionRequestFilter
|
||
variable so that all incoming player connexion requests are denied.
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : a structure describing a player
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_False
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : June 20,96
|
||
Author : Benoit Germain
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eNetDenyPlayerAccess(NetLib_tdstPlayerInfo *p_stConReqDesc,long *plParam)
|
||
{
|
||
*plParam = -1;
|
||
return NetLib_E_es_False;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_tduxPlayerId ulNetGetNewPlayerId
|
||
Returns a new player Id
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : None
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : tdulPlauyerId : a new player id
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : April 5, 96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tduxPlayerId ulNetGetNewPlayerId()
|
||
{
|
||
return (NetLib_tduxPlayerId)((*g_pfn_ulNetRandom)() % (C_uxNetLastUserId+1));
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_tdulTimeInfo ulLagUnitsToTimeInfo(NetLib_tdulTimeInfo ulTime, unsigned long ulTickForTimeInfo)
|
||
converts an universal lag unit expressed time to its time info united value.
|
||
This is because time info functions may return values in different units on the
|
||
various platforms. This function is necessary to uniformize the values.
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : ulLagTime: the time to convert
|
||
ulTickForTimeInfo: ticks for one second in time info units
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : the converted time
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : July 30,96
|
||
Author : Benoit Germain
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdulTimeInfo ulLagUnitsToTimeInfo(unsigned long ulLagTime, unsigned long ulTickForTimeInfo)
|
||
{
|
||
return (unsigned long)(ulLagTime * (ulTickForTimeInfo / (double)C_ulUniversalLagUnit));
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : eNetEraseInternalReadReceiptDesc
|
||
Erase an internal readreceipt desc
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : A pointer to a pointer to the read-receipt object
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : an error status
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : October 15,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus eNetEraseInternalReadReceiptDesc(tdstNetInternalReadReceiptDesc *p_stInternalReadReceiptDesc)
|
||
{
|
||
vFree((tdpPointer)(p_stInternalReadReceiptDesc->m_p_stMessage));
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : eNetBuildInternalReadReceiptDesc
|
||
Build a read/receipt internal structure
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : A pointer to a pointer to an internal read-receipt description structure
|
||
A pointer to a message
|
||
A pointer to a read-receipt description structure
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : an error status
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : October 16,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus eNetBuildInternalReadReceiptDesc(tdstNetInternalReadReceiptDesc *p_stInternalReadReceiptDesc,
|
||
tdstNetMessage *p_stMessage,NetLib_tdstReadReceiptDesc *p_stReadReceiptDesc)
|
||
{
|
||
if(!p_stMessage) return NetLib_E_es_InvalidMessage;
|
||
/* initialise the structure:*/
|
||
p_stInternalReadReceiptDesc->m_p_stMessage=(tdstNetMessage*)pMalloc(sizeof(tdstNetMessage)+p_stMessage->uwMessageSizeInBytes);
|
||
if(!p_stInternalReadReceiptDesc->m_p_stMessage) return NetLib_E_es_NotEnoughMemory;
|
||
/* copy the message :*/
|
||
g_pfn_vNetMemcpy(p_stInternalReadReceiptDesc->m_p_stMessage,p_stMessage,sizeof(tdstNetMessage)+p_stMessage->uwMessageSizeInBytes);
|
||
/* copy the read-receipt description structure*/
|
||
g_pfn_vNetMemcpy(&(p_stInternalReadReceiptDesc->m_stReadReceiptDesc),p_stReadReceiptDesc,sizeof(NetLib_tdstReadReceiptDesc));
|
||
/* init time info :*/
|
||
p_stInternalReadReceiptDesc->m_ulPreviousSending=p_stInternalReadReceiptDesc->m_ulFirstSending=g_pfn_ulNetGetTimeInfo();
|
||
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/*
|
||
------------------------------------------------------------------------------------------
|
||
DEFAULT NET FUNCTIONS
|
||
------------------------------------------------------------------------------------------
|
||
*/
|
||
#ifndef _NO_USE_DEFAULT_NET_FUNCTIONS_
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : unsigned long fn_ulDefaultNetRandom(void)
|
||
Default random function
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : None
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : unsigned long : random number
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : April 5, 96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
unsigned long _NET_CALLING_CONV_ fn_ulDefaultNetRandom(void)
|
||
{
|
||
unsigned long ulRandomValueReturned;
|
||
/* Getting a 32-bit random value : */
|
||
ulRandomValueReturned = (((unsigned long)rand())<<16) |((unsigned short)rand());
|
||
return ulRandomValueReturned;
|
||
}
|
||
|
||
#endif /*_NO_USE_DEFAULT_NET_FUNCTIONS_*/
|
||
|
||
#ifndef _NO_USE_DEFAULT_NET_FUNCTIONS_
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_tdulTimeInfo fn_ulDefaultNetGetTimeInfo(void)
|
||
Default function for getting time info (used for timeout)
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : None
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_tdulTimeInfo
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : April 5, 96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdulTimeInfo _NET_CALLING_CONV_ fn_ulDefaultNetGetTimeInfo(void)
|
||
{
|
||
return (NetLib_tdulTimeInfo)GetTickCount();
|
||
}
|
||
#endif /*_NO_USE_DEFAULT_NET_FUNCTIONS_*/
|
||
|
||
/*
|
||
------------------------------------------------------------------------------------------
|
||
NETLIB SYSTEM MESSAGE HANDLERS
|
||
------------------------------------------------------------------------------------------
|
||
*/
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : eNetBuildMessageSwapLittleBigEndianMap
|
||
Builds a map of functions processing little/big endian swap for sys msg
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : None
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : A NetLib_tdeErrorStatus
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : October 23,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus eNetBuildMessageSwapLittleBigEndianMap(void)
|
||
{
|
||
unsigned short uwCount;
|
||
/* Build message map :*/
|
||
gs_pfn_eSysMsgSwapMap=(tdfn_eNetSysMsgSwapLittleBigEndian *)pMalloc(sizeof(tdfn_eNetSysMsgSwapLittleBigEndian)*E_Net_mt_LastSysMsg);
|
||
|
||
if(!gs_pfn_eSysMsgSwapMap) return NetLib_E_es_NotEnoughMemory;
|
||
|
||
for(uwCount = 0;uwCount <E_Net_mt_LastSysMsg;uwCount++)
|
||
{
|
||
M_vNetAddMessageMapEntry(gs_pfn_eSysMsgSwapMap,uwCount,((tdfn_eNetSysMsgSwapLittleBigEndian)C_pNull));
|
||
}
|
||
|
||
M_vNetAddMessageMapEntry(gs_pfn_eSysMsgSwapMap,E_Net_mt_SysRequestActiveSessionsReply,eSwapLittleBigEndianSysMsgRequestSessionReply);
|
||
M_vNetAddMessageMapEntry(gs_pfn_eSysMsgSwapMap,E_Net_mt_SysConnectAgreement,eSwapLittleBigEndianSysMsgConnectAgreement);
|
||
M_vNetAddMessageMapEntry(gs_pfn_eSysMsgSwapMap,E_Net_mt_SysConnectDeny,eSwapLittleBigEndianSysMsgConnectDeny);
|
||
M_vNetAddMessageMapEntry(gs_pfn_eSysMsgSwapMap,E_Net_mt_SysPlayerDescriptorChanged,eSwapLittleBigEndianSysMsgPlayerDescriptorChanged);
|
||
M_vNetAddMessageMapEntry(gs_pfn_eSysMsgSwapMap,E_Net_mt_SysTimeDeltaRequest,eSwapLittleBigEndianSysMsgTimeDeltaRequest);
|
||
M_vNetAddMessageMapEntry(gs_pfn_eSysMsgSwapMap,E_Net_mt_SysTimeDeltaReply,eSwapLittleBigEndianSysMsgTimeDeltaRequest);/*same structure used*/
|
||
M_vNetAddMessageMapEntry(gs_pfn_eSysMsgSwapMap,E_Net_mt_SysDisconnectRemotePlayer,eSwapLittleBigEndianSysMsgDisconnectRemotePlayer);
|
||
M_vNetAddMessageMapEntry(gs_pfn_eSysMsgSwapMap,E_Net_mt_ReadReceipt,eSwapLittleBigEndianSysMsgReadReceipt);
|
||
M_vNetAddMessageMapEntry(gs_pfn_eSysMsgSwapMap,E_Net_mt_MaxNbrOfPlayers,eSwapLittleBigEndianSysMsgMaxNbrOfPlayers);
|
||
M_vNetAddMessageMapEntry(gs_pfn_eSysMsgSwapMap,E_Net_mt_SysSynchro,eSwapLittleBigEndianSysMsgSynchro);
|
||
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : Builds the netlib sys message map
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : None
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : A NetLib_tdeErrorStatus
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : September 16,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus eNetBuildMessageMap(void)
|
||
{
|
||
unsigned short uwCount;
|
||
/* Build message map :*/
|
||
gs_pfn_eSysMsgMap = (tdfn_eNetSysMsgHandle *)pMalloc(sizeof(tdfn_eNetSysMsgHandle)*E_Net_mt_LastSysMsg);
|
||
if(!gs_pfn_eSysMsgMap) return NetLib_E_es_NotEnoughMemory;
|
||
|
||
for(uwCount = 0;uwCount <E_Net_mt_LastSysMsg;uwCount++)
|
||
{
|
||
M_vNetAddMessageMapEntry(gs_pfn_eSysMsgMap,uwCount,((tdfn_eNetSysMsgHandle)C_pNull));
|
||
}
|
||
|
||
M_vNetAddMessageMapEntry(gs_pfn_eSysMsgMap,E_Net_mt_SysUnknownSender,eHandleNetSysMsgUnknownSender);
|
||
M_vNetAddMessageMapEntry(gs_pfn_eSysMsgMap,E_Net_mt_SysUnknownRecipient,eHandleNetSysMsgUnknownRecipient);
|
||
M_vNetAddMessageMapEntry(gs_pfn_eSysMsgMap,E_Net_mt_SysFullBuffer,eHandleNetSysMsgFullBuffer);
|
||
M_vNetAddMessageMapEntry(gs_pfn_eSysMsgMap,E_Net_mt_SysRequestActiveSessions,eHandleNetSysMsgRequestSession);
|
||
M_vNetAddMessageMapEntry(gs_pfn_eSysMsgMap,E_Net_mt_SysRequestActiveSessionsReply,eHandleNetSysMsgRequestSessionReply);
|
||
M_vNetAddMessageMapEntry(gs_pfn_eSysMsgMap,E_Net_mt_SysConnectRequest,eHandleNetSysMsgConnectRequest);
|
||
M_vNetAddMessageMapEntry(gs_pfn_eSysMsgMap,E_Net_mt_SysConnectCancel,eHandleNetSysMsgConnectCancel);
|
||
M_vNetAddMessageMapEntry(gs_pfn_eSysMsgMap,E_Net_mt_SysConnectAcknowledgement,eHandleNetSysMsgConnectAcknowledgement);
|
||
M_vNetAddMessageMapEntry(gs_pfn_eSysMsgMap,E_Net_mt_SysConnectAgreement,eHandleNetSysMsgConnectAgreement);
|
||
M_vNetAddMessageMapEntry(gs_pfn_eSysMsgMap,E_Net_mt_SysConnectListened,eHandleNetSysMsgConnectListened);
|
||
M_vNetAddMessageMapEntry(gs_pfn_eSysMsgMap,E_Net_mt_SysConnectDeny,eHandleNetSysMsgConnectDeny);
|
||
M_vNetAddMessageMapEntry(gs_pfn_eSysMsgMap,E_Net_mt_SysWaitFollow,eHandleNetSysMsgWaitFollow);
|
||
M_vNetAddMessageMapEntry(gs_pfn_eSysMsgMap,E_Net_mt_SysWaitBusy,eHandleNetSysMsgWaitBusy);
|
||
M_vNetAddMessageMapEntry(gs_pfn_eSysMsgMap,E_Net_mt_SysDisconnection,eHandleNetSysMsgDisconnection);
|
||
M_vNetAddMessageMapEntry(gs_pfn_eSysMsgMap,E_Net_mt_SysPlayerDescriptorChanged,eHandleNetSysMsgPlayerDescriptorChanged);
|
||
M_vNetAddMessageMapEntry(gs_pfn_eSysMsgMap,E_Net_mt_SysSessionDescriptorChanged,eHandleNetSysMsgSessionDescriptorChanged);
|
||
M_vNetAddMessageMapEntry(gs_pfn_eSysMsgMap,E_Net_mt_SysTimeDeltaRequest,eHandleNetSysMsgTimeDeltaRequest);
|
||
M_vNetAddMessageMapEntry(gs_pfn_eSysMsgMap,E_Net_mt_SysTimeDeltaReply,eHandleNetSysMsgTimeDeltaReply);
|
||
M_vNetAddMessageMapEntry(gs_pfn_eSysMsgMap,E_Net_mt_SysDisconnectRemotePlayer,eHandleNetSysMsgDisconnectRemotePlayer);
|
||
M_vNetAddMessageMapEntry(gs_pfn_eSysMsgMap,E_Net_mt_ReadReceipt,eHandleNetSysMsgReadReceipt);
|
||
M_vNetAddMessageMapEntry(gs_pfn_eSysMsgMap,E_Net_mt_MaxNbrOfPlayers,eHandleNetSysMsgMaxNbrOfPlayers);
|
||
M_vNetAddMessageMapEntry(gs_pfn_eSysMsgMap,E_Net_mt_TCPAddress,eHandleNetSysMsgTCPAddress);
|
||
M_vNetAddMessageMapEntry(gs_pfn_eSysMsgMap,E_Net_mt_TCPIsMe,eHandleNetSysMsgTCPIsMe);
|
||
M_vNetAddMessageMapEntry(gs_pfn_eSysMsgMap,E_Net_mt_TCPSupRoute,eHandleNetSysMsgTCPSupRoute);
|
||
M_vNetAddMessageMapEntry(gs_pfn_eSysMsgMap,E_Net_mt_SysSynchro,eHandleNetSysMsgSynchro);
|
||
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : Clears the netlib sys message map
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : None
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : A NetLib_tdeErrorStatus
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : October 23,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus eNetClearMessageSwapLittleBigEndianMap(void)
|
||
{
|
||
if (gs_pfn_eSysMsgSwapMap) vFree((tdpPointer)gs_pfn_eSysMsgSwapMap);
|
||
gs_pfn_eSysMsgMap = (tdfn_eNetSysMsgSwapLittleBigEndian*)C_pNull;
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : Clears the netlib sys message map
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : None
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : A NetLib_tdeErrorStatus
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : October 14,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus eNetClearMessageMap(void)
|
||
{
|
||
if (gs_pfn_eSysMsgMap) vFree((tdpPointer)gs_pfn_eSysMsgMap);
|
||
gs_pfn_eSysMsgMap = (tdfn_eNetSysMsgHandle *)C_pNull;
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : eHandleNetSysMsgUnknownSender
|
||
Handle of the system message : Unknown sender
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : a tdstNetIOSystemCell that contains the information about the message
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_NoError if no error occured
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : April 2,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eHandleNetSysMsgUnknownSender(tdstNetMessage *pstMes,tdeNetProtocol eProt,tduwNetChannel uwChannel)
|
||
{
|
||
return eLevel1HandleSysMsgUnknownSender(pstMes);
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : eHandleNetSysMsgUnknownRecipient
|
||
Handle of the system message : Unknown Recipient
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : a tdstNetIOSystemCell that contains the information about the message
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_NoError if no error occured
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : April 2,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eHandleNetSysMsgUnknownRecipient(tdstNetMessage *pstMes,tdeNetProtocol eProt,tduwNetChannel uwChannel)
|
||
{
|
||
return eLevel1HandleSysMsgUnknownRecipient(pstMes);
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : eHandleNetSysMsgFullBuffer
|
||
Handle of the system message : Full buffer
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : a tdstNetIOSystemCell that contains the information about the message
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_NoError if no error occured
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : April 2,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eHandleNetSysMsgFullBuffer(tdstNetMessage *pstMes,tdeNetProtocol eProt,tduwNetChannel uwChannel)
|
||
{
|
||
eLevel1HandleSysMsgFullBuffer(pstMes,eProt,uwChannel);
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : eSwapLittleBigEndianSysMsgPlayerDescriptorChanged
|
||
Swaps the system message : E_Net_mt_SysPlayerDescriptorChanged
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : a tdstNetIOSystemCell that contains the information about the message
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_NoError if no error occured
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : October 23,96
|
||
Author : Albert Pais
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Message body : -> ulPlayerId -> Swap
|
||
-> ucDescriptionLength -> nothing
|
||
-> pDescription -> Game's problem
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eSwapLittleBigEndianSysMsgPlayerDescriptorChanged(tdstNetMessage *pstMes,tdeNetProtocol eProt,tduwNetChannel uwChannel)
|
||
{
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : eHandleNetSysMsgPlayerDescriptorChanged
|
||
Handle of the system message : E_Net_mt_SysPlayerDescriptorChanged
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : a tdstNetIOSystemCell that contains the information about the message
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_NoError if no error occured
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : April 2,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eHandleNetSysMsgPlayerDescriptorChanged(tdstNetMessage *pstMes,tdeNetProtocol eProt,tduwNetChannel uwChannel)
|
||
{
|
||
NetLib_tdstPlayerInfo *p_stThePlayer;
|
||
tdpPointer pOriginData;
|
||
NetLib_tdeErrorStatus eErrorReturned;
|
||
|
||
if(pstMes->uxSessionId != gs_stCurrentSession.uxSessionId)
|
||
{
|
||
vFree(pstMes);
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/* If the local player is the recipient and the sender exists in the current session*/
|
||
if ((uwNetGetPlayerIndex(pstMes->uxSenderId)!=NetLib_C_uwInvalidPosition)
|
||
&& (pstMes->uxRecipientId == NetLib_uxGetOwnPlayerId()))
|
||
{
|
||
if (pstMes->m_uxReadReceiptId!=NetLib_C_ucNoReadReceipt)
|
||
/* if read-receipt required :*/
|
||
eNetSendReadReceiptMessage(pstMes);
|
||
|
||
p_stThePlayer = pstNetGetPlayerSlot(*((NetLib_tduxPlayerId*)(pstMes+1)));
|
||
if(!p_stThePlayer)
|
||
{
|
||
vFree(pstMes);
|
||
return NetLib_E_es_UnknownPlayerId;
|
||
}
|
||
|
||
if(p_stThePlayer->pPlayerDescriptionData)
|
||
{
|
||
vFree(p_stThePlayer->pPlayerDescriptionData);
|
||
p_stThePlayer->uxPlayerDescriptionLength = 0;
|
||
}
|
||
/* Initialize the new data :*/
|
||
pOriginData = (tdpPointer )(pstMes + 1);
|
||
pOriginData = (tdpPointer)(((NetLib_tduxPlayerId*)pOriginData)+1);
|
||
p_stThePlayer->uxPlayerDescriptionLength = *((NetLib_tduxDescriptionLength*)pOriginData);
|
||
pOriginData = (tdpPointer)((NetLib_tduxDescriptionLength*)pOriginData + 1);
|
||
if(p_stThePlayer->uxPlayerDescriptionLength)
|
||
{
|
||
p_stThePlayer->pPlayerDescriptionData = (tdpPointer)pMalloc(p_stThePlayer->uxPlayerDescriptionLength);
|
||
if(p_stThePlayer->pPlayerDescriptionData /*!=(tdpPointer)C_pNull*/)
|
||
{
|
||
g_pfn_vNetMemcpy(p_stThePlayer->pPlayerDescriptionData,pOriginData,p_stThePlayer->uxPlayerDescriptionLength);
|
||
vFree(pstMes);
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
vFree(pstMes);
|
||
return NetLib_E_es_NotEnoughMemory;
|
||
}
|
||
p_stThePlayer->pPlayerDescriptionData = C_pNull;
|
||
vFree(pstMes);
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
/*else*/
|
||
eErrorReturned = eLevel1RouteSysMsg(pstMes,eProt,uwChannel);
|
||
if(eErrorReturned != NetLib_E_es_NoError) vFree(pstMes);
|
||
return eErrorReturned;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : eHandleNetSysMsgSessionDescriptorChanged
|
||
Handle of the system message : E_Net_mt_SysSessionDescriptorChanged
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : a tdstNetIOSystemCell that contains the information about the message
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_NoError if no error occured
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : May 30,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eHandleNetSysMsgSessionDescriptorChanged(tdstNetMessage *pstMes,tdeNetProtocol eProt,tduwNetChannel uwChannel)
|
||
{
|
||
tdpPointer pOriginData;
|
||
NetLib_tdeErrorStatus eErrorReturned;
|
||
|
||
if(pstMes->uxSessionId != gs_stCurrentSession.uxSessionId)
|
||
{
|
||
vFree(pstMes);
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
if(pstMes->uxRecipientId == NetLib_uxGetOwnPlayerId())
|
||
{
|
||
if(pstMes->m_uxReadReceiptId!=NetLib_C_ucNoReadReceipt)
|
||
/* if read-receipt required :*/
|
||
eNetSendReadReceiptMessage(pstMes);
|
||
|
||
if(gs_stCurrentSession.pSessionDescriptionData /*!=(tdpPointer)C_pNull*/)
|
||
{
|
||
vFree(gs_stCurrentSession.pSessionDescriptionData);
|
||
/* Not necessary because reallocated just after :*/
|
||
/* p_stThePlayer->pPlayerDescriptionData = (tdpPointer)C_pNull;*/
|
||
gs_stCurrentSession.uxSessionDescriptionLength = 0;
|
||
}
|
||
/* Initialize the new data :*/
|
||
pOriginData = (tdpPointer )(pstMes + 1);
|
||
gs_stCurrentSession.uxSessionDescriptionLength = *((NetLib_tduxDescriptionLength*)pOriginData);
|
||
pOriginData = (tdpPointer)((NetLib_tduxDescriptionLength*)pOriginData + 1);
|
||
if(gs_stCurrentSession.uxSessionDescriptionLength)
|
||
{
|
||
gs_stCurrentSession.pSessionDescriptionData = (tdpPointer)pMalloc(gs_stCurrentSession.uxSessionDescriptionLength);
|
||
if(gs_stCurrentSession.pSessionDescriptionData /*!=(tdpPointer)C_pNull*/)
|
||
{
|
||
g_pfn_vNetMemcpy(gs_stCurrentSession.pSessionDescriptionData,pOriginData,
|
||
gs_stCurrentSession.uxSessionDescriptionLength );
|
||
|
||
vFree(pstMes);
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
else
|
||
{
|
||
vFree(pstMes);
|
||
return NetLib_E_es_NotEnoughMemory;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
gs_stCurrentSession.pSessionDescriptionData = C_pNull;
|
||
vFree(pstMes);
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
eErrorReturned = eLevel1RouteSysMsg(pstMes,eProt,uwChannel);
|
||
if(eErrorReturned != NetLib_E_es_NoError) vFree(pstMes);
|
||
return eErrorReturned;
|
||
}
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : pstNetBuildRequestSessionReplyMsg
|
||
Builds a message with the informations of the session
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : a tdstNetIOSystemCell that contains the information about the message
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : A pointer to the msg or NULL
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : September 20,96
|
||
Author : Albert Pais
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
It builds a message E_Net_mt_SysRequestActiveSessionsReply
|
||
The body of the message is (in this order) :
|
||
-> The id of the session
|
||
-> the max number players of the session
|
||
-> the effective number of players in the session
|
||
-> Player 1 's id
|
||
-> Player 2 's id
|
||
...
|
||
-> Player n 's id (where n equals the number of effective player)
|
||
-> the length of the session description in bytes
|
||
-> the session description data (number of bytes given by the previous slot)
|
||
-> the length of the player 1 description in bytes
|
||
-> the player 1 description data (number of bytes given by the previous slot)
|
||
-> the player 1 big/little endian flag
|
||
...
|
||
-> the length of the player n description in bytes
|
||
-> the player n description data
|
||
-> the player n big/little endian flag
|
||
-> a bytes for route building for the player 1
|
||
...
|
||
-> the length of the player n description in bytes
|
||
(where n equals the number of effective player)
|
||
-> the player n description data (number of bytes given by the previous slot)
|
||
(where n equals the number of effective player)
|
||
-> a bytes for route building for the player n
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
tdstNetMessage *pstNetBuildRequestSessionReplyMsg(tdeNetProtocol eProt,tduwNetChannel uwChannel,unsigned long ucMaxPlayerInfo)
|
||
{
|
||
tdstNetMessage *p_stMsgReturned;
|
||
unsigned short uwMessageLength;
|
||
unsigned short c_uwCurrentPlayerIndex;
|
||
unsigned short c_uwCurrentSlot;
|
||
tdpPointer p_OriginData;
|
||
NetLib_tduxPlayerId *d_ulPlayerIdArray;
|
||
NetLib_tduxDescriptionLength ucDescLength, ucCopyLength;
|
||
|
||
/* Determine the size of the message :*/
|
||
uwMessageLength =
|
||
sizeof(NetLib_tduxSessionId) /* for the id of the session*/
|
||
+sizeof(unsigned short) /* for the maximum numbers of players */
|
||
+sizeof(unsigned short) /* for the number of players*/
|
||
+sizeof(NetLib_tduxSessionId) * gs_stCurrentSession.uwNumberOfPlayers /* For each Id of the players of the session */
|
||
+sizeof(NetLib_tduxDescriptionLength)/* For the length of the session description*/
|
||
+gs_stCurrentSession.uxSessionDescriptionLength/* for the session description*/
|
||
+sizeof(NetLib_tduxDescriptionLength) * gs_stCurrentSession.uwNumberOfPlayers /* For the length of each player description */
|
||
+sizeof(NetLib_tducBigLittleEndian)*gs_stCurrentSession.uwNumberOfPlayers /* for the big/little endian flag*/
|
||
+sizeof(NetLib_tduxDescriptionLength); /* for the player description truncation size*/
|
||
|
||
for(c_uwCurrentPlayerIndex=0;c_uwCurrentPlayerIndex<gs_stCurrentSession.uwMaxNumberOfPlayers;c_uwCurrentPlayerIndex ++)
|
||
{/* For each player description :*/
|
||
if(M_ulNetPlayerIdSlot(&gs_stCurrentSession.d_stPlayerInfo[c_uwCurrentPlayerIndex]) != C_uxNetInvalidId)
|
||
{
|
||
ucDescLength=gs_stCurrentSession.d_stPlayerInfo[c_uwCurrentPlayerIndex].uxPlayerDescriptionLength;
|
||
if (ucDescLength<=ucMaxPlayerInfo)
|
||
uwMessageLength += ucDescLength;
|
||
else uwMessageLength += ucMaxPlayerInfo;
|
||
}
|
||
}
|
||
|
||
p_stMsgReturned = (tdstNetMessage*)pMalloc(sizeof(tdstNetMessage) + uwMessageLength);
|
||
if(!p_stMsgReturned) return (tdstNetMessage*)C_pNull;
|
||
|
||
/* Message length :*/
|
||
p_stMsgReturned->uwMessageSizeInBytes = uwMessageLength;
|
||
/* type :*/
|
||
p_stMsgReturned->eMessageType = E_Net_mt_SysRequestActiveSessionsReply;
|
||
p_stMsgReturned->uxPriority = NetLib_C_uxNoPriority;
|
||
p_stMsgReturned->uxReplaceType = 0;
|
||
p_stMsgReturned->uxReplace = 0;
|
||
p_stMsgReturned->m_uxReadReceiptId = NetLib_C_ucNoReadReceipt;
|
||
|
||
/* And now : the body :*/
|
||
/* The id of the session :*/
|
||
p_OriginData = (tdpPointer)(p_stMsgReturned + 1);
|
||
*((NetLib_tduxSessionId*)p_OriginData) = gs_stCurrentSession.uxSessionId;
|
||
/* The maximum number of players*/
|
||
p_OriginData = (tdpPointer)((NetLib_tduxSessionId*)p_OriginData + 1);
|
||
*((unsigned short *)p_OriginData) = gs_stCurrentSession.uwMaxNumberOfPlayers;
|
||
/* The number of players*/
|
||
p_OriginData = (tdpPointer)((unsigned short*)p_OriginData + 1);
|
||
*((unsigned short *)p_OriginData) = gs_stCurrentSession.uwNumberOfPlayers;
|
||
/* For each player : the ID :*/
|
||
p_OriginData = (tdpPointer)((unsigned short*)p_OriginData + 1);
|
||
/* d_ulPlayerIdArray is set to the correct place where ids are to be put :*/
|
||
d_ulPlayerIdArray = (NetLib_tduxPlayerId *)p_OriginData;
|
||
p_OriginData = (tdpPointer)((NetLib_tduxPlayerId*)p_OriginData +
|
||
gs_stCurrentSession.uwNumberOfPlayers);
|
||
|
||
/* The length of the Session description : */
|
||
*((NetLib_tduxDescriptionLength *)p_OriginData) = gs_stCurrentSession.uxSessionDescriptionLength;
|
||
/* The session description :*/
|
||
p_OriginData = (tdpPointer)((NetLib_tduxDescriptionLength*)p_OriginData + 1);
|
||
if(gs_stCurrentSession.uxSessionDescriptionLength)
|
||
{
|
||
g_pfn_vNetMemcpy(p_OriginData,gs_stCurrentSession.pSessionDescriptionData,
|
||
gs_stCurrentSession.uxSessionDescriptionLength);
|
||
}
|
||
p_OriginData = (tdpPointer)p_OriginData + gs_stCurrentSession.uxSessionDescriptionLength;
|
||
|
||
/* the player description truncation size (which might have been changed on the remote side */
|
||
|
||
*((NetLib_tduxDescriptionLength*)p_OriginData)=ucMaxPlayerInfo;
|
||
p_OriginData = p_OriginData + sizeof(NetLib_tduxDescriptionLength);
|
||
|
||
/* For each player : */
|
||
|
||
c_uwCurrentSlot = 0;
|
||
for (c_uwCurrentPlayerIndex=0;c_uwCurrentPlayerIndex<gs_stCurrentSession.uwMaxNumberOfPlayers;c_uwCurrentPlayerIndex++)
|
||
{
|
||
if (M_ulNetPlayerIdSlot(&gs_stCurrentSession.d_stPlayerInfo[c_uwCurrentPlayerIndex]) !=C_uxNetInvalidId)
|
||
{
|
||
d_ulPlayerIdArray[c_uwCurrentSlot++]=M_ulNetPlayerIdSlot(&gs_stCurrentSession.d_stPlayerInfo[c_uwCurrentPlayerIndex]);
|
||
ucDescLength=gs_stCurrentSession.d_stPlayerInfo[c_uwCurrentPlayerIndex].uxPlayerDescriptionLength;
|
||
/* The length of the description of the player :*/
|
||
*((NetLib_tduxDescriptionLength*)p_OriginData)=ucDescLength;
|
||
/* the description of the player :*/
|
||
p_OriginData=(tdpPointer)((NetLib_tduxDescriptionLength*)p_OriginData + 1);
|
||
if(ucDescLength)
|
||
{
|
||
ucCopyLength=ucDescLength>ucMaxPlayerInfo?ucMaxPlayerInfo:ucDescLength;
|
||
g_pfn_vNetMemcpy(p_OriginData,
|
||
gs_stCurrentSession.d_stPlayerInfo[c_uwCurrentPlayerIndex].pPlayerDescriptionData,
|
||
ucCopyLength);
|
||
p_OriginData=(tdpPointer)p_OriginData+ucCopyLength;
|
||
}
|
||
*((NetLib_tducBigLittleEndian*)p_OriginData)=gs_stCurrentSession.d_stPlayerInfo[c_uwCurrentPlayerIndex].m_ucLittleBigEndian;
|
||
p_OriginData=(tdpPointer)((NetLib_tducBigLittleEndian*)p_OriginData + 1);
|
||
}
|
||
}
|
||
|
||
return p_stMsgReturned;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : eHandleNetSysMsgRequestSession
|
||
Handle of the system message : Request session(E_Net_mt_SysRequestActiveSessions)
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : a tdstNetIOSystemCell that contains the information about the message
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_NoError if no error occured
|
||
NetLib_E_es_NotEnoughMemory if there was not enough memory
|
||
NetLib_E_es_ShouldNotReach if the message should not reach this point
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : April 2,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eHandleNetSysMsgRequestSession(tdstNetMessage *pstMes,tdeNetProtocol eProt,tduwNetChannel uwChannel)
|
||
{
|
||
NetLib_tdeErrorStatus eErrorReturned;
|
||
NetLib_tduxPlayerId ulExSenderNewRecipientId;
|
||
unsigned long ucMaxPlayerInfo;
|
||
|
||
/* If the current number of players is equal to the max number of player, do not answer :*/
|
||
if(gs_stCurrentSession.uwMaxNumberOfPlayers==gs_stCurrentSession.uwNumberOfPlayers)
|
||
{
|
||
vFree(pstMes);
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/* Builds the message :*/
|
||
/* Erase the previous message :*/
|
||
ulExSenderNewRecipientId = pstMes->uxSenderId;
|
||
ucMaxPlayerInfo=*((NetLib_tduxDescriptionLength *)(pstMes+1));
|
||
vFree(pstMes);
|
||
|
||
/* Build the new message :*/
|
||
pstMes = pstNetBuildRequestSessionReplyMsg(eProt,uwChannel,ucMaxPlayerInfo);
|
||
if(!pstMes) return NetLib_E_es_NotEnoughMemory;
|
||
|
||
/* Recipient id :*/
|
||
pstMes->uxRecipientId = ulExSenderNewRecipientId;
|
||
pstMes->uxSenderId = NetLib_uxGetOwnPlayerId();
|
||
|
||
eErrorReturned = eLevel1SendMessage(pstMes,eProt,uwChannel);
|
||
if(eErrorReturned != NetLib_E_es_NoError) vFree(pstMes);
|
||
|
||
return eErrorReturned;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : eNetRetrieveInfoSession
|
||
Retrieves and creates a session info from a msg
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : a msg
|
||
a pointer to a pointer to a session info structure
|
||
a pointer to an array of unsigned char
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_NoError if no error occured
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : September,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus eNetRetrieveInfoSession(tdstNetMessage *p_stMsgReturned,NetLib_tdstSessionInfo **p_stSessionInfoReceived,unsigned char **pp_ucWaitForReply)
|
||
{
|
||
tdpPointer p_OriginData;
|
||
unsigned short c_uwCount;
|
||
NetLib_tduxPlayerId *p_dListPlayerId;
|
||
NetLib_tduxDescriptionLength ucMaxPlayerInfo, ucActualSize, ucCopySize;
|
||
|
||
*p_stSessionInfoReceived=(NetLib_tdstSessionInfo *)pMalloc(sizeof(NetLib_tdstSessionInfo));
|
||
if(!(*p_stSessionInfoReceived)) return NetLib_E_es_NotEnoughMemory;
|
||
|
||
p_OriginData=(tdpPointer)(p_stMsgReturned + 1);
|
||
|
||
/* The session id :*/
|
||
(*p_stSessionInfoReceived)->uxSessionId = *((NetLib_tduxSessionId*)p_OriginData);
|
||
p_OriginData = (tdpPointer)((NetLib_tduxSessionId*)p_OriginData + 1);
|
||
|
||
/* Retrieves the maximum number of players :*/
|
||
(*p_stSessionInfoReceived)->uwMaxNumberOfPlayers = *((unsigned short*)p_OriginData);
|
||
p_OriginData = (tdpPointer)((unsigned short*)p_OriginData + 1);
|
||
|
||
/* Retrieves the number of players :*/
|
||
(*p_stSessionInfoReceived)->uwNumberOfPlayers = *((unsigned short *)p_OriginData);
|
||
p_OriginData = (tdpPointer)((unsigned short*)p_OriginData + 1);
|
||
|
||
/* Retrieves the list of id's players :*/
|
||
/* Cast part of the message to a list of players Id :*/
|
||
(*p_stSessionInfoReceived)->d_stPlayerInfo = (NetLib_tdstPlayerInfo *)
|
||
pMalloc(sizeof(NetLib_tdstPlayerInfo)*(*p_stSessionInfoReceived)->uwMaxNumberOfPlayers);
|
||
if(!(*p_stSessionInfoReceived)->d_stPlayerInfo)
|
||
{
|
||
vFree((tdpPointer)(*p_stSessionInfoReceived));
|
||
*p_stSessionInfoReceived= (NetLib_tdstSessionInfo *)C_pNull;
|
||
return NetLib_E_es_NotEnoughMemory;
|
||
}
|
||
|
||
(*p_stSessionInfoReceived)->uwIndexOfLocalPlayer = NetLib_C_uwInvalidPosition;
|
||
|
||
p_dListPlayerId = (NetLib_tduxPlayerId *)p_OriginData;
|
||
p_OriginData = (tdpPointer)((NetLib_tduxPlayerId *)p_OriginData+(*p_stSessionInfoReceived)->uwNumberOfPlayers);
|
||
|
||
/* The length of the session description :*/
|
||
(*p_stSessionInfoReceived)->uxSessionDescriptionLength = *((NetLib_tduxDescriptionLength*)p_OriginData);
|
||
p_OriginData = (tdpPointer)((NetLib_tduxDescriptionLength*)p_OriginData+1);
|
||
|
||
/* the session description*/
|
||
if((*p_stSessionInfoReceived)->uxSessionDescriptionLength)
|
||
{
|
||
(*p_stSessionInfoReceived)->pSessionDescriptionData = pMalloc((*p_stSessionInfoReceived)->uxSessionDescriptionLength);
|
||
if(!(*p_stSessionInfoReceived)->pSessionDescriptionData)
|
||
{
|
||
vFree((tdpPointer)(*p_stSessionInfoReceived)->d_stPlayerInfo);
|
||
vFree((tdpPointer)*p_stSessionInfoReceived);
|
||
*p_stSessionInfoReceived = (NetLib_tdstSessionInfo*)C_pNull;
|
||
return NetLib_E_es_NotEnoughMemory;
|
||
}
|
||
g_pfn_vNetMemcpy((*p_stSessionInfoReceived)->pSessionDescriptionData,
|
||
p_OriginData,
|
||
(*p_stSessionInfoReceived)->uxSessionDescriptionLength);
|
||
}
|
||
else (*p_stSessionInfoReceived)->pSessionDescriptionData = C_pNull;
|
||
p_OriginData = p_OriginData + (*p_stSessionInfoReceived)->uxSessionDescriptionLength;
|
||
|
||
/* player description truncation size */
|
||
|
||
(*p_stSessionInfoReceived)->uxPlayerDescTruncation=ucMaxPlayerInfo=*((NetLib_tduxDescriptionLength*)p_OriginData);
|
||
p_OriginData = p_OriginData + sizeof(NetLib_tduxDescriptionLength);
|
||
|
||
/* Player initialisation :*/
|
||
for(c_uwCount = 0;c_uwCount <(*p_stSessionInfoReceived)->uwNumberOfPlayers;c_uwCount++)
|
||
{
|
||
M_ulNetPlayerIdSlot(&((*p_stSessionInfoReceived)->d_stPlayerInfo[c_uwCount]))=p_dListPlayerId[c_uwCount];
|
||
ucActualSize=(*p_stSessionInfoReceived)->d_stPlayerInfo[c_uwCount].uxPlayerDescriptionLength=*((NetLib_tduxDescriptionLength*)p_OriginData);
|
||
p_OriginData=(tdpPointer)((NetLib_tduxDescriptionLength*)p_OriginData+1);
|
||
(*p_stSessionInfoReceived)->d_stPlayerInfo[c_uwCount].Options=NULL;
|
||
ucCopySize= ucActualSize > ucMaxPlayerInfo ? ucMaxPlayerInfo : ucActualSize;
|
||
if(ucCopySize)
|
||
{
|
||
(*p_stSessionInfoReceived)->d_stPlayerInfo[c_uwCount].pPlayerDescriptionData=
|
||
pMalloc(ucCopySize);
|
||
if((*p_stSessionInfoReceived)->d_stPlayerInfo[c_uwCount].pPlayerDescriptionData)
|
||
g_pfn_vNetMemcpy((*p_stSessionInfoReceived)->d_stPlayerInfo[c_uwCount].pPlayerDescriptionData,
|
||
p_OriginData,
|
||
ucCopySize);
|
||
else (*p_stSessionInfoReceived)->d_stPlayerInfo[c_uwCount].uxPlayerDescriptionLength=0;
|
||
}
|
||
else (*p_stSessionInfoReceived)->d_stPlayerInfo[c_uwCount].pPlayerDescriptionData=C_pNull;
|
||
p_OriginData = p_OriginData+ucCopySize;
|
||
(*p_stSessionInfoReceived)->d_stPlayerInfo[c_uwCount].m_ucLittleBigEndian=*((NetLib_tducBigLittleEndian*)p_OriginData);
|
||
p_OriginData = (tdpPointer)((NetLib_tducBigLittleEndian*)p_OriginData+1);
|
||
}
|
||
for (c_uwCount=(*p_stSessionInfoReceived)->uwNumberOfPlayers;c_uwCount<(*p_stSessionInfoReceived)->uwMaxNumberOfPlayers;c_uwCount++)
|
||
{
|
||
M_ulNetPlayerIdSlot(&((*p_stSessionInfoReceived)->d_stPlayerInfo[c_uwCount]))=C_uxNetInvalidId;
|
||
(*p_stSessionInfoReceived)->d_stPlayerInfo[c_uwCount].pPlayerDescriptionData=C_pNull;
|
||
(*p_stSessionInfoReceived)->d_stPlayerInfo[c_uwCount].uxPlayerDescriptionLength=0;
|
||
}
|
||
|
||
/*the waitforreply array :*/
|
||
*pp_ucWaitForReply = (unsigned char*)p_OriginData;
|
||
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : eNetHaveSessionsSamePlayers
|
||
Check if two sessions have the same players or not
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : NetLib_tdstSessionInfo *: one session
|
||
NetLib_tdstSessionInfo *: the other
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_NoError if no error occured
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : September,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus eNetHaveSessionsSamePlayers(NetLib_tdstSessionInfo *p_stSessionInfo1,NetLib_tdstSessionInfo *p_stSessionInfo2)
|
||
{
|
||
unsigned short c_uwCount;
|
||
unsigned short c_uwCount2;
|
||
NetLib_tdeErrorStatus eErrorReturned;
|
||
|
||
if(p_stSessionInfo1->uwNumberOfPlayers!=p_stSessionInfo2->uwNumberOfPlayers)
|
||
return NetLib_E_es_False;
|
||
|
||
/* Checking wether elements are equal or not*/
|
||
/* It is supposed that in each array, every id is different from all others*/
|
||
eErrorReturned = NetLib_E_es_True;
|
||
c_uwCount = 0;
|
||
while ((eErrorReturned == NetLib_E_es_True)
|
||
&&(c_uwCount < p_stSessionInfo1->uwNumberOfPlayers))
|
||
{
|
||
c_uwCount2 = 0;
|
||
while ((c_uwCount2 < p_stSessionInfo2->uwNumberOfPlayers)&&
|
||
(M_ulNetPlayerIdSlot(&(p_stSessionInfo1->d_stPlayerInfo[c_uwCount]))
|
||
!=M_ulNetPlayerIdSlot(&(p_stSessionInfo2->d_stPlayerInfo[c_uwCount2]))))
|
||
c_uwCount2++;
|
||
|
||
if(c_uwCount2 >=p_stSessionInfo2->uwNumberOfPlayers)
|
||
eErrorReturned = NetLib_E_es_False;
|
||
|
||
c_uwCount++;
|
||
}
|
||
return eErrorReturned;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : eNetCopySessionInfo
|
||
Copy information from one NetLib_tdstSessionInfo to another
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : NetLib_tdstSessionInfo *p_stDest : the destination
|
||
NetLib_tdstSessionInfo *p_stSrc : the source
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_NoError if no error occured
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : September,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus eNetCopySessionInfo(NetLib_tdstSessionInfo *p_stDest,NetLib_tdstSessionInfo *p_stSrc)
|
||
{
|
||
p_stDest->uxSessionId = p_stSrc->uxSessionId;
|
||
p_stDest->uwMaxNumberOfPlayers = p_stSrc->uwMaxNumberOfPlayers;
|
||
p_stDest->uwNumberOfPlayers = p_stSrc->uwNumberOfPlayers;
|
||
p_stDest->uwIndexOfLocalPlayer = p_stSrc->uwIndexOfLocalPlayer;
|
||
p_stDest->uxSessionDescriptionLength = p_stSrc->uxSessionDescriptionLength;
|
||
p_stDest->pSessionDescriptionData = p_stSrc->pSessionDescriptionData;
|
||
p_stDest->d_stPlayerInfo = p_stSrc->d_stPlayerInfo;
|
||
p_stDest->uxPlayerDescTruncation = p_stSrc->uxPlayerDescTruncation;
|
||
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : eSwapLittleBigEndianSysMsgRequestSessionReply
|
||
Swap the system message : Request session reply
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : a tdstNetIOSystemCell that contains the information about the message
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_NoError if no error occured
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : October 23,96
|
||
Author : Albert Pais
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Message body :
|
||
->ulSesssionId ->swap
|
||
->uwMaxNbrOfPlayers ->swap
|
||
->uwNbrOfPlayers ->swap
|
||
->ulPlayer1Id ->swap
|
||
->.
|
||
->.
|
||
->.
|
||
->ulPlayernId ->swap
|
||
->uxSessionDescriptionLength -> do nothing
|
||
->pSessionDescription -> game's problem
|
||
->ucPlayer1DescriptionLength -> do nothing
|
||
->pPlayer1DescriptionLength -> game's problem
|
||
->ucBigLittleEndianFlag -> do nothing
|
||
->.
|
||
->.
|
||
->.
|
||
->ucPlayernDescriptionLength -> do nothing
|
||
->pPlayernDescriptionLength -> game's problem
|
||
->ucBigLittleEndianFlag -> do nothing
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eSwapLittleBigEndianSysMsgRequestSessionReply(tdstNetMessage *pstMes,tdeNetProtocol eProt,tduwNetChannel uwChannel)
|
||
{
|
||
tdpPointer pData;
|
||
unsigned short uwNbrOfPlayers;
|
||
|
||
pData = (tdpPointer)(pstMes +1);
|
||
|
||
pData = (tdpPointer)((NetLib_tduxSessionId*)pData+1);
|
||
*((unsigned short*)pData) = /*max nbr of players*/
|
||
M_NET_uwSwapLittleBigEndian(*(unsigned short*)pData);
|
||
pData = (tdpPointer)((unsigned short*)pData+1);
|
||
uwNbrOfPlayers = *((unsigned short*)pData) = /*nbr of players*/
|
||
M_NET_uwSwapLittleBigEndian(*(unsigned short*)pData);
|
||
/* nothing more to do*/
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : eHandleNetSysMsgRequestSessionReply
|
||
Handle of the system message : Request session reply
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : a tdstNetIOSystemCell that contains the information about the message
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_NoError if no error occured
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : April 2&3,96
|
||
Author : Albert Pais
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Pre-supposed :
|
||
The global variables gs_dstSessions and gs_c_uwNumberOfSessionsDetected are correctly
|
||
initialised. That is to say enough memory is allocated for the array and the value
|
||
of the index is between 0 and the boundary of the array.
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Comment :
|
||
This functions update informations about sessions which answers to a RequestSession
|
||
message :
|
||
If it is a new session that answers, the functions create a new entry in the array
|
||
of the NetLib_tdstSessionInfo global object :gs_dstSessions and increase the value of
|
||
gs_c_uwNumberOfSessionsDetected that represents the number of sessions found
|
||
If this session already has an entry in the gs_dstSessions array, the functions
|
||
updates its informations about this game if necessary.
|
||
The function then call the necessary level 1 functions in order to have the
|
||
level 1 informations updated.
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eHandleNetSysMsgRequestSessionReply(tdstNetMessage *pstMes,tdeNetProtocol eProt,tduwNetChannel uwChannel)
|
||
{
|
||
NetLib_tdeErrorStatus eErrorReturned;
|
||
NetLib_tdstSessionInfo *p_stSessionInfoReceived;
|
||
NetLib_tdstSessionInfo *p_stSessionInfoPrevious;
|
||
unsigned short uwIndexOfSessionFound;
|
||
unsigned short c_uwCurrent;
|
||
unsigned short uwPrevNbrOfPlayers;
|
||
tdstNetTemp *p_stPreviousWait;
|
||
unsigned char *p_ucWaitFor;
|
||
|
||
if(gs_eListeningMode != E_Net_LisMod_ON)
|
||
{ /*We are not in a listening mode, so don't care of the message*/
|
||
/* but call the level 1 in order to update information */
|
||
eLevel1BuildRouteInfoOfSessionPlayer(pstMes,eProt,uwChannel);
|
||
vFree(pstMes);
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/*
|
||
FIRST : retrieve informations about the session detected :
|
||
*/
|
||
eErrorReturned=eNetRetrieveInfoSession(pstMes,&p_stSessionInfoReceived,&p_ucWaitFor);
|
||
if(eErrorReturned !=NetLib_E_es_NoError)
|
||
{
|
||
vFree(pstMes);
|
||
return eErrorReturned;
|
||
}
|
||
|
||
/* If a filter function is used, call it to check if the session is valid or not :*/
|
||
if(g_pfn_eSessionFilter /* !=((NetLib_tdeErrorStatus (*)(NetLib_tdstSessionInfo*)))C_pNull*/)
|
||
{
|
||
if(g_pfn_eSessionFilter(p_stSessionInfoReceived)!=NetLib_E_es_True)
|
||
{
|
||
/* The session has not been accepted, so discard it*/
|
||
vNetClearSessionInfo(p_stSessionInfoReceived);
|
||
vFree((tdpPointer)p_stSessionInfoReceived);
|
||
vFree(pstMes);
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
}
|
||
|
||
/* search if a session with the same Id exists : */
|
||
uwIndexOfSessionFound = 0;
|
||
while ((uwIndexOfSessionFound < gs_c_uwNumberOfSessionsDetected) &&
|
||
(gs_dstSessions[uwIndexOfSessionFound].uxSessionId!=p_stSessionInfoReceived->uxSessionId))
|
||
uwIndexOfSessionFound++;
|
||
|
||
|
||
if(uwIndexOfSessionFound < gs_c_uwNumberOfSessionsDetected)
|
||
/* //////////////////////////////////////////////////////////////////////////////// */
|
||
/* ////////// A session with the same Id has been found : ////////// */
|
||
/* //////////////////////////////////////////////////////////////////////////////// */
|
||
{
|
||
p_stSessionInfoPrevious = gs_dstSessions+uwIndexOfSessionFound;
|
||
eErrorReturned = eNetHaveSessionsSamePlayers(p_stSessionInfoPrevious,p_stSessionInfoReceived);
|
||
if(eErrorReturned == NetLib_E_es_True)
|
||
/* //////////////////////////////////////////////////////////////////////////////// */
|
||
/* ////////// The two lists are equals : ////////// */
|
||
/* //////////////////////////////////////////////////////////////////////////////// */
|
||
{
|
||
vNetClearSessionInfo(p_stSessionInfoReceived);
|
||
vFree((tdpPointer)p_stSessionInfoReceived);
|
||
p_stSessionInfoReceived = (NetLib_tdstSessionInfo*)C_pNull;
|
||
|
||
eErrorReturned = eLevel1BuildRouteInfo(pstMes,eProt,uwChannel);
|
||
if(eErrorReturned == NetLib_E_es_UnknownPlayerId) eErrorReturned = eLevel1UpdateRouteInfo(pstMes,eProt,uwChannel);
|
||
if(eErrorReturned == NetLib_E_es_UnknownSessionId) eErrorReturned = eLevel1AddNewSession(pstMes,eProt,uwChannel);
|
||
|
||
vFree(pstMes);
|
||
return eErrorReturned;
|
||
}
|
||
|
||
/* //////////////////////////////////////////////////////////////////////////////// */
|
||
/* ////////// The two lists are different ////////// */
|
||
/* //////////////////////////////////////////////////////////////////////////////// */
|
||
/* First : free the memory for player description :*/
|
||
|
||
p_stPreviousWait = (tdstNetTemp *)pMalloc(sizeof(tdstNetTemp)*p_stSessionInfoPrevious->uwNumberOfPlayers);
|
||
for (c_uwCurrent=0;c_uwCurrent<p_stSessionInfoPrevious->uwNumberOfPlayers;c_uwCurrent++)
|
||
{
|
||
if(p_stPreviousWait)
|
||
{
|
||
p_stPreviousWait[c_uwCurrent].ulPlayerId =M_ulNetPlayerIdSlot(&(p_stSessionInfoPrevious->d_stPlayerInfo[c_uwCurrent]));
|
||
}
|
||
}
|
||
|
||
uwPrevNbrOfPlayers = p_stSessionInfoPrevious->uwNumberOfPlayers;
|
||
|
||
vNetClearSessionInfo(p_stSessionInfoPrevious);
|
||
eNetCopySessionInfo(p_stSessionInfoPrevious,p_stSessionInfoReceived);
|
||
|
||
vFree((tdpPointer)p_stSessionInfoReceived);
|
||
p_stSessionInfoReceived = (NetLib_tdstSessionInfo *)C_pNull;
|
||
|
||
/* Here, data are updated for the level 2*/
|
||
/* So now : */
|
||
/* Update data in level 1 :*/
|
||
eErrorReturned = eLevel1UpdateRouteInfo(pstMes,eProt,uwChannel);
|
||
if(eErrorReturned == NetLib_E_es_UnknownSessionId)
|
||
/* Create the new session (Normaly should not happen)*/
|
||
eErrorReturned = eLevel1AddNewSession(pstMes,eProt,uwChannel);
|
||
|
||
vFree((tdpPointer)p_stPreviousWait);
|
||
vFree(pstMes);
|
||
return eErrorReturned;
|
||
}/* End of if if(c_uwCurrent < gs_c_uwNumberOfSessionsDetected)...*/
|
||
else
|
||
/* //////////////////////////////////////////////////////////////////////////////// */
|
||
/* ////////// A new session has been found : ////////// */
|
||
/* //////////////////////////////////////////////////////////////////////////////// */
|
||
{
|
||
/* Initialise the entry of the array gs_dstSessions at the */
|
||
/* gs_c_uwNumberOfSessionsDetected position with appropriate data */
|
||
/* It is supposed that these variables are correctely initialised :*/
|
||
/* Enough memory for gs_dstSessions and correct value for gs_c_uwNumberOfSessionsDetected */
|
||
|
||
if(gs_c_uwNumberOfSessionsDetected>=gs_uwNumberOfSessionsExpected)
|
||
{
|
||
vNetClearSessionInfo(p_stSessionInfoReceived);
|
||
vFree((tdpPointer)p_stSessionInfoReceived);
|
||
vFree(pstMes);
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
eNetCopySessionInfo(gs_dstSessions+gs_c_uwNumberOfSessionsDetected,p_stSessionInfoReceived);
|
||
vFree((tdpPointer)p_stSessionInfoReceived);
|
||
p_stSessionInfoReceived = (NetLib_tdstSessionInfo*)C_pNull;
|
||
|
||
/* the waiting flag */
|
||
gs_dpucWaitForReply[gs_c_uwNumberOfSessionsDetected]=1;
|
||
|
||
/* Inform level 1 of the new session*/
|
||
if((eErrorReturned = eLevel1AddNewSession(pstMes,eProt,uwChannel))==NetLib_E_es_SessionIdAlreadyAcknowledged)
|
||
{
|
||
if((eErrorReturned = eLevel1BuildRouteInfo(pstMes,eProt,uwChannel))== NetLib_E_es_UnknownPlayerId)
|
||
eErrorReturned = eLevel1UpdateRouteInfo(pstMes,eProt,uwChannel);
|
||
}
|
||
|
||
if(eErrorReturned == NetLib_E_es_NoError) gs_c_uwNumberOfSessionsDetected++;
|
||
else
|
||
{
|
||
/* Clear data :*/
|
||
vNetClearSessionInfo(gs_dstSessions+gs_c_uwNumberOfSessionsDetected);
|
||
gs_dpucWaitForReply[gs_c_uwNumberOfSessionsDetected] = 0;
|
||
}
|
||
|
||
vFree(pstMes);
|
||
return eErrorReturned;
|
||
}/* End of else if(c_uwCurrent < gs_c_uwNumberOfSessionsDetected)...: new session processed */
|
||
}/*End of function */
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_tdeErrorStatus eHandleNetSysMsgConnectRequest(tdstNetIOSystemCell*p_stIOSystCell)
|
||
Handle of the system message ConnectRequest
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : a tdstNetIOSystemCell that contains the information about the message
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_NoError if no error occured
|
||
NetLib_E_es_ShouldNotReach the message should not reach this function
|
||
NetLib_E_es_NotEnoughMemory : the function could not complete the process of the message
|
||
because of a lack of memory
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : April 4,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eHandleNetSysMsgConnectRequest(tdstNetMessage *pstMes,tdeNetProtocol eProt,tduwNetChannel uwChannel)
|
||
{
|
||
NetLib_tdeErrorStatus eErrorReturned;
|
||
tdpPointer p_OriginData;
|
||
NetLib_tduxPlayerId uxSenderId;
|
||
NetLib_tduxPlayerId uxRecipientId;
|
||
tdstNetMessage *p_stMessageReturned;
|
||
unsigned short c_uwCount;
|
||
long lParam;
|
||
unsigned char uxPlayerDescriptionLength;
|
||
|
||
uxSenderId = pstMes->uxSenderId;
|
||
uxRecipientId = pstMes->uxRecipientId;
|
||
if ((gs_p_stPreSessionPlayerInfo==(NetLib_tdstPlayerInfo*)C_pNull) ||
|
||
((gs_p_stPreSessionPlayerInfo /*!= (NetLib_tdstPlayerInfo*)C_pNull*/) &&
|
||
(M_ulNetPlayerIdSlot(gs_p_stPreSessionPlayerInfo) != uxSenderId) &&
|
||
(eNetCheckTimeOutOfPlayerConnected(0)==NetLib_E_es_TimeOutExpired)))
|
||
{
|
||
/* ------------------------------------------------------------
|
||
NO PREVIOUS CONNECTION :
|
||
------------------------------------------------------------ */
|
||
/* Empty the gs_p_stPreSessionPlayerInfo if necessary*/
|
||
/* this happens if too mutch time elapsed since the player*/
|
||
/* made its connection request*/
|
||
if(gs_p_stPreSessionPlayerInfo != (NetLib_tdstPlayerInfo*)C_pNull)
|
||
eNetCheckTimeOutOfPlayerConnected(1);
|
||
|
||
/* Check if the destinee is the local player */
|
||
if(uxRecipientId != NetLib_uxGetOwnPlayerId())
|
||
{
|
||
/* the recipient is not the local player*/
|
||
vFree(pstMes);
|
||
pstMes = (tdstNetMessage*)pMalloc(sizeof(tdstNetMessage));
|
||
if (pstMes)
|
||
{
|
||
/* Send a WaitFollow message to indicate that he must ask*/
|
||
/* for connection to this local player first*/
|
||
pstMes->eMessageType = E_Net_mt_SysWaitFollow;
|
||
pstMes->uxRecipientId = uxSenderId;
|
||
pstMes->uxSenderId = NetLib_uxGetOwnPlayerId();
|
||
pstMes->uwMessageSizeInBytes = 0;
|
||
pstMes->uxPriority = NetLib_C_uxNoPriority;
|
||
pstMes->uxReplaceType = 0;
|
||
pstMes->uxReplace = 0;
|
||
pstMes->m_uxReadReceiptId = NetLib_C_ucNoReadReceipt;
|
||
eErrorReturned = eLevel1SendMessage(pstMes,eProt,uwChannel);
|
||
|
||
if (eErrorReturned != NetLib_E_es_NoError) vFree(pstMes);
|
||
return eErrorReturned;
|
||
}
|
||
else
|
||
{ /* Not enough memory to process the message :*/
|
||
return NetLib_E_es_NotEnoughMemory;
|
||
}
|
||
}
|
||
|
||
/* The local player is the recipient */
|
||
/* check if it is not yet connected*/
|
||
c_uwCount = 0;
|
||
while ((c_uwCount<gs_stCurrentSession.uwMaxNumberOfPlayers)
|
||
&&(uxSenderId!=M_ulNetPlayerIdSlot(&gs_stCurrentSession.d_stPlayerInfo[c_uwCount])))
|
||
c_uwCount++;
|
||
|
||
if(c_uwCount < gs_stCurrentSession.uwMaxNumberOfPlayers)
|
||
{
|
||
/*The player is already in the session*/
|
||
/* May be he did not received the listening message*/
|
||
/* So resent it :*/
|
||
vFree(pstMes);
|
||
p_stMessageReturned = (tdstNetMessage*)pMalloc(sizeof(tdstNetMessage));
|
||
if(p_stMessageReturned)
|
||
{
|
||
p_stMessageReturned->eMessageType = E_Net_mt_SysConnectListened;
|
||
p_stMessageReturned->uxRecipientId=uxSenderId;
|
||
p_stMessageReturned->uxSenderId=NetLib_uxGetOwnPlayerId();
|
||
p_stMessageReturned->uwMessageSizeInBytes = 0;
|
||
p_stMessageReturned->uxPriority = NetLib_C_uxMaxPriority;
|
||
p_stMessageReturned->uxReplaceType = 0;
|
||
p_stMessageReturned->uxReplace = 0;
|
||
p_stMessageReturned->m_uxReadReceiptId = NetLib_C_ucNoReadReceipt;
|
||
if(gs_ArtificialLatency) eErrorReturned = eInternetSimuSendMessage(uxSenderId,p_stMessageReturned);
|
||
else eErrorReturned = eLevel1SendMessage(p_stMessageReturned,E_Net_pr_InvalidProtocol,C_uwNetInvalidChannel);
|
||
|
||
if(eErrorReturned !=NetLib_E_es_NoError) vFree((tdpPointer)p_stMessageReturned);
|
||
return eErrorReturned;
|
||
}
|
||
else return NetLib_E_es_NotEnoughMemory;
|
||
}
|
||
|
||
/* The player is realy a new one :*/
|
||
gs_p_stPreSessionPlayerInfo = (NetLib_tdstPlayerInfo*)pMalloc(sizeof(NetLib_tdstPlayerInfo));
|
||
if(!gs_p_stPreSessionPlayerInfo /*== (NetLib_tdstPlayerInfo*)C_pNull*/)
|
||
{
|
||
/* Not enough memory to process the message */
|
||
vFree(pstMes);
|
||
return NetLib_E_es_NotEnoughMemory;
|
||
}
|
||
|
||
/* Init player description :*/
|
||
M_ulNetPlayerIdSlot(gs_p_stPreSessionPlayerInfo) = uxSenderId;
|
||
gs_p_stPreSessionPlayerInfo->Options=NULL;
|
||
/* sets p_OriginData at the begining of the body of the message :*/
|
||
p_OriginData = (tdpPointer)(pstMes + 1);
|
||
/* retrieves the length of the player description :*/
|
||
gs_p_stPreSessionPlayerInfo->uxPlayerDescriptionLength=*((NetLib_tduxDescriptionLength*)p_OriginData);
|
||
p_OriginData = (tdpPointer)((NetLib_tduxDescriptionLength*)p_OriginData + 1);
|
||
if ((gs_p_stPreSessionPlayerInfo->uxPlayerDescriptionLength) &&
|
||
((gs_p_stPreSessionPlayerInfo->pPlayerDescriptionData =
|
||
(tdpPointer)pMalloc(gs_p_stPreSessionPlayerInfo->uxPlayerDescriptionLength))!=0))
|
||
{
|
||
/* retrieves the player description :*/
|
||
g_pfn_vNetMemcpy(gs_p_stPreSessionPlayerInfo->pPlayerDescriptionData,p_OriginData,
|
||
gs_p_stPreSessionPlayerInfo->uxPlayerDescriptionLength);
|
||
p_OriginData=p_OriginData + gs_p_stPreSessionPlayerInfo->uxPlayerDescriptionLength;
|
||
}
|
||
else
|
||
{
|
||
p_OriginData=p_OriginData + gs_p_stPreSessionPlayerInfo->uxPlayerDescriptionLength;
|
||
gs_p_stPreSessionPlayerInfo->uxPlayerDescriptionLength = 0;
|
||
gs_p_stPreSessionPlayerInfo->pPlayerDescriptionData = (tdpPointer)C_pNull;
|
||
}
|
||
gs_p_stPreSessionPlayerInfo->m_ucLittleBigEndian=*((NetLib_tducBigLittleEndian*)p_OriginData);
|
||
p_OriginData = p_OriginData + sizeof(NetLib_tducBigLittleEndian);
|
||
|
||
gs_p_stPreSessionPlayerInfo->m_bOverInternet=*p_OriginData;
|
||
|
||
/* Check if the game accept the connection process : */
|
||
if ((g_pfn_ePlayerConnectionRequestFilter) &&
|
||
(g_pfn_ePlayerConnectionRequestFilter(gs_p_stPreSessionPlayerInfo,&lParam)!=
|
||
NetLib_E_es_True))
|
||
{
|
||
/* the game refused the connection :*/
|
||
vFree(gs_p_stPreSessionPlayerInfo->pPlayerDescriptionData);
|
||
vFree((tdpPointer)gs_p_stPreSessionPlayerInfo);
|
||
gs_p_stPreSessionPlayerInfo = (NetLib_tdstPlayerInfo*)C_pNull;
|
||
vFree(pstMes);
|
||
pstMes = (tdstNetMessage*)pMalloc(sizeof(tdstNetMessage)+sizeof(long));
|
||
|
||
if(pstMes)
|
||
{
|
||
pstMes->eMessageType = E_Net_mt_SysConnectDeny;
|
||
pstMes->uwMessageSizeInBytes = sizeof(long);
|
||
pstMes->uxRecipientId = uxSenderId;
|
||
pstMes->uxSenderId = NetLib_uxGetOwnPlayerId();
|
||
pstMes->uxPriority = NetLib_C_uxNoPriority;
|
||
pstMes->uxReplaceType = 0;
|
||
pstMes->uxReplace = 0;
|
||
pstMes->m_uxReadReceiptId = NetLib_C_ucNoReadReceipt;
|
||
|
||
/* and now the body :*/
|
||
p_OriginData = (tdpPointer)(pstMes + 1);
|
||
*((long*)p_OriginData) = lParam;
|
||
|
||
if((eErrorReturned = eLevel1SendMessage(pstMes,eProt,uwChannel))!=NetLib_E_es_NoError)
|
||
vFree(pstMes);
|
||
return eErrorReturned;
|
||
}
|
||
else return NetLib_E_es_NotEnoughMemory;
|
||
}
|
||
|
||
/* initialise the gs_tdePreSessionPlayerStatus */
|
||
gs_tdePreSessionPlayerStatus = E_Net_ConRecSta_DOING;
|
||
/* Initialise the timeout :*/
|
||
if(g_pfn_ulNetGetTimeInfo) gs_tm_ulPreSessionPlayerTimer = (*g_pfn_ulNetGetTimeInfo)();
|
||
else gs_tm_ulPreSessionPlayerTimer = 0;
|
||
/* Inform the level1 of the connection request :*/
|
||
if (((eErrorReturned = eLevel1HandleSysMsgConnectRequest(pstMes,eProt,uwChannel)) != NetLib_E_es_NoError)
|
||
&&(eErrorReturned !=NetLib_E_es_IdAlreadyInRouteTable))
|
||
{/* Level 1 failure */
|
||
vFree(gs_p_stPreSessionPlayerInfo->pPlayerDescriptionData);
|
||
vFree((tdpPointer)gs_p_stPreSessionPlayerInfo);
|
||
gs_p_stPreSessionPlayerInfo = (NetLib_tdstPlayerInfo*)C_pNull;
|
||
gs_tdePreSessionPlayerStatus = E_Net_ConRecSta_NONE;
|
||
/* Close the connection with the player :*/
|
||
eLevel1DisconnectRemotePlayer(M_ulNetPlayerIdSlot(gs_p_stPreSessionPlayerInfo));
|
||
/* Free memory :*/
|
||
vFree(pstMes);
|
||
return eErrorReturned;
|
||
}
|
||
|
||
p_stMessageReturned = (tdstNetMessage*)pMalloc(
|
||
sizeof(tdstNetMessage) + /* for the message */
|
||
sizeof(unsigned short)+ /* for the number of players in the session*/
|
||
sizeof(NetLib_tduxPlayerId)*gs_stCurrentSession.uwNumberOfPlayers+ /* for the ids of each player*/
|
||
sizeof(char)); /* the "over internet" mark */
|
||
|
||
if(!p_stMessageReturned)
|
||
{
|
||
/* not enough memory to process the msg :*/
|
||
/* So clear data...*/
|
||
vFree((tdpPointer)gs_p_stPreSessionPlayerInfo->pPlayerDescriptionData);
|
||
vFree((tdpPointer)gs_p_stPreSessionPlayerInfo);
|
||
gs_p_stPreSessionPlayerInfo = (NetLib_tdstPlayerInfo*)C_pNull;
|
||
gs_tdePreSessionPlayerStatus = E_Net_ConRecSta_NONE;
|
||
|
||
/* Close the connection with the player :*/
|
||
eLevel1DisconnectRemotePlayer(M_ulNetPlayerIdSlot(gs_p_stPreSessionPlayerInfo));
|
||
|
||
vFree(pstMes);
|
||
return NetLib_E_es_NotEnoughMemory;
|
||
}
|
||
|
||
/* Send an agreement message :*/
|
||
/*
|
||
Body of the message :
|
||
->Number of players
|
||
->Player 1 Id
|
||
...
|
||
->Player n Id
|
||
*/
|
||
p_stMessageReturned->eMessageType = E_Net_mt_SysConnectAgreement;
|
||
p_stMessageReturned->uxRecipientId=uxSenderId;
|
||
p_stMessageReturned->uxSenderId=NetLib_uxGetOwnPlayerId();
|
||
p_stMessageReturned->uwMessageSizeInBytes = sizeof(unsigned short)
|
||
+ sizeof(NetLib_tduxPlayerId)*gs_stCurrentSession.uwNumberOfPlayers
|
||
+ sizeof(char);
|
||
p_stMessageReturned->uxPriority = NetLib_C_uxMaxPriority;
|
||
p_stMessageReturned->uxReplaceType = 0;
|
||
p_stMessageReturned->uxReplace = 0;
|
||
p_stMessageReturned->m_uxReadReceiptId = NetLib_C_ucNoReadReceipt;
|
||
|
||
/* Builds the body of the message :*/
|
||
p_OriginData = (tdpPointer)(p_stMessageReturned+1);
|
||
*((unsigned short*)p_OriginData) = gs_stCurrentSession.uwNumberOfPlayers;
|
||
p_OriginData = (tdpPointer)((unsigned short*)p_OriginData + 1);
|
||
for(c_uwCount = 0;c_uwCount <gs_stCurrentSession.uwMaxNumberOfPlayers; c_uwCount++)
|
||
{
|
||
if(M_ulNetPlayerIdSlot(&gs_stCurrentSession.d_stPlayerInfo[c_uwCount])!=C_uxNetInvalidId)
|
||
{
|
||
*((NetLib_tduxPlayerId*)p_OriginData)=M_ulNetPlayerIdSlot(&gs_stCurrentSession.d_stPlayerInfo[c_uwCount]);
|
||
p_OriginData=(tdpPointer)((NetLib_tduxPlayerId*)p_OriginData + 1);
|
||
}
|
||
}
|
||
|
||
(*(char *)p_OriginData) = gs_p_stPreSessionPlayerInfo->m_bOverInternet;
|
||
|
||
if(gs_ArtificialLatency) eErrorReturned = eInternetSimuSendMessage(uxSenderId,p_stMessageReturned);
|
||
else eErrorReturned = eLevel1SendMessage(p_stMessageReturned,E_Net_pr_InvalidProtocol,C_uwNetInvalidChannel);
|
||
if(eErrorReturned != NetLib_E_es_NoError)
|
||
{
|
||
/* Close the connection with the player : */
|
||
eLevel1DisconnectRemotePlayer(M_ulNetPlayerIdSlot(gs_p_stPreSessionPlayerInfo));
|
||
/* Clear data : */
|
||
vFree((tdpPointer)p_stMessageReturned);
|
||
p_stMessageReturned = (tdstNetMessage*)C_pNull;
|
||
vFree((tdpPointer)gs_p_stPreSessionPlayerInfo->pPlayerDescriptionData);
|
||
/* Not necessary :
|
||
gs_p_stPreSessionPlayerInfo->pPlayerDescriptionData = (tdpPointer)C_pNull; */
|
||
vFree((tdpPointer)gs_p_stPreSessionPlayerInfo);
|
||
gs_p_stPreSessionPlayerInfo = (NetLib_tdstPlayerInfo*)C_pNull;
|
||
gs_tdePreSessionPlayerStatus = E_Net_ConRecSta_NONE;
|
||
}
|
||
vFree(pstMes);
|
||
return eErrorReturned;
|
||
}/* end of if(gs_p_stPreSessionPlayerInfo == C_pNull)*/
|
||
|
||
/*------------------------------------------------------------
|
||
A CONNECTION IS ALREADY IN PROGRESS :
|
||
------------------------------------------------------------ */
|
||
/* check if it is the same player that sends this connection msg :*/
|
||
if(uxSenderId != M_ulNetPlayerIdSlot(gs_p_stPreSessionPlayerInfo))
|
||
{ /* a new player asks for connection */
|
||
vFree(pstMes);
|
||
pstMes = (tdstNetMessage*)pMalloc(sizeof(tdstNetMessage));
|
||
if(pstMes)
|
||
{
|
||
pstMes->eMessageType = E_Net_mt_SysWaitBusy;
|
||
pstMes->uxRecipientId = uxSenderId;
|
||
pstMes->uxSenderId = NetLib_uxGetOwnPlayerId();
|
||
pstMes->uwMessageSizeInBytes = 0;
|
||
pstMes->uxPriority = NetLib_C_uxNoPriority;
|
||
pstMes->uxReplaceType = 0;
|
||
pstMes->uxReplace = 0;
|
||
pstMes->m_uxReadReceiptId = NetLib_C_ucNoReadReceipt;
|
||
eErrorReturned = eLevel1SendMessage(pstMes,eProt,uwChannel);
|
||
if(eErrorReturned != NetLib_E_es_NoError) vFree(pstMes);
|
||
return eErrorReturned;
|
||
}
|
||
else
|
||
{
|
||
vFree(pstMes);
|
||
return NetLib_E_es_NotEnoughMemory;
|
||
}
|
||
}
|
||
|
||
/* The sender is the same as the one in the buffer*/
|
||
|
||
/* check if the local player is the recipient of the message :*/
|
||
if(uxRecipientId != NetLib_uxGetOwnPlayerId())
|
||
{/* the local player is not the recipient : so route message */
|
||
|
||
/* set the "via internet" mark of the message */
|
||
|
||
/* sets p_OriginData at the begining of the body of the message :*/
|
||
p_OriginData = (tdpPointer)(pstMes + 1);
|
||
/* retrieves the length of the player description :*/
|
||
uxPlayerDescriptionLength = *((NetLib_tduxDescriptionLength*)p_OriginData);
|
||
/* skip all data before the "via internet" mark */
|
||
p_OriginData = (tdpPointer)(p_OriginData +
|
||
sizeof(NetLib_tduxDescriptionLength) +
|
||
uxPlayerDescriptionLength +
|
||
sizeof(NetLib_tducBigLittleEndian));
|
||
/* eventually set the mark */
|
||
if(eLevel1GoesToIP(uxRecipientId)) *((char *)p_OriginData)=1;
|
||
|
||
/* route the message */
|
||
|
||
eErrorReturned = eLevel1RouteSysMsg(pstMes,eProt,uwChannel);
|
||
if(eErrorReturned != NetLib_E_es_NoError) vFree(pstMes);
|
||
return eErrorReturned;
|
||
}
|
||
|
||
/* the local player is the recipient*/
|
||
eLevel1HandleSysMsgConnectRequest(pstMes,eProt,uwChannel);
|
||
|
||
/* We do not need p_stIOSystCell any more :*/
|
||
vFree(pstMes);
|
||
|
||
p_stMessageReturned=(tdstNetMessage*)pMalloc(sizeof(tdstNetMessage)+sizeof(unsigned short)+
|
||
sizeof(NetLib_tduxPlayerId)*gs_stCurrentSession.uwNumberOfPlayers);
|
||
|
||
if(!p_stMessageReturned) return NetLib_E_es_NotEnoughMemory; /* not enough memory to process the message*/
|
||
|
||
p_stMessageReturned->eMessageType = E_Net_mt_SysConnectAgreement;
|
||
p_stMessageReturned->uxRecipientId=uxSenderId;
|
||
p_stMessageReturned->uxSenderId=NetLib_uxGetOwnPlayerId();
|
||
p_stMessageReturned->uwMessageSizeInBytes=sizeof(unsigned short)
|
||
+sizeof(NetLib_tduxPlayerId)*gs_stCurrentSession.uwNumberOfPlayers;
|
||
p_stMessageReturned->uxPriority = NetLib_C_uxMaxPriority;
|
||
p_stMessageReturned->uxReplaceType = 0;
|
||
p_stMessageReturned->uxReplace = 0;
|
||
p_stMessageReturned->m_uxReadReceiptId = NetLib_C_ucNoReadReceipt;
|
||
|
||
/* Builds the body of the message :*/
|
||
p_OriginData = (tdpPointer)(p_stMessageReturned + 1);
|
||
*((unsigned short*)p_OriginData) = gs_stCurrentSession.uwNumberOfPlayers;
|
||
p_OriginData = (tdpPointer)((unsigned short*)p_OriginData + 1);
|
||
for(c_uwCount = 0;c_uwCount <gs_stCurrentSession.uwMaxNumberOfPlayers; c_uwCount++)
|
||
{
|
||
if(M_ulNetPlayerIdSlot(&gs_stCurrentSession.d_stPlayerInfo[c_uwCount]) != C_uxNetInvalidId)
|
||
{
|
||
*((NetLib_tduxPlayerId*)p_OriginData) = M_ulNetPlayerIdSlot(&gs_stCurrentSession.d_stPlayerInfo[c_uwCount]);
|
||
p_OriginData =(tdpPointer)((NetLib_tduxPlayerId*)p_OriginData + 1);
|
||
}
|
||
}
|
||
if(gs_ArtificialLatency) eErrorReturned = eInternetSimuSendMessage(uxSenderId,p_stMessageReturned);
|
||
else eErrorReturned = eLevel1SendMessage(p_stMessageReturned,E_Net_pr_InvalidProtocol,C_uwNetInvalidChannel);
|
||
if(eErrorReturned!=NetLib_E_es_NoError) vFree((tdpPointer)p_stMessageReturned);
|
||
|
||
/* we choose to restart the timer */
|
||
gs_tm_ulPreSessionPlayerTimer = (*g_pfn_ulNetGetTimeInfo)();
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_tdeErrorStatus eHandleNetSysMsgConnectCancel(tdstNetIOSystemCell*p_stIOSystCell)
|
||
Handle of the system message ConnectCancel
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : a tdstNetIOSystemCell that contains the information about the message
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_NoError if no error occured
|
||
NetLib_E_es_ShouldNotReach the message should not reach this function
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : April 4,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eHandleNetSysMsgConnectCancel(tdstNetMessage *pstMes,tdeNetProtocol eProt,tduwNetChannel uwChannel)
|
||
{
|
||
NetLib_tdeErrorStatus eErrorReturned;
|
||
|
||
if(pstMes->uxRecipientId != NetLib_uxGetOwnPlayerId())
|
||
{/* the message must be routed*/
|
||
eErrorReturned = eLevel1RouteSysMsg(pstMes,eProt,uwChannel);
|
||
if(eErrorReturned != NetLib_E_es_NoError) vFree(pstMes);
|
||
return eErrorReturned;
|
||
}
|
||
|
||
/* the local player is the recipient */
|
||
if ((gs_p_stPreSessionPlayerInfo)
|
||
&&(pstMes->uxSenderId == M_ulNetPlayerIdSlot(gs_p_stPreSessionPlayerInfo)))
|
||
{
|
||
/*The player cancels its connection request*/
|
||
/* Close the communication medium :*/
|
||
eLevel1DisconnectRemotePlayer(M_ulNetPlayerIdSlot(gs_p_stPreSessionPlayerInfo));
|
||
/*Clear the information about the player*/
|
||
vFree((tdpPointer)gs_p_stPreSessionPlayerInfo->pPlayerDescriptionData);
|
||
vFree((tdpPointer)gs_p_stPreSessionPlayerInfo);
|
||
gs_p_stPreSessionPlayerInfo = (NetLib_tdstPlayerInfo*)C_pNull;
|
||
gs_tdePreSessionPlayerStatus = E_Net_ConRecSta_NONE;
|
||
}
|
||
else
|
||
{
|
||
/* no one made a connection. Check if it not a player already in the game :*/
|
||
if(uwNetGetPlayerIndex(pstMes->uxSenderId)!=NetLib_C_uwInvalidPosition)
|
||
{
|
||
if(g_pfn_vDisconnectCallBack)
|
||
(*g_pfn_vDisconnectCallBack)(pstMes->uxSenderId);
|
||
eNetRemoveRemotePlayer(pstMes->uxSenderId);
|
||
}
|
||
}
|
||
vFree(pstMes);
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_tdeErrorStatus eHandleNetSysMsgConnectAcknowledgement(tdstNetIOSystemCell*p_stIOSystCell)
|
||
Handle of the system message Connect acknowledgement
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : a tdstNetIOSystemCell that contains the information about the message
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_NoError if no error occured
|
||
NetLib_E_es_ShouldNotReach the message should not reach this function
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : April 4,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eHandleNetSysMsgConnectAcknowledgement(tdstNetMessage *pstMes,tdeNetProtocol eProt,tduwNetChannel uwChannel)
|
||
{
|
||
NetLib_tdeErrorStatus eErrorReturned;
|
||
NetLib_tdstListenDesc stListenDesc;
|
||
char flagDirect; /* Direct route flag. */
|
||
flagDirect=*((char *)(pstMes+1));
|
||
|
||
if(pstMes->uxRecipientId == NetLib_uxGetOwnPlayerId())
|
||
{/* the local player is the recipient */
|
||
if((gs_p_stPreSessionPlayerInfo) &&
|
||
(pstMes->uxSenderId == M_ulNetPlayerIdSlot(gs_p_stPreSessionPlayerInfo)))
|
||
{/*The player confirms its connection request*/
|
||
gs_tdePreSessionPlayerStatus = E_Net_ConRecSta_DONE;
|
||
if (flagDirect==0) vLevel1AddBroadcastPath(NetLib_uxGetOwnPlayerId(),pstMes->uxSenderId);
|
||
if(gs_ucAcceptWithoutListening==NetLib_C_ucAcceptWithoutListening)
|
||
{
|
||
stListenDesc.m_ulMaxWaitingTime = 0;
|
||
stListenDesc.m_pPlayerDescriptionData = C_pNull;
|
||
NetLib_eListenForRequest(&stListenDesc);
|
||
}
|
||
}
|
||
/*
|
||
else
|
||
somone different from the player who asked for the connection
|
||
confirms a connection. There is nothing to do.
|
||
*/
|
||
vFree(pstMes);
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/* the message must be routed*/
|
||
*((char *)(pstMes+1))=1; /* Set the route flag (message not direct).*/
|
||
vLevel1AddBroadcastPath(pstMes->uxSenderId,pstMes->uxRecipientId);
|
||
eErrorReturned = eLevel1RouteSysMsg(pstMes,eProt,uwChannel);
|
||
if(eErrorReturned != NetLib_E_es_NoError) vFree(pstMes); /* Erase data*/
|
||
|
||
return eErrorReturned;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : eSwapLittleBigEndianSysMsgConnectAgreement
|
||
swap the system message Connect agreement
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : a tdstNetIOSystemCell that contains the information about the message
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_NoError if no error occured
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : October 23,96
|
||
Author : Albert Pais
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Message body :
|
||
-> uwNbrOfPlayers
|
||
-> ulPlayer1Id
|
||
-> .
|
||
-> .
|
||
-> .
|
||
-> ulPlayernId
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eSwapLittleBigEndianSysMsgConnectAgreement(tdstNetMessage *pstMes,tdeNetProtocol eProt,tduwNetChannel uwChannel)
|
||
{
|
||
unsigned short uwCount;
|
||
unsigned short uwNbrOfPlayers;
|
||
tdpPointer pOriginData;
|
||
|
||
pOriginData = (tdpPointer)(pstMes+1);
|
||
uwNbrOfPlayers = *((unsigned short*)pOriginData) =
|
||
M_NET_uwSwapLittleBigEndian(*((unsigned short*)pOriginData));
|
||
pOriginData = (tdpPointer)((unsigned short *)pOriginData +1);
|
||
for(uwCount = 0;uwCount < uwNbrOfPlayers;uwCount++)
|
||
{
|
||
pOriginData = (tdpPointer)((NetLib_tduxPlayerId*)pOriginData+1);
|
||
}
|
||
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_tdeErrorStatus eHandleNetSysMsgConnectAgreement(tdstNetIOSystemCell*p_stIOSystCell)
|
||
Handle of the system message Connect agreement
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : a tdstNetIOSystemCell that contains the information about the message
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_NoError if no error occured
|
||
NetLib_E_es_ShouldNotReach the message should not reach this function
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : April 4,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eHandleNetSysMsgConnectAgreement(tdstNetMessage *pstMes,tdeNetProtocol eProt,tduwNetChannel uwChannel)
|
||
{
|
||
NetLib_tdeErrorStatus eErrorReturned;
|
||
NetLib_tduxPlayerId *d_ulIdPlayerArray;
|
||
unsigned short c_uwCount;
|
||
unsigned short c_uwCount2;
|
||
unsigned short uwNumberOfPlayers;
|
||
unsigned short uwSenderIndex;
|
||
unsigned char b_ucDifferent;
|
||
tdpPointer p_OriginData;
|
||
|
||
if(pstMes->uxRecipientId != NetLib_uxGetOwnPlayerId())
|
||
{/* the local player is not the recipient :*/
|
||
eErrorReturned = eLevel1RouteSysMsg(pstMes,eProt,uwChannel);
|
||
if(eErrorReturned != NetLib_E_es_NoError) vFree(pstMes);
|
||
return eErrorReturned;
|
||
}
|
||
|
||
/* The local player is the recipient */
|
||
if(!gs_p_stConnectRequestSessionInfo)
|
||
{/* It should not occured but...*/
|
||
vFree(pstMes);
|
||
return NetLib_E_es_UnknownError;
|
||
}/* end of else (gs_p_stConnectRequestSessionInfo != C_pNull)*/
|
||
|
||
/*
|
||
found the index of the sender
|
||
*/
|
||
uwSenderIndex = 0;
|
||
while ((uwSenderIndex<gs_p_stConnectRequestSessionInfo->uwNumberOfPlayers)
|
||
&&(pstMes->uxSenderId!=
|
||
M_ulNetPlayerIdSlot(&gs_p_stConnectRequestSessionInfo->d_stPlayerInfo[uwSenderIndex])))
|
||
{
|
||
uwSenderIndex++;
|
||
}
|
||
if(uwSenderIndex >=gs_p_stConnectRequestSessionInfo->uwNumberOfPlayers )
|
||
{/* It should not occured but...*/
|
||
vFree(pstMes);
|
||
return NetLib_E_es_UnknownError;
|
||
}/* end of else (gs_p_stConnectRequestSessionInfo != C_pNull)*/
|
||
|
||
/* Check the intergity of the session information with the message sent*/
|
||
/* Sets p_OriginData at the begining of the message body :*/
|
||
p_OriginData = (tdpPointer)(pstMes + 1);
|
||
/* Retireves the number of players*/
|
||
uwNumberOfPlayers = *((unsigned short*)p_OriginData);
|
||
p_OriginData = (tdpPointer)((unsigned short*)p_OriginData + 1);
|
||
/* Retrieves the array of player ids*/
|
||
d_ulIdPlayerArray = (NetLib_tduxPlayerId *)p_OriginData;
|
||
|
||
if(gs_p_stConnectRequestSessionInfo->uwNumberOfPlayers != uwNumberOfPlayers)
|
||
{/* The numbers of players are different..............*/
|
||
gs_d_tdeConnectRequestStatusArray[uwSenderIndex] = E_Net_ConReqSta_SessionChanged;
|
||
vFree(pstMes);
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/* The number of players are equals, but are they the same ?????*/
|
||
c_uwCount = 0;
|
||
b_ucDifferent = 0;
|
||
while((c_uwCount < uwNumberOfPlayers)&&(!b_ucDifferent))
|
||
{
|
||
c_uwCount2 = 0;
|
||
while((c_uwCount2<uwNumberOfPlayers)&&(d_ulIdPlayerArray[c_uwCount] != M_ulNetPlayerIdSlot(&gs_p_stConnectRequestSessionInfo->d_stPlayerInfo[c_uwCount2])))
|
||
{
|
||
c_uwCount2++;
|
||
}/*End of while((C_uwCount2 <...*/
|
||
if(c_uwCount2 >=uwNumberOfPlayers) b_ucDifferent = 1;
|
||
|
||
c_uwCount++;
|
||
}/* End of while((c_uwCount < uwNumberOfPlayers)&&(b_ucDifferent == 0)...*/
|
||
|
||
vFree(pstMes);
|
||
|
||
if(b_ucDifferent != 0)
|
||
{
|
||
gs_d_tdeConnectRequestStatusArray[uwSenderIndex] = E_Net_ConReqSta_SessionChanged;
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/* The list are equals*/
|
||
|
||
/* rembember the "over internet" mark */
|
||
|
||
p_OriginData = p_OriginData + uwNumberOfPlayers*sizeof(NetLib_tduxPlayerId);
|
||
gs_p_stConnectRequestSessionInfo->d_stPlayerInfo[uwSenderIndex].m_bOverInternet=*p_OriginData;
|
||
|
||
gs_d_tdeConnectRequestStatusArray[uwSenderIndex] = E_Net_ConReqSta_Done;
|
||
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : eSwapLittleBigEndianSysMsgConnectDeny
|
||
swap the system message Connect deny
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : a tdstNetIOSystemCell that contains the information about the message
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_NoError if no error occured
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : October 23,96
|
||
Author : Albert Pais
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Message body :
|
||
->lParam -> swap
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eSwapLittleBigEndianSysMsgConnectDeny(tdstNetMessage *pstMes,tdeNetProtocol eProt,tduwNetChannel uwChannel)
|
||
{
|
||
*((long*)(pstMes+1))=M_NET_ulSwapLittleBigEndian(*((long*)(pstMes+1)));
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_tdeErrorStatus eHandleNetSysMsgConnectDeny(tdstNetIOSystemCell*p_stIOSystCell)
|
||
Handle of the system message Connect deny
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : a tdstNetIOSystemCell that contains the information about the message
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_NoError if no error occured
|
||
NetLib_E_es_ShouldNotReach the message should not reach this function
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : April 4,96
|
||
Author : Albert Pais
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Improvement :
|
||
Check that the sender of the message belongs to the session where the connection
|
||
has been done.
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eHandleNetSysMsgConnectDeny(tdstNetMessage *pstMes,tdeNetProtocol eProt,tduwNetChannel uwChannel)
|
||
{
|
||
NetLib_tdeErrorStatus eErrorReturned;
|
||
unsigned short c_uwCount;
|
||
tdpPointer p_MsgData;
|
||
|
||
/* Cancel the conection :*/
|
||
if(pstMes->uxRecipientId == NetLib_uxGetOwnPlayerId())
|
||
{/* the local player is the recipient*/
|
||
p_MsgData = (tdpPointer) (pstMes + 1);
|
||
gs_lConDenyParam = *((long*)p_MsgData);
|
||
|
||
if(gs_p_stConnectRequestSessionInfo)
|
||
{
|
||
c_uwCount = 0;
|
||
while(c_uwCount < gs_p_stConnectRequestSessionInfo->uwNumberOfPlayers)
|
||
{
|
||
if (M_ulNetPlayerIdSlot(&(gs_p_stConnectRequestSessionInfo->d_stPlayerInfo[c_uwCount]))
|
||
== pstMes->uxSenderId)
|
||
{
|
||
gs_d_tdeConnectRequestStatusArray[c_uwCount] = E_Net_ConReqSta_Refused;
|
||
c_uwCount = gs_p_stConnectRequestSessionInfo->uwNumberOfPlayers+1;
|
||
}
|
||
else c_uwCount++;
|
||
}
|
||
}
|
||
else return NetLib_E_es_ShouldNotReach;
|
||
|
||
vFree(pstMes);
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
else
|
||
{/* the local player is not the recipient :*/
|
||
eErrorReturned = eLevel1RouteSysMsg(pstMes,eProt,uwChannel);
|
||
if(eErrorReturned != NetLib_E_es_NoError) vFree(pstMes);
|
||
return eErrorReturned;
|
||
}
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_tdeErrorStatus eHandleNetSysMsgConnectListened(tdstNetIOSystemCell*p_stIOSystCell)
|
||
Handle of the system message Connect agreement
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : a tdstNetIOSystemCell that contains the information about the message
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_NoError if no error occured
|
||
NetLib_E_es_ShouldNotReach the message should not reach this function
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : April 10,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eHandleNetSysMsgConnectListened(tdstNetMessage *pstMes,tdeNetProtocol eProt,tduwNetChannel uwChannel)
|
||
{
|
||
unsigned short c_uwCount;
|
||
NetLib_tdeErrorStatus eErrorReturned;
|
||
char flagDirect; /* Direct route flag. */
|
||
flagDirect=*((char *)(pstMes+1));
|
||
|
||
/* Check if the message is for the local player :*/
|
||
if(pstMes->uxRecipientId !=NetLib_uxGetOwnPlayerId())
|
||
{/* the local player is not the recipient :*/
|
||
*((char *)(pstMes+1))=1; /* Set the route flag (message not direct).*/
|
||
vLevel1AddBroadcastPath(pstMes->uxSenderId,pstMes->uxRecipientId);
|
||
if((eErrorReturned = eLevel1RouteSysMsg(pstMes,eProt,uwChannel))!=NetLib_E_es_NoError)
|
||
vFree(pstMes);
|
||
return eErrorReturned;
|
||
}
|
||
|
||
/* The local player is the recipient :*/
|
||
if(!gs_p_stConnectRequestSessionInfo) return NetLib_E_es_ShouldNotReach;
|
||
|
||
/* finding the appropriate player :*/
|
||
c_uwCount = 0;
|
||
while ((c_uwCount<gs_p_stConnectRequestSessionInfo->uwNumberOfPlayers)&&
|
||
(M_ulNetPlayerIdSlot(&gs_p_stConnectRequestSessionInfo->d_stPlayerInfo[c_uwCount]) !=
|
||
pstMes->uxSenderId))
|
||
c_uwCount++;
|
||
|
||
if(c_uwCount < gs_p_stConnectRequestSessionInfo->uwNumberOfPlayers)
|
||
{
|
||
if (flagDirect==0) vLevel1AddBroadcastPath(NetLib_uxGetOwnPlayerId(),pstMes->uxSenderId);
|
||
gs_d_tdeConnectRequestStatusArray[c_uwCount] = E_Net_ConReqSta_Listened;
|
||
vFree(pstMes);
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
else
|
||
{
|
||
vFree(pstMes);
|
||
return NetLib_E_es_UnknownPlayerId;
|
||
}
|
||
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_tdeErrorStatus eHandleNetSysMsgWaitFollow(tdstNetIOSystemCell*p_stIOSystCell)
|
||
Handle of the system message Wait follow
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : a tdstNetIOSystemCell that contains the information about the message
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_NoError if no error occured
|
||
NetLib_E_es_ShouldNotReach the message should not reach this function
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : April 4,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eHandleNetSysMsgWaitFollow(tdstNetMessage *pstMes,tdeNetProtocol eProt,tduwNetChannel uwChannel)
|
||
{
|
||
NetLib_tdeErrorStatus eErrorReturned;
|
||
|
||
if(pstMes->uxRecipientId != NetLib_uxGetOwnPlayerId())
|
||
{/* the local player is not the recipient :*/
|
||
if((eErrorReturned = eLevel1RouteSysMsg(pstMes,eProt,uwChannel))!=NetLib_E_es_NoError)
|
||
vFree(pstMes);
|
||
return eErrorReturned;
|
||
}
|
||
|
||
if(!gs_p_stConnectRequestSessionInfo)
|
||
{
|
||
vFree(pstMes);
|
||
return NetLib_E_es_ShouldNotReach;
|
||
}
|
||
|
||
/* Frees the memory : */
|
||
vFree(pstMes);
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description :NetLib_tdeErrorStatus eHandleNetSysMsgWaitBusy(tdstNetIOSystemCell*p_stIOSystCell)
|
||
Handle of the system message wait busy
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : a tdstNetIOSystemCell that contains the information about the message
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_NoError if no error occured
|
||
NetLib_E_es_ShouldNotReach the message should not reach this function
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : April 4,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eHandleNetSysMsgWaitBusy(tdstNetMessage *pstMes,tdeNetProtocol eProt,tduwNetChannel uwChannel)
|
||
{
|
||
NetLib_tdeErrorStatus eErrorReturned;
|
||
unsigned short c_uwCount;
|
||
|
||
if(pstMes->uxRecipientId != NetLib_uxGetOwnPlayerId())
|
||
{/* the local playr is not the recipient*/
|
||
if((eErrorReturned = eLevel1RouteSysMsg(pstMes,eProt,uwChannel))!=NetLib_E_es_NoError)
|
||
vFree(pstMes);
|
||
return eErrorReturned;
|
||
}
|
||
|
||
if (!gs_p_stConnectRequestSessionInfo)
|
||
{
|
||
vFree(pstMes);
|
||
return NetLib_E_es_ShouldNotReach;
|
||
}
|
||
|
||
/* Cancel the conection :*/
|
||
for(c_uwCount = 0; c_uwCount < gs_p_stConnectRequestSessionInfo->uwNumberOfPlayers;c_uwCount++)
|
||
gs_d_tdeConnectRequestStatusArray[c_uwCount] = E_Net_ConReqSta_WaitBusy;
|
||
|
||
vFree(pstMes);
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description :NetLib_tdeErrorStatus eHandleNetSysMsgDisconnection(tdstNetIOSystemCell*p_stIOSystCell)
|
||
Handle of the system message Disconnect
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : a tdstNetIOSystemCell that contains the information about the message
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_NoError if no error occured
|
||
NetLib_E_es_ShouldNotReach the message should not reach this function
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : April 4,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eHandleNetSysMsgDisconnection(tdstNetMessage *pstMes,tdeNetProtocol eProt,tduwNetChannel uwChannel)
|
||
{
|
||
NetLib_tdeErrorStatus eErrorReturned;
|
||
|
||
if ((pstMes->uxSessionId == gs_stCurrentSession.uxSessionId) &&
|
||
(pstMes->eMessageType ==E_Net_mt_SysDisconnection))
|
||
{
|
||
if(pstMes->uxRecipientId == NetLib_uxGetOwnPlayerId())
|
||
{/* the local player is the recipient*/
|
||
if ((gs_p_stPreSessionPlayerInfo)&&
|
||
(pstMes->uxSenderId == M_ulNetPlayerIdSlot(gs_p_stPreSessionPlayerInfo)))
|
||
{
|
||
/*The player cancels its connection request*/
|
||
|
||
/* Close the communication medium :*/
|
||
eLevel1DisconnectRemotePlayer(M_ulNetPlayerIdSlot(gs_p_stPreSessionPlayerInfo));
|
||
/*Clear the information about the player*/
|
||
vFree((tdpPointer)gs_p_stPreSessionPlayerInfo->pPlayerDescriptionData);
|
||
vFree((tdpPointer)gs_p_stPreSessionPlayerInfo);
|
||
gs_p_stPreSessionPlayerInfo = (NetLib_tdstPlayerInfo*)C_pNull;
|
||
gs_tdePreSessionPlayerStatus = E_Net_ConRecSta_NONE;
|
||
}
|
||
else
|
||
{
|
||
if (uwNetGetPlayerIndex(pstMes->uxSenderId) != NetLib_C_uwInvalidPosition)
|
||
{
|
||
eNetDisconnectPlayer(pstMes->uxSenderId, 1);
|
||
}
|
||
}
|
||
|
||
vFree(pstMes);
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
else
|
||
{/* the local player is not the recipient*/
|
||
if((eErrorReturned = eLevel1RouteSysMsg(pstMes,eProt,uwChannel))!=NetLib_E_es_NoError)
|
||
vFree(pstMes);
|
||
return eErrorReturned;
|
||
}
|
||
}
|
||
else
|
||
{/* The message has a bad type ?*/
|
||
vFree(pstMes);
|
||
return NetLib_E_es_ShouldNotReach;
|
||
}
|
||
}
|
||
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description :eHandleNetSysMsgTimeDeltaRequest
|
||
Swap a E_Net_mt_SysTimeDeltaRequest msg and a E_Net_mt_SysTimeDeltaReply msg
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : a tdstNetIOSystemCell that contains the information about the message
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_NoError if no error occured
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : October 23,1996
|
||
Author : Albert PAIS
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Message body : a tdstNetPingMessage
|
||
-> ulTimeOfSender ->swap
|
||
-> ulTimeOfRecipient ->swap
|
||
-> ulScaleOfRecipient ->swap
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eSwapLittleBigEndianSysMsgTimeDeltaRequest(tdstNetMessage *pstMes,tdeNetProtocol eProt,tduwNetChannel uwChannel)
|
||
{
|
||
tdstNetPingMessage *p_stPingMsg;
|
||
|
||
p_stPingMsg = (tdstNetPingMessage *)(pstMes+1);
|
||
p_stPingMsg->ulTimeOfSender = M_NET_ulSwapLittleBigEndian(p_stPingMsg->ulTimeOfSender);
|
||
p_stPingMsg->ulTimeOfRecipient = M_NET_ulSwapLittleBigEndian(p_stPingMsg->ulTimeOfRecipient);
|
||
p_stPingMsg->ulScaleOfRecipient = M_NET_ulSwapLittleBigEndian(p_stPingMsg->ulScaleOfRecipient);
|
||
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description :NetLib_tdeErrorStatus eHandleNetSysMsgTimeDeltaRequest(tdstNetIOSystemCell*p_stIOSystCell)
|
||
Handles a timer value request
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : a tdstNetIOSystemCell that contains the information about the message
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_NoError if no error occured
|
||
another error condition if the reply could not be sent back
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : June 20,1996
|
||
Author : Benoit Germain
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eHandleNetSysMsgTimeDeltaRequest(tdstNetMessage *pstMes,tdeNetProtocol eProt,tduwNetChannel uwChannel)
|
||
{
|
||
NetLib_tdeErrorStatus eReturnValue;
|
||
tdstNetMessage *p_stRequestMessage;
|
||
unsigned short c_uwCurrentIndex;
|
||
|
||
/* retrieve the message itself */
|
||
p_stRequestMessage=pstMes;
|
||
|
||
/* Retrieves the index of the sender:*/
|
||
c_uwCurrentIndex = 0;
|
||
while ((c_uwCurrentIndex < gs_stCurrentSession.uwMaxNumberOfPlayers) &&
|
||
(M_ulNetPlayerIdSlot(&gs_stCurrentSession.d_stPlayerInfo[c_uwCurrentIndex])!=p_stRequestMessage->uxSenderId))
|
||
{
|
||
c_uwCurrentIndex ++;
|
||
}
|
||
|
||
/* If the local player is the recipient and the sender exists in the current session*/
|
||
if ((c_uwCurrentIndex < gs_stCurrentSession.uwMaxNumberOfPlayers)
|
||
&&(p_stRequestMessage->uxRecipientId == NetLib_uxGetOwnPlayerId()))
|
||
{
|
||
tdstNetPingMessage *p_stRepliedPing=(tdstNetPingMessage *)(p_stRequestMessage+1);
|
||
|
||
/* add our local time and scale in the body of the message, after the local time of the sender.
|
||
* we have to scale the time by the number of total expected retries of the caller because of
|
||
* the very large values the timer function can return. */
|
||
p_stRepliedPing->ulTimeOfRecipient=ulTimeInfoToLagUnits(g_pfn_ulNetGetTimeInfo(),gs_ulLocalTimeScale);
|
||
p_stRepliedPing->ulScaleOfRecipient=gs_ulLocalTimeScale;
|
||
/* the message is a reply to the request */
|
||
p_stRequestMessage->eMessageType=E_Net_mt_SysTimeDeltaReply;
|
||
p_stRequestMessage->uxRecipientId=p_stRequestMessage->uxSenderId;
|
||
p_stRequestMessage->uxSenderId=NetLib_uxGetOwnPlayerId();
|
||
p_stRequestMessage->uxPriority = NetLib_C_uxMaxPriority;
|
||
p_stRequestMessage->uxReplaceType = 0;
|
||
p_stRequestMessage->uxReplace = 1;
|
||
p_stRequestMessage->m_uxReadReceiptId = NetLib_C_ucNoReadReceipt;
|
||
/* try to send the message */
|
||
if(gs_ArtificialLatency)
|
||
eReturnValue = eInternetSimuSendMessage(p_stRequestMessage->uxSenderId, p_stRequestMessage);
|
||
else
|
||
eReturnValue = eLevel1SendMessage(p_stRequestMessage,E_Net_pr_InvalidProtocol,C_uwNetInvalidChannel);
|
||
|
||
if(eReturnValue==NetLib_E_es_NoError)
|
||
{
|
||
#if defined(NET_USE_DEBUG)
|
||
vDebugSI(Net_C_Debug_NetSer,"request recvd, reply sent, time",p_stRepliedPing->ulTimeOfRecipient);
|
||
#endif /* NET_USE_DEBUG */
|
||
}
|
||
|
||
/* if it failed, free the message */
|
||
if (eReturnValue != NetLib_E_es_NoError) vFree((tdpPointer) p_stRequestMessage);
|
||
|
||
/* return the error status */
|
||
return eReturnValue;
|
||
}
|
||
else /* route the message, because it is not ours */
|
||
{
|
||
eReturnValue = eLevel1RouteSysMsg(pstMes,eProt,uwChannel);
|
||
if(eReturnValue != NetLib_E_es_NoError) vFree(pstMes);
|
||
|
||
return eReturnValue;
|
||
}
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description :NetLib_tdeErrorStatus eHandleNetSysMsgTimeDeltaReply(tdstNetIOSystemCell*p_stIOSystCell)
|
||
Handles a timer value reply
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : a tdstNetIOSystemCell that contains the information about the message
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : NetLib_E_es_NoError if no error occured
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : June 20,1996
|
||
Author : Benoit Germain
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eHandleNetSysMsgTimeDeltaReply(tdstNetMessage *pstMes,tdeNetProtocol eProt,tduwNetChannel uwChannel)
|
||
{
|
||
NetLib_tdeErrorStatus eErrorReturned;
|
||
tdstNetMessage *p_stReplyMessage;
|
||
unsigned short uwTimedPlayerIndex;
|
||
unsigned long ulReceptionDate;
|
||
unsigned long ulHalfPingDelay;
|
||
tdstNetTimeDelta *pTimeDelta;
|
||
|
||
/* retrieve the message itself */
|
||
p_stReplyMessage = pstMes;
|
||
|
||
/* Retrieves the index of the sender :*/
|
||
uwTimedPlayerIndex = 0;
|
||
while ((uwTimedPlayerIndex < gs_stCurrentSession.uwMaxNumberOfPlayers) &&
|
||
(M_ulNetPlayerIdSlot(&gs_stCurrentSession.d_stPlayerInfo[uwTimedPlayerIndex])!=p_stReplyMessage->uxSenderId))
|
||
{
|
||
uwTimedPlayerIndex ++;
|
||
}
|
||
|
||
/* If the local player is the recipient and the sender exists in the current session*/
|
||
if ((uwTimedPlayerIndex < gs_stCurrentSession.uwMaxNumberOfPlayers)
|
||
&& (p_stReplyMessage->uxRecipientId == NetLib_uxGetOwnPlayerId()))
|
||
{
|
||
tdstNetPingMessage *p_stRepliedPing=(tdstNetPingMessage *)(p_stReplyMessage+1);
|
||
|
||
/* no handling if the delay calibration was not properly set up
|
||
* or if the reply arrives after the timeout */
|
||
if (!gs_d_stTimeDeltas || !gs_b_ucDeltaCalibrationIsEnabled) return NetLib_E_es_ShouldNotReach;
|
||
|
||
/* when did I get the answer back (expressed in universal lag units) ? */
|
||
ulReceptionDate=ulTimeInfoToLagUnits(g_pfn_ulNetGetTimeInfo(),gs_ulLocalTimeScale);
|
||
|
||
/* look for the related player delay */
|
||
for (uwTimedPlayerIndex=0;uwTimedPlayerIndex<gs_stCurrentSession.uwMaxNumberOfPlayers;uwTimedPlayerIndex++)
|
||
{
|
||
/* if we found the sender in the array of delays we are trying to compute */
|
||
if (gs_d_stTimeDeltas[uwTimedPlayerIndex].ulPlayerId == p_stReplyMessage->uxSenderId)
|
||
{
|
||
pTimeDelta=gs_d_stTimeDeltas+uwTimedPlayerIndex;
|
||
/* forth and back took that long (in universal lag units) */
|
||
ulHalfPingDelay=(ulReceptionDate - p_stRepliedPing->ulTimeOfSender)/2;
|
||
/* we got one more reply */
|
||
pTimeDelta->NumberOfRetries++;
|
||
/* store the latency we got (in universal lag units) */
|
||
pTimeDelta->ulLatency += ulHalfPingDelay;
|
||
/* we add the delay for a future average computation (keep it in universal lag units) */
|
||
pTimeDelta->dDeltaWithLocal+=((double)ulHalfPingDelay + (double)p_stRepliedPing->ulTimeOfSender - (double)p_stRepliedPing->ulTimeOfRecipient);
|
||
/* here is the total number of replies we got */
|
||
pTimeDelta->ulScaleOfRecipient = p_stRepliedPing->ulScaleOfRecipient;
|
||
#if defined(NET_USE_DEBUG)
|
||
vDebugSISISISI(Net_C_Debug_NetSer,"NumPing",p_stRepliedPing->numPing,
|
||
"TimRec",ulReceptionDate,"Half Ping",ulHalfPingDelay,
|
||
"TimRem",p_stRepliedPing->ulTimeOfRecipient);
|
||
vDebugSISI(Net_C_Debug_NetSer,"Delta",(ulHalfPingDelay + p_stRepliedPing->ulTimeOfSender - p_stRepliedPing->ulTimeOfRecipient),
|
||
"E-Md",p_stRepliedPing->ulTimeOfRecipient-p_stRepliedPing->ulTimeOfSender);
|
||
#endif /* NET_USE_DEBUG */
|
||
pTimeDelta->LastRetries=p_stRepliedPing->numPing;
|
||
break;
|
||
}
|
||
}
|
||
|
||
/* free the message because we no longer need it */
|
||
vFree((tdpPointer) p_stReplyMessage);
|
||
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
else /* route the message, because it is not ours */
|
||
{
|
||
eErrorReturned = eLevel1RouteSysMsg(pstMes,eProt,uwChannel);
|
||
if(eErrorReturned != NetLib_E_es_NoError) vFree(pstMes);
|
||
return eErrorReturned;
|
||
}
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description :eSwapLittleBigEndianSysMsgDisconnectRemotePlayer
|
||
Swap E_Net_mt_SysDisconnectRemotePlayer message
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : a pointer to the tdstNetIOSystemCell
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : A NetLib_tdeErrorStatus
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : October 23,96
|
||
Author : Albert Pais
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Message body : -> ulPlayerId -> swap
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eSwapLittleBigEndianSysMsgDisconnectRemotePlayer(tdstNetMessage *pstMes,tdeNetProtocol eProt,tduwNetChannel uwChannel)
|
||
{
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description :eHandleNetSysMsgDisconnectRemotePlayer
|
||
Handle a E_Net_mt_SysDisconnectRemotePlayer message
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : a pointer to the tdstNetIOSystemCell
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : A NetLib_tdeErrorStatus
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : September 16,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eHandleNetSysMsgDisconnectRemotePlayer(tdstNetMessage *pstMes,tdeNetProtocol eProt,tduwNetChannel uwChannel)
|
||
{
|
||
NetLib_tduxPlayerId ulPlayerId;
|
||
NetLib_tdstDoForAllDesc stDoForAllDesc;
|
||
NetLib_tdeErrorStatus eErrorReturned;
|
||
|
||
if(pstMes->uxRecipientId != NetLib_uxGetOwnPlayerId())
|
||
{/* the message must be routed*/
|
||
eErrorReturned = eLevel1RouteSysMsg(pstMes,eProt,uwChannel);
|
||
if(eErrorReturned != NetLib_E_es_NoError) vFree(pstMes);
|
||
return eErrorReturned;
|
||
}
|
||
|
||
/* Check if the player belongs to the session :*/
|
||
if(uwNetGetPlayerIndex(pstMes->uxSenderId)==NetLib_C_uwInvalidPosition)
|
||
{
|
||
vFree(pstMes);
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/* Retrieve the player concerned :*/
|
||
ulPlayerId = *((NetLib_tduxPlayerId*)(pstMes + 1));
|
||
vFree(pstMes);
|
||
|
||
if(uwNetGetPlayerIndex(ulPlayerId)!=NetLib_C_uwInvalidPosition)
|
||
{
|
||
|
||
/* If somebody disconnects us from the session, quit it :*/
|
||
/* that is call the callback for all players */
|
||
if(NetLib_uxGetOwnPlayerId()==ulPlayerId)
|
||
{
|
||
stDoForAllDesc.m_pfn_eForAll = eNetDisconnectPlayer;
|
||
stDoForAllDesc.m_lParameter = 1;
|
||
stDoForAllDesc.m_eGoOnCondition = NetLib_E_es_NoError;
|
||
stDoForAllDesc.m_ucIncludeLocal = NetLib_C_ucNotIncludeLocalPlayer;
|
||
eErrorReturned = NetLib_eDoForAllPlayers(&stDoForAllDesc);
|
||
if (gs_uwMode==NetLib_Mode_Direct) vNetSetSessionId(M_ulNetPlayerIdSlot(&gs_stCurrentSession.d_stPlayerInfo[gs_stCurrentSession.uwIndexOfLocalPlayer]));
|
||
}
|
||
|
||
/* call the callback for the disconnected player (possibly the local player) ...*/
|
||
|
||
eErrorReturned=eNetDisconnectPlayer(ulPlayerId, 1);
|
||
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
return NetLib_E_es_UnknownPlayerId;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description :eSwapLittleBigEndianSysMsgReadReceipt
|
||
Swap E_Net_mt_ReadReceipt message
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : a pointer to the tdstNetIOSystemCell
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : A NetLib_tdeErrorStatus
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : October 23,96
|
||
Author : Albert Pais
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Message body : -> ulReadReceiptId -> swap
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eSwapLittleBigEndianSysMsgReadReceipt(tdstNetMessage *pstMes,tdeNetProtocol eProt,tduwNetChannel uwChannel)
|
||
{
|
||
*((unsigned long *)(pstMes+1))=
|
||
M_NET_ulSwapLittleBigEndian(*((unsigned long *)(pstMes+1)));
|
||
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description :eHandleNetSysMsgReadReceipt
|
||
Handle E_Net_mt_ReadReceipt message
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : a pointer to the tdstNetIOSystemCell
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : A NetLib_tdeErrorStatus
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : October 17,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eHandleNetSysMsgReadReceipt(tdstNetMessage *pstMes,tdeNetProtocol eProt,tduwNetChannel uwChannel)
|
||
{
|
||
NetLib_tduxPlayerId uxSenderId;
|
||
NetLib_uxReadReceiptId ulReadReceiptId;
|
||
tdstNetInternalReadReceiptDesc *p_stInternalReadReceiptDesc;
|
||
tdstNetIter stIter;
|
||
NetLib_tdeErrorStatus eErrorReturned;
|
||
|
||
if(pstMes->uxRecipientId != NetLib_uxGetOwnPlayerId())
|
||
{/* the message must be routed*/
|
||
eErrorReturned = eLevel1RouteSysMsg(pstMes,eProt,uwChannel);
|
||
if(eErrorReturned != NetLib_E_es_NoError)
|
||
vFree(pstMes);
|
||
return eErrorReturned;
|
||
}
|
||
|
||
/* retrieve the read-receipt and sender id :*/
|
||
uxSenderId = pstMes->uxSenderId;
|
||
ulReadReceiptId = *((NetLib_uxReadReceiptId*)(pstMes + 1));
|
||
|
||
p_stInternalReadReceiptDesc=(tdstNetInternalReadReceiptDesc*)
|
||
pNetList2IterInit(&stIter,&gs_stReadReceiptList);
|
||
while (p_stInternalReadReceiptDesc)
|
||
{
|
||
if ((p_stInternalReadReceiptDesc->m_stReadReceiptDesc.m_uxReadReceiptId == ulReadReceiptId)
|
||
&&(p_stInternalReadReceiptDesc->m_p_stMessage->uxRecipientId == uxSenderId))
|
||
{ /* we have found the player :*/
|
||
/* call the callback with the success flag*/
|
||
if(p_stInternalReadReceiptDesc->m_stReadReceiptDesc.p_fnv_ReadReceiptCallback)
|
||
p_stInternalReadReceiptDesc->m_stReadReceiptDesc.p_fnv_ReadReceiptCallback(uxSenderId,
|
||
ulReadReceiptId,NetLib_C_ucReadReceiptSuccess,
|
||
p_stInternalReadReceiptDesc->m_stReadReceiptDesc.m_lCallbackParam);
|
||
/* remove the message :*/
|
||
eNetEraseInternalReadReceiptDesc(p_stInternalReadReceiptDesc);
|
||
pNetList2DeleteElem(&stIter);
|
||
break;
|
||
}
|
||
else p_stInternalReadReceiptDesc=(tdstNetInternalReadReceiptDesc*)pNetList2Next(&stIter);
|
||
}
|
||
vFree(pstMes);
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description :eSwapLittleBigEndianSysMsgMaxNbrOfPlayers
|
||
Swap E_Net_mt_MaxNbrOfPlayers message
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : a pointer to the tdstNetIOSystemCell
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : A NetLib_tdeErrorStatus
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : October 28,96
|
||
Author : Albert Pais
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Message body : -> uwNewNbrMax -> swap
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eSwapLittleBigEndianSysMsgMaxNbrOfPlayers(tdstNetMessage *pstMes,tdeNetProtocol eProt,tduwNetChannel uwChannel)
|
||
{
|
||
*((unsigned short*)(pstMes+1))=M_NET_uwSwapLittleBigEndian(*((unsigned short*)(pstMes+1)));
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description :eHandleNetSysMsgMaxNbrOfPlayers
|
||
Handles E_Net_mt_MaxNbrOfPlayers message
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input : a pointer to the tdstNetIOSystemCell
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output : A NetLib_tdeErrorStatus
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : October 28,96
|
||
Author : Albert Pais
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eHandleNetSysMsgMaxNbrOfPlayers(tdstNetMessage *pstMes,tdeNetProtocol eProt,tduwNetChannel uwChannel)
|
||
{
|
||
NetLib_tdeErrorStatus eErrorReturned;
|
||
|
||
if(pstMes->uxRecipientId != NetLib_uxGetOwnPlayerId())
|
||
{ /* the message must be routed*/
|
||
eErrorReturned = eLevel1RouteSysMsg(pstMes,eProt,uwChannel);
|
||
if(eErrorReturned != NetLib_E_es_NoError) vFree(pstMes);
|
||
return eErrorReturned;
|
||
}
|
||
|
||
eErrorReturned = eNetInternalChangeMaxNbrOfPlayers(*((unsigned short*)(pstMes+1)));
|
||
|
||
if ((pstMes->m_uxReadReceiptId!=NetLib_C_ucNoReadReceipt)
|
||
&&(eErrorReturned == NetLib_E_es_NoError))
|
||
/* if read-receipt required :*/
|
||
eNetSendReadReceiptMessage(pstMes);
|
||
|
||
vFree(pstMes);
|
||
return eErrorReturned;
|
||
}
|
||
/*
|
||
------------------------------------------------------------------------------------------
|
||
INTERNET SIMULATION DELAY
|
||
------------------------------------------------------------------------------------------
|
||
*/
|
||
NetLib_tdeErrorStatus eInternetSimuSendMessage(NetLib_tduxPlayerId uxRecipientId,tdstNetMessage *pstMessage)
|
||
{
|
||
tdstMsgInfo *p_stNewMsg;
|
||
tdstNetIter stIter;
|
||
|
||
pNetList2IterInit(&stIter,&gs_stPlayerSendingList);
|
||
vNetList2ToEnd(&stIter);
|
||
p_stNewMsg=(tdstMsgInfo *)pNetList2ReservElem(&stIter,sizeof(tdstMsgInfo));
|
||
if(!p_stNewMsg) return NetLib_E_es_NotEnoughMemory;
|
||
p_stNewMsg->m_ulSendingTime = g_pfn_ulNetGetTimeInfo()+gs_ulInternetDelay+g_pfn_ulNetRandom()%(gs_ulInternetRandom+1);
|
||
p_stNewMsg->m_p_stMessage = pstMessage;
|
||
p_stNewMsg->m_ulPlayerId = uxRecipientId;
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
NetLib_tdeErrorStatus eNetManageInternetDelay(void)
|
||
{
|
||
tdstMsgInfo *p_stNewMsg;
|
||
tdstNetIter stIter;
|
||
|
||
p_stNewMsg=(tdstMsgInfo *)pNetList2IterInit(&stIter,&gs_stPlayerSendingList);
|
||
while (p_stNewMsg)
|
||
{
|
||
if(g_pfn_ulNetGetTimeInfo() >= p_stNewMsg->m_ulSendingTime)
|
||
{
|
||
/* Its time to send the message :*/
|
||
eLevel1SendMessage(p_stNewMsg->m_p_stMessage,E_Net_pr_InvalidProtocol,C_uwNetInvalidChannel);
|
||
p_stNewMsg=(tdstMsgInfo *)pNetList2DeleteElem(&stIter);
|
||
}
|
||
else p_stNewMsg=(tdstMsgInfo *)pNetList2Next(&stIter);
|
||
}
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
TCP reconection.
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : 24/1/97
|
||
Author : David Fournier
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
|
||
static tdstTCPReconnectInterface gs_stReconnectInterface;
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_tdeErrorStatus vNetInitTCPReconnect(void)
|
||
Initialize TCP reconnect interface.
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
void vNetInitTCPReconnect(void)
|
||
{
|
||
gs_stReconnectInterface.pfn_eTCPReconnect=NULL;
|
||
gs_stReconnectInterface.pfn_eTCPGetPortAndAddress=NULL;
|
||
gs_stReconnectInterface.pfn_vTCPNewRouteKnown=NULL;
|
||
gs_stReconnectInterface.pfn_uwTCPGetNewReconnectChannel=NULL;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : tdstTCPReconnectInterface *pstNetGetTCPReconnectInterface(void)
|
||
Return TCP reconnect interface for initialisation.
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
tdstTCPReconnectInterface *pstNetGetTCPReconnectInterface(void)
|
||
{
|
||
return &gs_stReconnectInterface;
|
||
}
|
||
|
||
#pragma pack(push)
|
||
#pragma pack(1)
|
||
|
||
typedef struct
|
||
{
|
||
unsigned long AdrIP;
|
||
unsigned short NumPort;
|
||
}tdstTCPAddress;
|
||
|
||
#pragma pack(pop)
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_tdeErrorStatus eNetSendTCPAddress(void)
|
||
Sends own TCP adresse to other players for they can reconect us directly.
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus eNetSendTCPAddress(void)
|
||
{
|
||
tdstNetMessage *p_stMessage;
|
||
NetLib_tdeErrorStatus eErrorReturned;
|
||
tdstTCPAddress localTCPAddress;
|
||
if (!gs_stReconnectInterface.pfn_eTCPGetPortAndAddress) return NetLib_E_es_NoError;
|
||
if (gs_stReconnectInterface.pfn_eTCPGetPortAndAddress(&localTCPAddress.NumPort,&localTCPAddress.AdrIP)==NetLib_E_es_NoError)
|
||
{
|
||
if (localTCPAddress.NumPort!=0)
|
||
{
|
||
p_stMessage=(tdstNetMessage*)pMalloc(sizeof(tdstNetMessage)+sizeof(tdstTCPAddress));
|
||
if(!p_stMessage) return NetLib_E_es_NotEnoughMemory;
|
||
p_stMessage->eMessageType = E_Net_mt_TCPAddress;
|
||
p_stMessage->uxRecipientId=C_uxNetBroadcastId;
|
||
p_stMessage->uxSenderId=NetLib_uxGetOwnPlayerId();
|
||
p_stMessage->uwMessageSizeInBytes = sizeof(tdstTCPAddress);
|
||
p_stMessage->uxPriority = NetLib_C_uxMaxPriority;
|
||
p_stMessage->uxReplaceType = 0;
|
||
p_stMessage->uxReplace = 0;
|
||
p_stMessage->m_uxReadReceiptId = NetLib_C_ucNoReadReceipt;
|
||
*((tdstTCPAddress *)(p_stMessage+1))=localTCPAddress;
|
||
if(gs_ArtificialLatency) eErrorReturned=eInternetSimuSendMessage(C_uxNetBroadcastId,p_stMessage);
|
||
else eErrorReturned=eLevel1SendMessage(p_stMessage,E_Net_pr_InvalidProtocol,C_uwNetInvalidChannel);
|
||
|
||
if(eErrorReturned!=NetLib_E_es_NoError) vFree((tdpPointer)p_stMessage);
|
||
}
|
||
}
|
||
eErrorReturned=NetLib_E_es_NoError;
|
||
return eErrorReturned;
|
||
}
|
||
|
||
#pragma pack(push)
|
||
#pragma pack(1)
|
||
|
||
typedef struct
|
||
{
|
||
NetLib_tduxPlayerId IdPlayer;
|
||
char First;
|
||
}tdstTCPIsMe;
|
||
|
||
#pragma pack(pop)
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_tdeErrorStatus eNetSendTCPIsMe(void)
|
||
Send own Id on the new chanel for the remote player can update his rout table.
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus eNetSendTCPIsMe(tduwNetChannel uwChannel,char First)
|
||
{
|
||
tdstNetMessage *p_stMessage;
|
||
NetLib_tdeErrorStatus eErrorReturned;
|
||
tdstTCPIsMe IsMe;
|
||
|
||
IsMe.First=First;
|
||
IsMe.IdPlayer=NetLib_uxGetOwnPlayerId();
|
||
|
||
p_stMessage=(tdstNetMessage*)pMalloc(sizeof(tdstNetMessage)+sizeof(tdstTCPIsMe));
|
||
if(!p_stMessage) return NetLib_E_es_NotEnoughMemory;
|
||
p_stMessage->eMessageType = E_Net_mt_TCPIsMe;
|
||
p_stMessage->uwMessageSizeInBytes = sizeof(tdstTCPIsMe);
|
||
p_stMessage->uxPriority = NetLib_C_uxMaxPriority;
|
||
p_stMessage->uxReplaceType = 0;
|
||
p_stMessage->uxReplace = 0;
|
||
p_stMessage->uxSenderId=IsMe.IdPlayer;
|
||
p_stMessage->uxRecipientId=C_uxNetBroadcastId;
|
||
p_stMessage->m_uxReadReceiptId = NetLib_C_ucNoReadReceipt;
|
||
*((tdstTCPIsMe *)(p_stMessage+1))=IsMe;
|
||
eErrorReturned=eLevel1SendMessage(p_stMessage,E_Net_pr_Windows95TCPProtocol,uwChannel);
|
||
|
||
if(eErrorReturned!=NetLib_E_es_NoError)
|
||
{
|
||
vFree((tdpPointer)p_stMessage);
|
||
}
|
||
return eErrorReturned;
|
||
}
|
||
|
||
#pragma pack(push)
|
||
#pragma pack(1)
|
||
|
||
typedef struct
|
||
{
|
||
NetLib_tduxPlayerId IdSource;
|
||
NetLib_tduxPlayerId IdDest;
|
||
}tdstTCPSupRoute;
|
||
|
||
#pragma pack(pop)
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_tdeErrorStatus eNetSendTCPSupRoute(void)
|
||
Supprim a path in the broadcast table of all remote players.
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus eNetSendTCPSupRoute(NetLib_tduxPlayerId IdSource,NetLib_tduxPlayerId IdDest)
|
||
{
|
||
tdstNetMessage *p_stMessage;
|
||
NetLib_tdeErrorStatus eErrorReturned;
|
||
tdstTCPSupRoute *pSupRout;
|
||
|
||
p_stMessage=(tdstNetMessage*)pMalloc(sizeof(tdstNetMessage)+sizeof(tdstTCPSupRoute));
|
||
if(!p_stMessage) return NetLib_E_es_NotEnoughMemory;
|
||
p_stMessage->eMessageType = E_Net_mt_TCPSupRoute;
|
||
p_stMessage->uxRecipientId=C_uxNetBroadcastId;
|
||
p_stMessage->uxSenderId=NetLib_uxGetOwnPlayerId();
|
||
p_stMessage->uwMessageSizeInBytes = sizeof(tdstTCPSupRoute);
|
||
p_stMessage->uxPriority = NetLib_C_uxMaxPriority;
|
||
p_stMessage->uxReplaceType = 0;
|
||
p_stMessage->uxReplace = 0;
|
||
p_stMessage->m_uxReadReceiptId = NetLib_C_ucNoReadReceipt;
|
||
pSupRout=(tdstTCPSupRoute *)(p_stMessage+1);
|
||
pSupRout->IdSource=IdSource;
|
||
pSupRout->IdDest=IdDest;
|
||
if(gs_ArtificialLatency) eErrorReturned=eInternetSimuSendMessage(C_uxNetBroadcastId,p_stMessage);
|
||
else eErrorReturned=eLevel1SendMessage(p_stMessage,E_Net_pr_InvalidProtocol,C_uwNetInvalidChannel);
|
||
|
||
if(eErrorReturned!=NetLib_E_es_NoError) vFree((tdpPointer)p_stMessage);
|
||
return eErrorReturned;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description :eHandleNetSysMsgTCPAddress
|
||
Recept a demand of reconection direct with a TCP adress.
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eHandleNetSysMsgTCPAddress(tdstNetMessage *pstMes,tdeNetProtocol eProt,tduwNetChannel uwChannel)
|
||
{
|
||
tdstTCPAddress *remoteTCPAddress;
|
||
if (!gs_stReconnectInterface.pfn_eTCPReconnect)
|
||
{
|
||
vFree(pstMes);
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
if (vLevel1ExistBroadcastPath(NetLib_uxGetOwnPlayerId(),pstMes->uxSenderId))
|
||
{
|
||
vFree(pstMes);
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
remoteTCPAddress=(tdstTCPAddress *)(pstMes+1);
|
||
gs_stReconnectInterface.pfn_eTCPReconnect(remoteTCPAddress->NumPort,remoteTCPAddress->AdrIP);
|
||
vFree(pstMes);
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description :eHandleNetSysMsgTCPIsMe
|
||
Recept a demand of update the rout table for a player.
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eHandleNetSysMsgTCPIsMe(tdstNetMessage *pstMes,tdeNetProtocol eProt,tduwNetChannel uwChannel)
|
||
{
|
||
tdstTCPIsMe *pIsMe;
|
||
if (!gs_stReconnectInterface.pfn_vTCPNewRouteKnown)
|
||
{
|
||
vFree(pstMes);
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
pIsMe=(tdstTCPIsMe *)(pstMes+1);
|
||
eLevel1UpdateRouteOfPlayer(pstMes,eProt,uwChannel);
|
||
eNetSendTCPSupRoute(NetLib_uxGetOwnPlayerId(),pIsMe->IdPlayer);
|
||
if (pIsMe->First) eNetSendTCPIsMe(uwChannel,0);
|
||
if (gs_uwMode==NetLib_Mode_UBI) gs_stReconnectInterface.pfn_vTCPNewRouteKnown(uwChannel);
|
||
vFree(pstMes);
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description :eHandleNetSysMsgTCPSupRoute
|
||
Supprim a broadcast path in the broadcast table.
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eHandleNetSysMsgTCPSupRoute(tdstNetMessage *pstMes,tdeNetProtocol eProt,tduwNetChannel uwChannel)
|
||
{
|
||
tdstTCPSupRoute *pSupRout;
|
||
pSupRout=(tdstTCPSupRoute *)(pstMes+1);
|
||
vLevel1SupBroadcastPath(pSupRout->IdSource,pSupRout->IdDest);
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/*//////////////////////////////////////////////////////////////////////////////
|
||
Description : iNetEngineTCPReconect
|
||
Engine function : Handles getactive sessions.
|
||
//////////////////////////////////////////////////////////////////////////////*/
|
||
int _NET_CALLING_CONV_ iNetEngineTCPReconect(void)
|
||
{
|
||
tduwNetChannel uwChannel;
|
||
if (!gs_stReconnectInterface.pfn_uwTCPGetNewReconnectChannel) return 0;
|
||
uwChannel=gs_stReconnectInterface.pfn_uwTCPGetNewReconnectChannel();
|
||
if (uwChannel!=C_uwNetInvalidChannel) eNetSendTCPIsMe(uwChannel,1);
|
||
return 0;
|
||
}
|