Files
firestorm/Gameleap/code/mw4/Code/MW4/mreplay2.cpp
T
Cyd 2b8ca921cb Initial full mirror of c:\VWE (source + assets + toolchain + outputs) via Git LFS
Complete disaster-recovery snapshot: engine/game source, game data assets,
VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive.
Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false,
no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
2026-06-24 21:28:16 -05:00

1991 lines
56 KiB
C++

CMRPFull g_MRF;
extern DPSESSIONDESC2 CurrentSession;
extern DWORD MyDirectPlayID;
extern bool IAmTheServer;
extern bool InNetworkGame;
extern char GameNameBuffer[];
extern char PasswordBuffer[];
extern DWORD gInSecureGame;
extern ListOfNames* CurrentPlayers;
extern char *LocalIPAddress; // extern SCRIPTVAR_STR(LocalIPAddress);
extern int ConnectionIndex;
DWORD g_dwMR_Meta = 0xab9a655f;
DWORD g_dwMR_MetaOldA = 0xab9a654f;
bool g_bMRTest = false;
const char* g_pcszGameDataExtMR = ".mr";
#if !defined(SCRIPTCALLBACK)
#define SCRIPTCALLBACK(func) int __stdcall func( void * instance, int args, void * arg[])
#endif // !defined(SCRIPTCALLBACK)
#if !defined(FREE_PTR)
#define FREE_PTR(ptr) if ((void *)ptr) { gos_Free((void *)ptr); (ptr)=NULL; }
#endif // !defined(FREE_PTR)
extern bool g_bCOOP; // COin OPeration
extern void RegisterData(void);
extern void UnRegisterData(void);
extern SCRIPTCALLBACK(CancelDialup);
extern SCRIPTCALLBACK(PreConnect);
extern SCRIPTCALLBACK(LoadMPConnectionSettings);
extern SCRIPTCALLBACK(InitConnectionWizard);
extern void _stdcall gos_RealRemovePlayerFromGame( ListOfNames** pListOfPlayers, char* Name, DPID dpId );
extern void _stdcall gos_RealAddPlayerToGame( ListOfNames** pListOfPlayers, char* Name, DPID dpId );
extern void _stdcall CTCL_SetMissionParamsBy(void* pNMP, int nSize);
void __stdcall MRP_OnGameOpen(const char* pcszGameName, DWORD dwMyID, const char* pcszPlayer, const char* pcszPassword);
void __stdcall NET_AddPlayerToGame(void/*ListOfNames*/** pListOfPlayers, char* Name, DPID dpId);
void __stdcall NET_RemovePlayerFromGame(void/*ListOfNames*/** pListOfPlayers, char* Name, DPID dpId);
void __stdcall NET_AddRemoveConnection(bool bAdd, void* pConnection);
void __stdcall NET_SessionLost();
void* __stdcall MRP_NetInformation(gosNetInfo Info, DWORD Parameter, char* Name);
void __stdcall MRP_NetServerCommands(gos_NetCommands Command, DWORD Data1);
NetPacket* __stdcall MRP_NETGETMESSAGE();
bool _stdcall MRP_LOCALSENDNETMESSAGE(int message_type, void/*Stuff::MemoryStream*/* message);
void __stdcall MRP_BACKGROUNDTACK();
bool __stdcall MRP_NETSENDMESSAGE(NetPacket* Message);
#define STRING_SIZE 256
void _inline AllocString(char * &sptr)
{
sptr = (char *)gos_Malloc(STRING_SIZE);
sptr[0] = 0;
}
void _inline FreeString(char * &sptr)
{
FREE_PTR(sptr);
}
void __stdcall MRP_OnGameOpen(const char* pcszGameName, DWORD dwMyID, const char* pcszPlayer, const char* pcszPassword)
{
g_MRF.OnGameOpen(pcszGameName, dwMyID, pcszPlayer, pcszPassword);
}
void __stdcall NET_AddPlayerToGame(void/*ListOfNames*/** pListOfPlayers, char* Name, DPID dpId)
{
g_MRF.AddRemovePlayerToGame(MRP_ADD_PLAYER_NAME, Name, dpId);
}
void __stdcall NET_RemovePlayerFromGame(void/*ListOfNames*/** pListOfPlayers, char* Name, DPID dpId)
{
g_MRF.AddRemovePlayerToGame(MRP_REMOVE_PLAYER_NAME, Name, dpId);
}
void __stdcall NET_AddRemoveConnection(bool bAdd, void* pConnection)
{
g_MRF.AddRemoveConnection(bAdd, (Connection*)pConnection);
}
void __stdcall NET_SessionLost()
{
g_MRF.SessionLost();
}
void* __stdcall MRP_NetInformation(gosNetInfo Info, DWORD Parameter, char* Name)
{
return g_MRF.NetInformation(Info, Parameter, Name);
}
void __stdcall MRP_NetServerCommands(gos_NetCommands Command, DWORD Data1)
{
g_MRF.NetServerCommands(Command, Data1);
}
NetPacket* __stdcall MRP_NETGETMESSAGE()
{
return g_MRF.NetGetMessage();
}
bool _stdcall MRP_LOCALSENDNETMESSAGE(int message_type, void/*Stuff::MemoryStream*/* message)
{
return g_MRF.LocalSendNetMessage(message_type, *(Stuff::MemoryStream*)message);
}
void __stdcall MRP_BACKGROUNDTACK()
{
g_MRF.BackgroundTack();
}
bool __stdcall MRP_NETSENDMESSAGE(NetPacket* Message)
{
return true;
}
int SMRP::GetMemSize() const
{
return sizeof(SMRP) + m_nLen;
}
CMRPPack* AllocMRPPack(int nCount, PMRP* ppMRP)
{
CMRPPack* pMRPPack = (CMRPPack*)malloc(sizeof(CMRPPack) + sizeof(PMRP) * nCount);
pMRPPack->Construct(nCount, ppMRP);
return pMRPPack;
}
void FreeMRPPack(CMRPPack* pMRPPack)
{
if (pMRPPack) {
pMRPPack->Destruct();
free(pMRPPack);
}
}
void CMRPPack::Construct(int nCount, PMRP* ppMRP)
{
m_pPrev = NULL;
m_pNext = NULL;
m_fFrameTime = 0.0f;
m_nCount = nCount;
if (ppMRP)
memcpy(&m_pa[0], ppMRP, sizeof(PMRP) * nCount);
}
void CMRPPack::Destruct()
{
PMRP* ppStart = &m_pa[0];
PMRP* ppEnd = &m_pa[m_nCount];
while(ppEnd-- > ppStart) {
free(*ppEnd);
}
}
int CMRPPack::GetMemSize() const
{
int nSize = sizeof(CMRPPack);
for(int i = 0; i < m_nCount; i++) {
nSize += m_pa[i]->GetMemSize();
}
return nSize;
}
void CMRPPack::Save(Stuff::DynamicMemoryStream& mf)
{
mf.WriteBytes(&m_fFrameTime, sizeof(m_fFrameTime));
for(int i = 0; i < m_nCount; i++) {
PMRP pMRP = m_pa[i];
mf.WriteBytes(&pMRP->m_nCommand, sizeof(pMRP->m_nCommand));
mf.WriteBytes(&pMRP->m_nType, sizeof(pMRP->m_nType));
mf.WriteBytes(&pMRP->m_nLen, sizeof(pMRP->m_nLen));
mf.WriteBytes(pMRP->m_ba, pMRP->m_nLen);
}
}
void CMRPPack::Load(Stuff::MemoryStream& mf, DWORD dwMeta)
{
if (dwMeta != g_dwMR_MetaOldA) {
mf.ReadBytes(&m_fFrameTime, sizeof(m_fFrameTime));
}
for(int i = 0; i < m_nCount; i++) {
int nCommand;
int nType;
int nLen;
mf.ReadBytes(&nCommand, sizeof(nCommand));
mf.ReadBytes(&nType, sizeof(nType));
mf.ReadBytes(&nLen, sizeof(nLen));
PMRP pMRP = (PMRP)malloc(sizeof(SMRP) + nLen);
pMRP->m_nCommand = nCommand;
pMRP->m_nType = nType;
pMRP->m_nLen = nLen;
mf.ReadBytes(pMRP->m_ba, nLen);
m_pa[i] = pMRP;
}
}
CMRPPlayer::CMRPPlayer()
: m_pPrev(NULL), m_pNext(NULL), m_bBOT(false), m_strName(""), m_strClan(""), m_strScript(""), m_connection_id(0), m_pilotTeam(0), m_pilotDecals(0), m_teamDecals(0), m_mechChasisID(0), m_pilotSkins(0), m_tonnage(0), m_pBufVCM(NULL), m_vehicleCreateMessage(NULL)
{
}
CMRPPlayer::~CMRPPlayer()
{
if (m_vehicleCreateMessage) {
delete m_vehicleCreateMessage;
m_vehicleCreateMessage = NULL;
}
if (m_pBufVCM) {
free(m_pBufVCM);
m_pBufVCM = NULL;
}
}
int CMRPPlayer::GetMemSize() const
{
int nSize = sizeof(CMRPPlayer);
nSize += m_strName.GetLength() + 1;
nSize += m_strClan.GetLength() + 1;
nSize += m_strScript.GetLength() + 1;
nSize += m_vehicleCreateMessage->GetSize();
return nSize;
}
void CMRPPlayer::Save(Stuff::DynamicMemoryStream& mf)
{
mf.WriteBit(m_bBOT);
mf.WriteByteAlign();
mf << m_strName;
mf << m_strClan;
mf << m_strScript;
mf.WriteBytes(&m_connection_id, sizeof(m_connection_id));
mf.WriteBytes(&m_pilotTeam, sizeof(m_pilotTeam));
mf.WriteBytes(&m_pilotDecals, sizeof(m_pilotDecals));
mf.WriteBytes(&m_teamDecals, sizeof(m_teamDecals));
mf.WriteBytes(&m_mechChasisID, sizeof(m_mechChasisID));
mf.WriteBytes(&m_pilotSkins, sizeof(m_pilotSkins));
mf.WriteBytes(&m_tonnage, sizeof(m_tonnage));
// for bot only - start
mf << m_aiModel;
int n = m_vehicleCreateMessage->GetSize();
mf.WriteBytes(&n, sizeof(n));
mf.WriteBytes(m_pBufVCM, n);
}
void CMRPPlayer::Load(Stuff::MemoryStream& mf)
{
mf.ReadBit(m_bBOT);
mf.ReadByteAlign();
mf >> m_strName;
mf >> m_strClan;
mf >> m_strScript;
mf.ReadBytes(&m_connection_id, sizeof(m_connection_id));
mf.ReadBytes(&m_pilotTeam, sizeof(m_pilotTeam));
mf.ReadBytes(&m_pilotDecals, sizeof(m_pilotDecals));
mf.ReadBytes(&m_teamDecals, sizeof(m_teamDecals));
mf.ReadBytes(&m_mechChasisID, sizeof(m_mechChasisID));
mf.ReadBytes(&m_pilotSkins, sizeof(m_pilotSkins));
mf.ReadBytes(&m_tonnage, sizeof(m_tonnage));
// for bot only - start
mf >> m_aiModel;
int n;
mf.ReadBytes(&n, sizeof(n));
m_pBufVCM = (BYTE*)malloc(n);
mf.ReadBytes(m_pBufVCM, n);
m_vehicleCreateMessage = new MemoryStream(m_pBufVCM, n);
}
CMRPFull::CMRPFull()
: m_strGameName(""), m_dwMyDirectPlayID(0), m_strPlayer(""), m_strPassword(""),
m_bStarting(false), m_bStarted(false), m_bStopping(false), m_bStopped(false),
m_nMissionParamSize(0), m_pMissionParam(NULL), m_bTeamGame(false), m_pMRPPlayers(NULL), m_nCount(-1), m_fFrameTime(0.0), m_pMRPPackStart(NULL),
m_pCurMRPPack(NULL)
{
m_nBOTPlayers = 0;
m_nLoadingPlayers = 0;
m_nBroadCastPlayers = 0;
}
CMRPFull::~CMRPFull()
{
Reset();
}
MWApplication* CMRPFull::Check()
{
MWApplication* app = MWApplication::GetInstance();
if (app) {
if (app->networkingFlag) {
if (app->serverFlag)
return app;
}
}
return NULL;
}
bool CMRPFull::IsValidData() const
{
if (m_pMissionParam) {
if (m_pMRPPlayers) {
if (m_pMRPPackStart) {
return true;
}
}
}
return false;
}
void CMRPFull::Reset()
{
FreeString(LocalIPAddress);
m_bStarting = false;
m_bStarted = false;
m_bStopping = false;
m_bStopped = false;
while(m_pMRPPackStart) {
CMRPPack* pNext = m_pMRPPackStart->m_pNext;
FreeMRPPack(m_pMRPPackStart);
m_pMRPPackStart = pNext;
}
while(m_pMRPPlayers) {
CMRPPlayer* pNext = m_pMRPPlayers->m_pNext;
delete m_pMRPPlayers;
m_pMRPPlayers = pNext;
}
if (m_pMissionParam) {
delete [] m_pMissionParam;
m_pMissionParam = NULL;
}
m_strGameName = (const char*)NULL;
m_strPlayer = (const char*)NULL;
m_strPassword = (const char*)NULL;
m_nMissionParamSize = 0;
m_nBOTPlayers = 0;
m_nLoadingPlayers = 0;
m_nBroadCastPlayers = 0;
int i;
for(i = 0; i < m_nCount; i++) {
free(m_pa[i]);
}
m_nCount = -1;
m_fFrameTime = 0.0;
m_pCurMRPPack = NULL;
m_pLastDictionary = m_pLastDictionaryToBeSent = NULL;
}
bool CMRPFull::IsValid() const
{
if (m_bStarted && (m_nLoadingPlayers > 0) && m_pMRPPackStart) {
return true;
}
return false;
}
void CMRPFull::Loading()
{
}
void CMRPFull::Loaded()
{
}
void CMRPFull::PreRendering()
{
}
void CMRPFull::PreRendered()
{
}
void CMRPFull::Starting()
{
if (Check()) {
if (g_nMR == 1)
m_bStarting = true;
}
}
void CMRPFull::Started()
{
MWApplication* app = Check();
if (app) {
if (g_nMR == 1) {
NetMissionParameters::MWNetMissionParameters* params = app->GetLocalNetParams();
DynamicMemoryStream stream;
params->SaveParameters(&stream);
stream.WriteByteAlign();
stream.Rewind();
m_pMissionParam = new BYTE[stream.GetBufferBytesUsed()];
memcpy(m_pMissionParam, stream.GetPointer(), stream.GetBufferBytesUsed());
m_nMissionParamSize = stream.GetBufferBytesUsed();
m_bTeamGame = !!params->m_teamAllowed;
m_bStarted = true;
} else {
}
}
}
void CMRPFull::StartFrame()
{
MWApplication* app = Check();
if (app) {
if (g_nMR == 1) {
if (m_bStarted) {
MWMission* mission = Cast_Object(MWMission*, MWMission::GetInstance());
if (mission && (m_nCount == -1)) {
m_nCount++;
m_fFrameTime = mission->GetMissionTime();
}
}
} else {
}
}
}
void CMRPFull::StopFrame()
{
if (m_nCount != -1) {
MWApplication* app = Check();
if (app && (m_nCount > 0)) {
CMRPPack* pMRPPack = AllocMRPPack(m_nCount, &m_pa[0]);
if (m_pMRPPackStart) {
CMRPPack* p = m_pMRPPackStart;
while(p->m_pNext) {
p = p->m_pNext;
}
p->m_pNext = pMRPPack;
pMRPPack->m_pPrev = p;
} else {
m_pMRPPackStart = pMRPPack;
}
pMRPPack->m_fFrameTime = m_fFrameTime;
}
m_nCount = -1;
}
}
void CMRPFull::ReduceFrame()
{
}
void CMRPFull::Stopping()
{
if (g_nMR == 1) {
m_bStopping = true;
}
}
void CMRPFull::Stopped()
{
OnGameClose();
}
PMRPPlayer CMRPFull::AddMRPPlayer(bool bBOT)
{
PMRPPlayer p = NULL;
if (g_nMR == 1) {
MWApplication* app = Check();
if (app) {
if (g_nMR == 1) {
p = new CMRPPlayer();
PMRPPlayer pList = m_pMRPPlayers;
if (pList) {
while(pList->m_pNext) {
pList = pList->m_pNext;
}
pList->m_pNext = p;
p->m_pPrev = pList;
} else {
m_pMRPPlayers = p;
}
p->m_bBOT = bBOT;
if (bBOT) {
m_nBOTPlayers++;
} else {
if (!m_bStarted) {
if (m_bStarting) {
m_nBroadCastPlayers++;
} else {
m_nLoadingPlayers++;
}
}
}
}
}
}
return p;
}
PMRP CMRPFull::AddMRP(int nCommand, int nType, int nLen)
{
gosASSERT(g_nMR == 1);
if (m_nCount < 0) {
// should be frame started...
StartFrame();
}
PMRP pRet = (PMRP)malloc(sizeof(SMRP) + nLen);
pRet->m_nCommand = nCommand;
pRet->m_nType = nType;
pRet->m_nLen = nLen;
m_pa[m_nCount++] = pRet;
return pRet;
}
void CMRPFull::OnGameOpen(const char* pcszGameName, DWORD dwMyID, const char* pcszPlayer, const char* pcszPassword)
{
Reset();
g_nMR = 0;
if (!CTCL_IsConsole()) {
if (!g_bCOOP && CTCL_IsConsoleX()) {
gosASSERT(g_bIsServer);
if (g_nMissionReview)
g_nMR = 1;
} else {
if (g_bMRTest)
g_nMR = 1;
}
}
m_CurrentSession = CurrentSession;
m_strGameName = pcszGameName;
m_dwMyDirectPlayID = dwMyID;
m_strPlayer = pcszPlayer;
m_strPassword = pcszPassword;
}
void CMRPFull::OnGameClose()
{
if (g_nMR == 1) {
StopFrame();
m_bStopped = true;
DbgReport();
if (IsValidData()) {
char szFile[256];
if (!g_bCOOP && CTCL_IsConsoleX()) {
GetFileName4GUID(szFile, "c:", g_pcszGameDataSavePath, g_pcszGameDataExtMR, g_guidGameDatas);
if (SaveMR(szFile)) {
CTCL_SendFile(g_SysTime, g_guidGameDatas, 1);
}
} else {
if (g_bMRTest) {
GetFileName4GUID(szFile, "c:", g_pcszGameDataSavePath, g_pcszGameDataExtMR);
SaveMR(szFile);
}
}
}
} else if (g_nMR == 2) {
QuitReplay();
}
g_nMR = 0;
}
void CMRPFull::AddRemovePlayerToGame(int nCommand, char* Name, DPID dpId)
{
if (!Name)
Name = "";
#if defined(_DEBUG) && 0 // jcem - for MR test
{
char Buffer[128];
sprintf(Buffer, "Network::RoutePacket() Player(\"%s\") %s\n", Name, (nCommand == MRP_ADD_PLAYER_NAME) ? "Added": "Deleted");
OutputDebugString(Buffer);
}
#endif // _DEBUG && ...
/*
PMRP pMRP = AddMRP(nCommand, 0, strlen(Name) + 1);
SMRP_PLAYER_NAME& PN = pMRP->m_PlayerName[0];
PN.m_dpId = dpId;
strcpy(PN.m_szName, Name);
*/
}
void CMRPFull::AddRemoveConnection(bool bAdd, Connection* pConnection)
{
gosASSERT(pConnection);
#if defined(_DEBUG) && 0 // jcem - for MR test
{
char Buffer[128];
sprintf(Buffer, "Network::RoutePacket() Connection %s\n", bAdd ? "Added": "Deleted");
OutputDebugString(Buffer);
}
#endif // _DEBUG && ...
/*
PMRP pMRP = AddMRP(bAdd ? gosNet_PlayerAdded: gosNet_PlayerDeleted, 0, sizeof(DWORD));
pMRP->m_dpID = pConnection->GetNetworkAddress();
*/
}
void CMRPFull::SessionLost()
{
#if defined(_DEBUG) && 0 // jcem - for MR test
{
char Buffer[128];
sprintf(Buffer, "Network::RoutePacket() SessionLost\n");
OutputDebugString(Buffer);
}
#endif // _DEBUG && ...
/*
AddMRP(gosNet_GameEnded, 0, 0);
*/
}
void* CMRPFull::NetInformation(gosNetInfo Info, DWORD Parameter, char* Name)
{
gosASSERT(g_nMR == 2);
gosASSERT(InNetworkGame);
gosASSERT(IAmTheServer);
static char Buffer[256];
void* result=0;
switch( Info )
{
//
// Returns TRUE if in a networked game
//
case gos_Networking:
{
result=(void*)1;
return result;
}
//
// Returns TRUE if you created the game (FALSE=Joined)
//
case gos_GameSecure:
{
result=(void*)(CurrentSession.dwFlags&DPSESSION_SECURESERVER);
return result;
}
//
// Returns NULL or pointer to password string
//
case gos_GamePassword:
{
if( PasswordBuffer[0] )
result=PasswordBuffer;
return result;
}
//
// Returns TRUE if the host created the game as a secure game
//
case gos_AmITheServer:
{
result=(void*)1;
return result;
}
//
// Returns the number of player in the current game
//
case gos_NumberOfPlayers:
{
DWORD NumPlayers=0;
ListOfNames* pThis=CurrentPlayers;
while( pThis )
{
NumPlayers++;
pThis=pThis->pNext;
}
result=(void*)NumPlayers;
return result;
}
//
// Returns a char* for the ip address
//
case gos_MyIPAddress:
{
result=(void*)MyIPAddress;
return result;
}
//
// Returns a DWORD for this machines player NUMBER
//
case gos_MyID:
{
result=(void*)MyDirectPlayID;
return result;
}
//
// Returns a DWORD for the servers player NUMBER
//
case gos_ServerID:
{
if( Environment.NetworkGame && Connected )
result=(void*)DPID_SERVERPLAYER;
return result;
}
//
// Returns a DWORD for ALL players (broadcast)
//
case gos_AllID:
{
if( Environment.NetworkGame && Connected )
result=(void*)DPID_ALLPLAYERS;
return result;
}
//
// Returns a player ID for the player NUMBER passed in the parameter
//
case gos_PlayerID:
{
DWORD NumPlayers=0;
ListOfNames* pThis=CurrentPlayers;
while( pThis )
{
if( NumPlayers==Parameter )
{
result=(void*)pThis->Data;
break;
}
NumPlayers++;
pThis=pThis->pNext;
}
return result;
}
//
// Returns a NUMBER for the player ID passed in the parameter (or 0xffffffff if not found)
//
case gos_PlayerNumber:
{
result=(void*)0xffffffff;
DWORD NumPlayers=0;
ListOfNames* pThis=CurrentPlayers;
while( pThis )
{
if( pThis->Data==Parameter )
{
result=(void*)NumPlayers;
break;
}
NumPlayers++;
pThis=pThis->pNext;
}
return result;
}
//
// Returns a char* for the player NUMBER passed in the parameter
//
case gos_PlayerName:
{
result=(void*)"";
DWORD NumPlayers=0;
ListOfNames* pThis=CurrentPlayers;
while( pThis )
{
if( NumPlayers==Parameter )
{
result=(void*)pThis->Name;
}
NumPlayers++;
pThis=pThis->pNext;
}
return result;
}
//
// Returns if the game is currently locked
//
case gos_LockedStatus:
{
result=(void*)(CurrentSession.dwFlags&DPSESSION_JOINDISABLED ? 1 : 0);
return result;
}
//
// Returns number of packets sent in the past frame to the player NUMBER passed
//
case gos_PacketsSentLastFrame:
{
PacketLogging* pThis=pDebugPacketLog;
DWORD PlayerID=(DWORD)gos_NetInformation(gos_PlayerID);
DWORD Counter=0;
/*while( pThis )
{
if( CurrentFrameNumber-1==pThis->FrameNumber && PlayerID==pThis->ToID )
Counter++;
pThis=pThis->pNext;
}*/
result=(void*)Counter;
return result;
}
//
// Returns number of packets recieved in the past Frame from the player NUMBER passed
//
case gos_PacketsFromLastFrame:
{
PacketLogging* pThis=pDebugPacketLog;
DWORD PlayerID=(DWORD)gos_NetInformation(gos_PlayerID);
DWORD Counter=0;
/*while( pThis )
{
if( CurrentFrameNumber-1==pThis->FrameNumber && PlayerID==pThis->FromID )
Counter++;
pThis=pThis->pNext;
}*/
result=(void*)Counter;
return result;
}
//
// Returns number of bytes sent in the past Frame to the player NUMBER passed
//
case gos_BytesSentLastFrame:
{
PacketLogging* pThis=pDebugPacketLog;
DWORD PlayerID=(DWORD)gos_NetInformation(gos_PlayerID);
DWORD Counter=0;
/*while( pThis )
{
if( CurrentFrameNumber-1==pThis->FrameNumber && PlayerID==pThis->ToID )
Counter+=pThis->Size;
pThis=pThis->pNext;
}*/
result=(void*)Counter;
return result;
}
//
// Returns number of bytes recieved in the past Frame from the player NUMBER passed
//
case gos_BytesFromLastFrame:
{
PacketLogging* pThis=pDebugPacketLog;
DWORD PlayerID=(DWORD)gos_NetInformation(gos_PlayerID);
DWORD Counter=0;
/*while( pThis )
{
if( CurrentFrameNumber-1==pThis->FrameNumber && PlayerID==pThis->FromID )
Counter+=pThis->Size;
pThis=pThis->pNext;
}*/
result=(void*)Counter;
return result;
}
//
// Returns total number of bytes sent in the past Frame to the player NUMBER passed (including packet overhead)
//
case gos_BandwithSentLastFrame:
{
PacketLogging* pThis=pDebugPacketLog;
DWORD PlayerID=(DWORD)gos_NetInformation(gos_PlayerID);
DWORD Counter=0;
/*while( pThis )
{
if( CurrentFrameNumber-1==pThis->FrameNumber && PlayerID==pThis->ToID )
Counter+=pThis->Size+PACKET_OVERHEAD;
pThis=pThis->pNext;
}*/
result=(void*)Counter;
return result;
}
//
// Returns total number of bytes recieved in the past Frame from the player NUMBER passed (including packet overhead)
//
case gos_BandwithFromLastFrame:
{
PacketLogging* pThis=pDebugPacketLog;
DWORD PlayerID=(DWORD)gos_NetInformation(gos_PlayerID);
DWORD Counter=0;
/*while( pThis )
{
if( CurrentFrameNumber-1==pThis->FrameNumber && PlayerID==pThis->FromID )
Counter+=pThis->Size+PACKET_OVERHEAD;
pThis=pThis->pNext;
}*/
result=(void*)Counter;
return result;
}
//
// Returns number of packets lost from the player NUMBER passed (based on packet numbers and retries)
//
case gos_PacketsLostLastFrame:
{
return (void*)0;
}
//
// Returns the average ping time for any guaranteed packets sent in the last frame to the player NUMBER
//
case gos_LatencyLastFrame:
{
return (void*)0;
}
//
// Returns the number of packets still in the send queue
//
case gos_GetMessageSendQueue:
{
result=(void*)0;
return result;
}
//
// Returns the number of Games found on network (or 1 if in a network game)
//
case gos_NumberOfGames:
{
result=(void*)1;
return result;
}
//
// Returns the name of the Game with the parameter passed (If in a game, returns this games name)
//
case gos_NameOfGame:
{
result=(void*)"";
if( 0==Parameter )
result=(void*)CurrentSession.lpszSessionNameA;
return result;
}
//
// Returns true if the game name passed is passworded, Name=Game Name
//
case gos_IsGamePassworded:
{
result=(void*)((CurrentSession.dwFlags&DPSESSION_PASSWORDREQUIRED) ? 1 : 0);
return result;
}
//
// Returns true if the game name passed is secure, Name=Game Name
//
case gos_IsGameSecure:
{
result=(void*)((CurrentSession.dwFlags&DPSESSION_SECURESERVER) ? 1 : 0);
return result;
}
//
// Returns true if the game name passed is locked so no more players can enter, Name=Game Name
//
case gos_IsGameLocked:
{
result=(void*)((CurrentSession.dwFlags&DPSESSION_JOINDISABLED) ? 1 : 0);
return result;
}
//
// Returns maximum number of players in a game, Name=Game Name
//
case gos_MaxPlayersInGame:
{
result=(void*)CurrentSession.dwMaxPlayers;
return result;
}
//
// Returns a pointer to 16 bytes of information from the game, Name=Game Name (Games set this in Environment.NetGameInfo)
//
case gos_InformationAboutGame:
{
result=(void*)&CurrentSession.dwUser1;
return result;
}
//
// Returns number of players in a game, Name=Game Name (If in a game, returns player in this game)
//
case gos_NumberOfPlayersInGame:
{
result=gos_NetInformation(gos_NumberOfPlayers);
return result;
}
//
// Return players name - Parameter=Player #, Name=Game Name. (If in a game, returns players name in this game)
//
case gos_NameOfPlayersInGame:
{
result=gos_NetInformation(gos_PlayerName,Parameter);
return result;
}
//
// Returns the number of modems installed
//
case gos_NumberOfModems:
{
DWORD ModemNumber=0;
result=(void*)ModemNumber;
return result;
}
//
// Returns the name of the modem number passed
//
case gos_NameOfModem:
{
result=(void*)"";
return result;
}
//
// Returns the number of serial ports installed
//
case gos_NumberOfSerialPorts:
{
DWORD PortNumber=0;
result=(void*)PortNumber;
return result;
}
//
// Returns the name of the serial port number passed
//
case gos_NameOfSerialPort:
{
result=(void*)"";
return result;
}
/* To be added once UI queries required decided
//
// Returns the status of the ZoneTech matchmaking connect attempt for game server
// 0 is success, 1 not yet tried, 2 pending, 3 failed, 4 lost connection
//
case gos_GameRegistrationStatus:
{
DWORD status = 1;
IZoneAsync::STATUS actual =IZoneAsync::STATUS_FAILED;
if (g_pZMAsync)
{
g_pZMAsync->GetStatus(&actual);
switch (actual)
{
case IZoneAsync::STATUS_COMPLETED:
status =0;
break;
case IZoneAsync::STATUS_STARTING:
status = 2;
break;
default:
status = 3;
break;
}
}
return (void*) status;
}
//
// Returns the status of the ZoneTech matchmaking connect attempt for game joiner
// 0 is success, 1 not yet tried, 2 pending, 3 failed, 4 lost connection
//
case gos_GameBrowseStatus:
{
DWORD status = 1;
IZoneAsync::STATUS actual =IZoneAsync::STATUS_FAILED;
if (g_pZMAsync)
{
g_pZMAsync->GetStatus(&actual);
switch (actual)
{
case IZoneAsync::STATUS_COMPLETED:
status =0;
break;
case IZoneAsync::STATUS_STARTING:
status = 2;
break;
default:
status = 3;
break;
}
}
return (void*) status;
}
//
//
//
*/
#ifdef OUTBOUND_WINDOW
case gos_GetNumOutboudWindows:
OutboundWindow * pOW;
pOW = OutboundWindow::m_pHead;
int i;
i=0;
while (pOW)
{
i++;
pOW = pOW->m_pNext;
}
return (void *)i;
break;
case gos_GetOutboundWindowSize:
pOW = OutboundWindow::m_pHead;
while (pOW)
{
if (Parameter==0)
break;
Parameter--;
pOW = pOW->m_pNext;
}
if (Parameter != 0)
return (void *)-1;
return (void *)(pOW->m_NextPacketNumberToSend - pOW->m_LastPacketTheyReceived);
break;
case gos_GetOutboundWindowSizeDpid:
pOW=OutboundWindow::Find(Parameter);
if (pOW)
{
return (void *)(pOW->m_NextPacketNumberToSend - pOW->m_LastPacketTheyReceived);
}
return (void *)-10000;
break;
case gos_GetOB_NxtPkt2Send:
pOW = OutboundWindow::m_pHead;
while (pOW)
{
if (Parameter==0)
break;
Parameter--;
pOW = pOW->m_pNext;
}
if (Parameter != 0)
return (void *)-1;
return (void *)(pOW->m_NextPacketNumberToSend);
break;
case gos_GetOB_LstPktRcvd:
pOW = OutboundWindow::m_pHead;
while (pOW)
{
if (Parameter==0)
break;
Parameter--;
pOW = pOW->m_pNext;
}
if (Parameter != 0)
return (void *)-1;
return (void *)(pOW->m_LastPacketWeReceived);
break;
case gos_GetOB_LstPktTheyRcvd:
pOW = OutboundWindow::m_pHead;
while (pOW)
{
if (Parameter==0)
break;
Parameter--;
pOW = pOW->m_pNext;
}
if (Parameter != 0)
return (void *)-1;
return (void *)(pOW->m_LastPacketTheyReceived);
break;
#else
case gos_GetNumOutboudWindows:
case gos_GetOutboundWindowSize:
case gos_GetOB_NxtPkt2Send:
case gos_GetOB_LstPktRcvd:
case gos_GetOB_LstPktTheyRcvd:
return 0;
break;
#endif
default:
STOP(( "Unknown info %d",Info ));
}
return 0;
}
void CMRPFull::NetServerCommands(gos_NetCommands Command, DWORD Data1)
{
gosASSERT(g_nMR == 2);
switch( Command )
{
//
// Remove the player with PlayerID == Data1 from the game
//
case gos_Command_KillPlayer:
{
gosASSERT( InNetworkGame && IAmTheServer && Data1!=MyDirectPlayID ); // Not allowed to delete yourself like this
//wDestroyPlayer( dplay4, Data1 ); // Allow any ID - so players already dead / dieing don't cause an error
return;
}
//
// Datat1=1 to lock the game, 0=to unlock the game - no more players can join when a game is locked
//
case gos_Command_LockGame:
{
gosASSERT( InNetworkGame && IAmTheServer );
CurrentSession.dwFlags&=~(DPSESSION_JOINDISABLED|DPSESSION_NEWPLAYERSDISABLED);
if( Data1 )
CurrentSession.dwFlags|=DPSESSION_JOINDISABLED|DPSESSION_NEWPLAYERSDISABLED;
break;
}
//
// Updates the 'game data' from Environment.NetGameInfo - so players enumerating games can see the changes
//
case gos_Command_UpdateGameData:
{
gosASSERT( InNetworkGame && IAmTheServer );
break;
}
//
// Updates the number of maximum players allowed in a game from Environment.NetworkMaxPlayers
//
case gos_Commend_UpdateMaxPlayers:
{
gosASSERT( InNetworkGame && IAmTheServer );
CurrentSession.dwMaxPlayers=Environment.NetworkMaxPlayers;
break;
}
default:
STOP(( "Bad command" ));
}
}
NetPacket* CMRPFull::NetGetMessage()
{
gosASSERT(g_nMR == 2);
MWApplication* app = Check();
if (app && app->GetApplicationState() == ApplicationStateEngine::RunningGameState) {
}
return (NetPacket*)NULL;
}
bool CMRPFull::LocalSendNetMessage(int message_type, Stuff::MemoryStream& message)
{
if (g_nMR == 1) {
switch(message_type) {
case MWEntityManager::DictionaryIndexMessageID:
case MWEntityManager::WeaponBundleMessageID:
case MWApplication::ScoreFormatMessageID:
case MWApplication::ScoreMessageID:
SendMessage(message_type, &message);
return false;
default:
if ((MWEntityManager::DictionaryPage0MessageID <= message_type) && (message_type < MWEntityManager::DictionaryPageMaxMessageID)) {
SendMessage(message_type, &message);
return false;
}
break;
}
} else if (g_nMR == 2) {
switch(message_type) {
case MWApplication::RequestNewDictionaryMessageID:
if (m_pLastDictionary) {
m_pLastDictionaryToBeSent = m_pLastDictionary;
}
return false;
}
}
return true;
}
void CMRPFull::BackgroundTack()
{
gosASSERT(g_nMR == 2);
MWApplication* app = Check();
if (app) {
if (app->GetApplicationState() == ApplicationStateEngine::RunningGameState) {
MWEntityManager* pMWENTMGR = MWEntityManager::GetInstance();
if (m_pLastDictionaryToBeSent) {
PMRP pMRP = m_pLastDictionaryToBeSent;
m_pLastDictionaryToBeSent = NULL;
Stuff::MemoryStream message(&pMRP->m_ba[0], pMRP->m_nLen);
pMWENTMGR->UpdateClientEntites(1, pMRP->m_nType, &message);
return;
}
if (m_pCurMRPPack) {
MWMission* mission = Cast_Object(MWMission*, MWMission::GetInstance());
Scalar fFrameTime = mission->GetMissionTime();
if (m_pCurMRPPack->m_fFrameTime <= fFrameTime) {
int i;
for(i = 0; i < Maximum_Players; ++i)
{
if (app->servedConnectionData[i].clientLoaded) {
if (pMWENTMGR->serverController->waitingForRespawn[i]) {
Mech *vehicle = (Mech *)app->servedConnectionData[i].clientPlayer->vehicle; // pMWENTMGR->playerVehicle[i];
if (vehicle) {
pMWENTMGR->serverController->waitingForRespawn[i] = false;
Point3D trans;
YawPitchRoll rot;
vehicle->GetDeadReckonedNetworkPosition(trans, rot);
vehicle->ClearNetworkPosition();
LinearMatrix4D drop_position;
drop_position.BuildTranslation(trans);
drop_position.BuildRotation(rot);
vehicle->SetNewLocalToParent(drop_position);
vehicle->SyncMatrices(true);
Map::GetInstance()->UpdateZone(vehicle);
}
}
}
}
int nCount = m_pCurMRPPack->m_nCount;
for(i = 0; i < nCount; i++) {
PMRP pMRP = m_pCurMRPPack->m_pa[i];
switch(pMRP->m_nCommand) {
case 0:
{
Stuff::MemoryStream message(&pMRP->m_ba[0], pMRP->m_nLen);
switch(pMRP->m_nType)
{
case MWApplication::ScoreFormatMessageID:
case MWApplication::ScoreMessageID:
app->ReceiveDirectMessage(1, pMRP->m_nType, &message);
break;
default:
pMWENTMGR->UpdateClientEntites(1, pMRP->m_nType, &message);
if (pMRP->m_nType == MWEntityManager::DictionaryIndexMessageID) {
m_pLastDictionary = pMRP;
}
}
break;
}
case MRP_RESPAWNMESSAGEID:
{
Stuff::MemoryStream message(&pMRP->m_ba[0], pMRP->m_nLen);
int nIdx = pMRP->m_nType;
if (nIdx < 0) {
nIdx++;
nIdx = -nIdx; // lancemate...
app->lancemateConnectionData[nIdx].lancemateMech->respawnCount+=1;
app->RespawnLancemateMessageHandler(1, &message);
} else {
app->servedConnectionData[nIdx].clientPlayer->GetVehicle()->respawnCount += 1;
EntityManager::GetInstance()->SetPlayerReady(app->servedConnectionData[nIdx].clientPlayer->vehicle);
app->RespawnMessageHandler(1, &message);
}
break;
}
case MRP_FULLCONFIRM:
{
int nWritten = pMRP->m_nType;
Stuff::MemoryStream message(&pMRP->m_ba[0], pMRP->m_nLen);
int version = 0;
message.ReadBits(&version,8);
Dictionary *dictionary = pMWENTMGR->GetDictionaryManager(1)->GetDictionary(version);
if (dictionary != NULL)
{
int rate_type = pMWENTMGR->bitManager->GetUpdateRate(UpdateManager::MechPositionUpdateID, dictionary->dictionaryBandwidth).m_ActiveRate;
Scalar rate = DictionaryPage::CalculateSeconds(rate_type);
while(nWritten-- > 0) {
BYTE connectionID;
WORD localID;
message.ReadBits(&connectionID, 8);
message.ReadBits(&localID, 16);
ReplicatorID id(connectionID, localID);
Entity* pEntity = NULL;
Connection* con2 = Network::GetInstance()->GetConnection(id.connectionID);
if (con2 != NULL) {
Check_Object(con2);
pEntity = (Entity*)con2->FindReplicator(id);
if (pEntity && !pEntity->IsDerivedFrom(MechWarrior4::Mech::DefaultData)) {
pEntity = NULL;
}
}
if (pEntity) {
MechPositionUpdate::Decode(pEntity, &message, 0.0, 0.0f, 1, dictionary->debugDictionaryLevel, dictionary->dictionaryBandwidth, rate);
ExternalJumpJetUpdate::Decode(pEntity, &message, 0.0, 0.0f, 1, dictionary->debugDictionaryLevel, dictionary->dictionaryBandwidth, rate);
MechInternalDamageUpdate::Decode(pEntity, &message, 0.0, 0.0f, 1, dictionary->debugDictionaryLevel, dictionary->dictionaryBandwidth, rate);
} else {
MechPositionUpdate::Skip(&message, 0, 0.0, 1, dictionary->debugDictionaryLevel, dictionary->dictionaryBandwidth);
ExternalJumpJetUpdate::Skip(&message, 0, 0.0, 1, dictionary->debugDictionaryLevel, dictionary->dictionaryBandwidth);
MechInternalDamageUpdate::Skip(&message, 0, 0.0, 1, dictionary->debugDictionaryLevel, dictionary->dictionaryBandwidth);
}
message.ReadByteAlign();
}
}
break;
}
case MRP_MECHDAMAGETAKEN:
{
const SMRP_MECH_DAMAGETAKEN& t = pMRP->m_MDT[0];
ReplicatorID victim(t.m_bCon1, t.m_wLID1);
Connection *vicConn = Network::GetInstance()->GetConnection(victim.connectionID);
if (vicConn != 0)
{
Check_Object(vicConn);
Replicator* repVict = vicConn->FindReplicator(victim);
if (repVict)
{
ReplicatorID inflicting(t.m_bCon2, t.m_wLID2);
Connection *inflConn = Network::GetInstance()->GetConnection(inflicting.connectionID);
if (inflConn != 0)
{
Check_Object(inflConn);
Replicator* repInfl = inflConn->FindReplicator(inflicting);
if (repInfl)
{
// pass attacker and victim to spectator state engine
if ((t.m_damageType == BeamDamageType) || (t.m_damageType == MissileDamageType) || (t.m_damageType == ProjectileDamageType)) {
Mech_CheckDamage(repVict, repInfl);
}
}
}
}
}
}
}
}
m_pCurMRPPack = m_pCurMRPPack->m_pNext;
}
} else {
app->QueStopGame();
}
}
}
}
PMRP CMRPFull::SendMessage(int message_type, Stuff::MemoryStream *message, int nCommand/* = 0*/)
{
gosASSERT(g_nMR == 1);
PMRP pMRP;
if (message) {
message->WriteByteAlign();
message->Rewind();
int nLen = message->GetBufferBytesUsed();
const unsigned char* pSrc = (const unsigned char*)message->GetPointer();
pMRP = AddMRP(nCommand, message_type, nLen);
if (nLen > 0) {
memcpy(&pMRP->m_ba[0], pSrc, nLen);
}
} else {
pMRP = AddMRP(nCommand, message_type, 0);
}
return pMRP;
}
void g_MRF_MechDamageTaken(ReplicatorID id1, ReplicatorID id2, Stuff::Scalar damage_taken, int weaponID, int damageType)
{
g_MRF.MechDamageTaken(id1, id2, damage_taken, weaponID, damageType);
}
void CMRPFull::MechDamageTaken(ReplicatorID mech1, ReplicatorID mech2, Stuff::Scalar damage_taken, int weaponID, int damageType)
{
PMRP pMRP = AddMRP(MRP_MECHDAMAGETAKEN, 0, sizeof(SMRP_MECH_DAMAGETAKEN));
SMRP_MECH_DAMAGETAKEN& t = pMRP->m_MDT[0];
t.m_fDamage = damage_taken;
t.m_bCon1 = mech1.connectionID;
t.m_weaponID = weaponID;
t.m_wLID1 = mech1.localID;
t.m_bCon2 = mech2.connectionID;
t.m_damageType = damageType;
t.m_wLID2 = mech2.localID;
}
void _cdecl CMRPFull::SendCommand(int nCommand, ...)
{
}
void CMRPFull::DoReplay()
{
g_nMR = 2;
CTCL_SetGameState(_EGS_Preparing);
MWApplication* app = MWApplication::GetInstance();
g_pfn_NETINFORMATION = MRP_NetInformation;
g_pfn_NETSERVERCOMMANDS = MRP_NetServerCommands;
g_pfn_NETGETMESSAGE = MRP_NETGETMESSAGE;
g_pfn_BACKGROUNDTACK = MRP_BACKGROUNDTACK;
m_pCurMRPPack = m_pMRPPackStart;
m_pLastDictionary = NULL;
m_pLastDictionaryToBeSent = NULL;
g_pfn_NETSENDMESSAGE = MRP_NETSENDMESSAGE;
// see - CTCL_DoCreateGame() for full processing
// see - gos_NetStartGame
// store secure state
gInSecureGame=MWApplication::SecureNetGame; // true;
// initialize GameOS variables
gos_InitializeNetworking();
// get the ip address
//
UnRegisterData();
RegisterData();
AllocString(LocalIPAddress);
CancelDialup(NULL, 0, NULL);
LoadMPConnectionSettings(NULL, 0, NULL);
InitConnectionWizard(NULL, 0, NULL);
ConnectionIndex = 0;
PreConnect(NULL, 0, NULL);
// Mech4CreateGame -> gos_CreateGame -> InternalCreateGame
#ifdef OUTBOUND_WINDOW
OutboundWindow::CleanAll();
#endif
CurrentSession = m_CurrentSession;
MyDirectPlayID = m_dwMyDirectPlayID;
gosASSERT(m_strGameName.GetLength() > 0);
GUID guid = gos_GenerateUniqueGUID();
sprintf(GameNameBuffer, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
guid.Data1, guid.Data2, guid.Data3,
guid.Data4[0], guid.Data4[1],
guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]);
// strcpy(GameNameBuffer, m_strGameName);
if ((const char*)m_strPassword)
strcpy(PasswordBuffer, m_strPassword);
else
PasswordBuffer[0] = '\0';
InNetworkGame=1;
IAmTheServer=1;
// GetCurrentPlayers();
CMRPPlayer* pPlayer;
// find server
pPlayer = m_pMRPPlayers;
while(pPlayer->m_bBOT || (pPlayer->m_connection_id != 1)) {
pPlayer = pPlayer->m_pNext;
gosASSERT(pPlayer);
}
// add server...
gos_RealAddPlayerToGame(&CurrentPlayers, pPlayer->m_strName, MyDirectPlayID);
// see - CTCL_DoGame1st()
g_bIsServer = true;
app->networkingFlag = true;
app->serverFlag = true;
if (Network::GetInstance() == NULL)
{
gos_PushCurrentHeap(MechWarrior4::Heap);
Verify(!Network::GetInstance());
GlobalPointers::AddGlobalPointer(new Network, NetworkGlobalPointerIndex);
Register_Object(Network::GetInstance());
gos_PopCurrentHeap();
}
app->SaveServerOptions();
#if defined(LAB_ONLY)
MWGameInfo::g_lastGameType = MWGameInfo::g_currentGameType;
MWGameInfo::g_currentGameType = MWGameInfo::MultiServer;
#endif
//app->LoadServerOptions();
//app->SendRequestConnectionMessage();
for (int i = 0; i < Maximum_Lancemates; ++i)
{
app->lancemateConnectionData[i].Disconnect();
}
app->memoryDiffKiller.Init();
gosASSERT(MW4Shell::NetConnectedToServer(NULL, 0, NULL));
CTCL_InitMechDatas();
MW4Shell::Instance->InitNetworkScenarios(NULL, 0, (void**)NULL);
// see - CTCL_SetMissionParams();
CTCL_SetMissionParamsBy(m_pMissionParam, m_nMissionParamSize);
// MWApplication::AcceptConnectionMessageHandler(int connection, Stuff::MemoryStream *message)
// add bot !players
pPlayer = m_pMRPPlayers;
while(pPlayer) {
if (pPlayer->m_bBOT) {
MechWarrior4::LancemateConnectionData& lcd = app->lancemateConnectionData[pPlayer->m_connection_id];
lcd.lancemateConnected = true;
lcd.lancemateVehicleAccepted = true;
strcpy(lcd.lancemateName, pPlayer->m_strName);
strcpy(lcd.lancemateClan, pPlayer->m_strClan);
strcpy(lcd.scriptName, pPlayer->m_strScript);
lcd.aiModel = pPlayer->m_aiModel;
lcd.pilotTeam = pPlayer->m_pilotTeam;
//lcd.pilotDecals = pPlayer->m_pilotDecals;
//lcd.teamDecals = pPlayer->m_teamDecals;
lcd.mechChasisID = pPlayer->m_mechChasisID;
//lcd.pilotSkins = pPlayer->m_pilotSkins;
lcd.tonnage = pPlayer->m_tonnage;
//lcd.clientKey = 1000;
MemoryStream* pVCM = pPlayer->m_vehicleCreateMessage;
BYTE* pData = new BYTE[pVCM->GetSize()];
memcpy(pData, pVCM->GetPointer(), pVCM->GetSize());
lcd.lancemateCreateMessage = new MemoryStream(pData, pVCM->GetSize());
}
pPlayer = pPlayer->m_pNext;
}
// add players !bot
pPlayer = m_pMRPPlayers;
while(pPlayer) {
if (!pPlayer->m_bBOT) {
MechWarrior4::ServedConnectionData& scd = app->servedConnectionData[pPlayer->m_connection_id];
if (pPlayer->m_connection_id != 1) {
gos_RealAddPlayerToGame(&CurrentPlayers, pPlayer->m_strName, 0);
Network::GetInstance()->Set_nextConnectionID(pPlayer->m_connection_id);
Network::GetInstance()->net_AddPlayer(pPlayer->m_strName, pPlayer->m_connection_id);
}
gosASSERT(scd.clientConnected);
if (scd.clanName)
{
delete scd.clanName;
scd.clanName = NULL;
}
int clan_size = strlen(pPlayer->m_strClan) + 1;
scd.clanName = new char[clan_size];
strcpy(scd.clanName, pPlayer->m_strClan);
scd.clientVehicleAccepted = true;
scd.clientReady = true;
scd.clientSentScoreFormat = false;
scd.clientAllowTransfer = false;
scd.clientQuedForLaunch = true;
scd.pilotTeam = pPlayer->m_pilotTeam;
scd.pilotDecals = pPlayer->m_pilotDecals;
scd.teamDecals = pPlayer->m_teamDecals;
scd.mechChasisID = pPlayer->m_mechChasisID;
scd.pilotSkins = pPlayer->m_pilotSkins;
scd.tonnage = pPlayer->m_tonnage;
//scd.clientKey = 1000;
MemoryStream* pVCM = pPlayer->m_vehicleCreateMessage;
BYTE* pData = new BYTE[pVCM->GetSize()];
memcpy(pData, pVCM->GetPointer(), pVCM->GetSize());
scd.vehicleCreateMessage = new MemoryStream(pData, pVCM->GetSize());
}
pPlayer = pPlayer->m_pNext;
}
// see - CTCL_SetMechs();
// see - CTCL_CheckClientReady();
app->lastMapCRC = -1;
app->haveNetworkMap = true;
// see - CTCL_CheckServerReady()
// app->VerifyAllPlayerVehicles();
// void CTCL_StartGame(BOOL bRealLaunch -> false)
MW4Shell::Instance->EndAllScripts();
MW4Shell::Instance->currentShellRunning = MW4Shell::MainShellRunning; //MW4Shell::NoShellRunning;
MW4Shell::Instance->shellCommand = MW4Shell::StartNetworkGameCommand;
MW4Shell::Instance->shellStart = MW4Shell::MainShellStart;
// app->CTCL_CheckRunningStart();
// if (GetApplicationState() == ApplicationStateEngine::PreRenderState)
// CTCL_StartGame(TRUE);
}
void CMRPFull::QuitReplay()
{
gos_ShutdownNetwork();
g_pfn_NETSENDMESSAGE = NULL;
g_pfn_BACKGROUNDTACK = NULL;
m_pLastDictionaryToBeSent = NULL;
m_pLastDictionary = NULL;
m_pCurMRPPack = NULL;
g_pfn_NETGETMESSAGE = NULL;
g_pfn_NETSERVERCOMMANDS = NULL;
g_pfn_NETINFORMATION = NULL;
}
int CMRPFull::GetMemSize() const
{
int nSize = sizeof(CMRPFull);
nSize += m_strGameName.GetLength() + 1;
nSize += m_strPlayer.GetLength() + 1;
nSize += m_strPassword.GetLength() + 1;
nSize += m_nMissionParamSize;
CMRPPlayer* p1 = m_pMRPPlayers;
while(p1) {
nSize += p1->GetMemSize();
nSize += sizeof(int);
p1 = p1->m_pNext;
}
CMRPPack* p2 = m_pMRPPackStart;
while(p2) {
nSize += p2->GetMemSize();
nSize += sizeof(int);
nSize += p2->m_nCount;
p2 = p2->m_pNext;
}
return nSize;
}
void CMRPFull::DbgReport() const
{
#if 0
MString str;
char Buffer[128];
str = "";
sprintf(Buffer, "CMRPFull: %d, m_CurrentSession: %d, m_nMissionParamSize: %d\n", sizeof(CMRPFull), sizeof(m_CurrentSession), m_nMissionParamSize);
str += Buffer;
OutputDebugString(Buffer);
int nPlayersSize = 0;
CMRPPlayer* p1 = m_pMRPPlayers;
while(p1) {
nPlayersSize = p1->GetMemSize();
p1 = p1->m_pNext;
}
sprintf(Buffer, "nPlayersSize: %d, %f, m_nBOTPlayers: %d, m_nLoadingPlayers: %d\n", nPlayersSize, (1.0 * nPlayersSize) / (1.0 * (m_nBOTPlayers + m_nLoadingPlayers + m_nBroadCastPlayers)), m_nBOTPlayers, m_nLoadingPlayers);
str += Buffer;
OutputDebugString(Buffer);
int nMRPPacks = 0;
int nMRPPackSize = 0;
CMRPPack* p2 = m_pMRPPackStart;
while(p2) {
nMRPPackSize += p2->GetMemSize();
nMRPPacks++;
p2 = p2->m_pNext;
}
sprintf(Buffer, "nMRPPacks: %d, nMRPPackSize: %d, %f\n", nMRPPacks, nMRPPackSize, (1.0 * nMRPPackSize) / (1.0 * nMRPPacks));
str += Buffer;
OutputDebugString(Buffer);
Scalar f;
//(m_fFrameTime / 60): total = 1: f
// f = total * 60 / m_fFrameTime;
f = 60.0 * (nPlayersSize + nMRPPackSize) / m_fFrameTime;
f /= 1024.0;
sprintf(Buffer, "====\nTotalSize: %f kb, %f seconds(%f kb per minutes)\n", (1.0 * (nPlayersSize + nMRPPackSize)) / 1024.0, m_fFrameTime, f);
str += Buffer;
OutputDebugString(Buffer);
FILE* file = fopen("c:\\mr-info.txt", "wb");
if (file) {
fputs(str, file);
fclose(file);
}
#endif
}
bool CMRPFull::SaveMR(const char* pcszFile)
{
gosASSERT(pcszFile && pcszFile[0]);
FILE* f = fopen(pcszFile, "wb");
if (f) {
Stuff::DynamicMemoryStream mf(GetMemSize());
mf.WriteBytes(&g_dwMR_Meta, sizeof(g_dwMR_Meta));
mf.WriteBytes(&m_CurrentSession, sizeof(m_CurrentSession));
mf << m_strGameName;
mf.WriteBytes(&m_dwMyDirectPlayID, sizeof(m_dwMyDirectPlayID));
mf << m_strPlayer;
mf << m_strPassword;
mf.WriteBit(m_bStarting);
mf.WriteBit(m_bStarted);
mf.WriteBit(m_bStopping);
mf.WriteBit(m_bStopped);
mf.WriteBit(m_bTeamGame);
mf.WriteByteAlign();
mf.WriteBytes(&m_nMissionParamSize, sizeof(m_nMissionParamSize));
mf.WriteBytes(m_pMissionParam, m_nMissionParamSize);
mf.WriteBytes(&m_nBOTPlayers, sizeof(m_nBOTPlayers));
mf.WriteBytes(&m_nLoadingPlayers, sizeof(m_nLoadingPlayers));
mf.WriteBytes(&m_nBroadCastPlayers, sizeof(m_nBroadCastPlayers));
int n = m_nBOTPlayers + m_nLoadingPlayers + m_nBroadCastPlayers;
CMRPPlayer* p1 = m_pMRPPlayers;
while(n-- > 0) {
p1->Save(mf);
p1 = p1->m_pNext;
}
mf.WriteBytes(&m_fFrameTime, sizeof(m_fFrameTime));
CMRPPack* p2 = m_pMRPPackStart;
n = 0;
while(p2) {
n++;
p2 = p2->m_pNext;
}
mf.WriteBytes(&n, sizeof(n));
p2 = m_pMRPPackStart;
while(p2) {
mf.WriteBytes(&p2->m_nCount, sizeof(p2->m_nCount));
p2->Save(mf);
p2 = p2->m_pNext;
}
mf.WriteByteAlign();
fwrite(mf.GetStreamStart(), mf.GetBytesUsed(), 1, f);
fclose(f);
return true;
}
return false;
}
bool CMRPFull::LoadDefaultMR()
{
char szFile[256];
GetFileName4GUID(szFile, "c:", g_pcszGameDataSavePath, g_pcszGameDataExtMR);
return LoadMR(szFile);
}
bool CMRPFull::LoadMR(const char* pcszFile)
{
gosASSERT(pcszFile && pcszFile[0]);
bool bRet = false;
FILE* f = fopen(pcszFile, "rb");
if (f) {
Reset();
long lSize = _filelength(fileno(f));
BYTE* pBuf = (BYTE*)malloc(lSize);
fread(pBuf, lSize, 1, f);
MemoryStream mf(pBuf, lSize);
DWORD dwMeta;
mf.ReadBytes(&dwMeta, sizeof(dwMeta));
if ((dwMeta == g_dwMR_Meta) || (dwMeta == g_dwMR_MetaOldA)) {
mf.ReadBytes(&m_CurrentSession, sizeof(m_CurrentSession));
mf >> m_strGameName;
mf.ReadBytes(&m_dwMyDirectPlayID, sizeof(m_dwMyDirectPlayID));
mf >> m_strPlayer;
mf >> m_strPassword;
mf.ReadBit(m_bStarting);
mf.ReadBit(m_bStarted);
mf.ReadBit(m_bStopping);
mf.ReadBit(m_bStopped);
mf.ReadBit(m_bTeamGame);
mf.ReadByteAlign();
mf.ReadBytes(&m_nMissionParamSize, sizeof(m_nMissionParamSize));
m_pMissionParam = new BYTE[m_nMissionParamSize];
mf.ReadBytes(m_pMissionParam, m_nMissionParamSize);
mf.ReadBytes(&m_nBOTPlayers, sizeof(m_nBOTPlayers));
mf.ReadBytes(&m_nLoadingPlayers, sizeof(m_nLoadingPlayers));
mf.ReadBytes(&m_nBroadCastPlayers, sizeof(m_nBroadCastPlayers));
int n;
n = m_nBOTPlayers + m_nLoadingPlayers + m_nBroadCastPlayers;
CMRPPlayer* p1Last = NULL;
while(n-- > 0) {
CMRPPlayer* p1 = new CMRPPlayer;
if (p1Last) {
p1Last->m_pNext = p1;
p1->m_pPrev = p1Last;
} else {
m_pMRPPlayers = p1;
}
p1Last = p1;
p1->Load(mf);
}
mf.ReadBytes(&m_fFrameTime, sizeof(m_fFrameTime));
mf.ReadBytes(&n, sizeof(n));
CMRPPack* p2Last = NULL;
while(n-- > 0) {
int nCount;
mf.ReadBytes(&nCount, sizeof(nCount));
CMRPPack* p2 = AllocMRPPack(nCount, (PMRP*)NULL);
if (p2Last) {
p2Last->m_pNext = p2;
p2->m_pPrev = p2Last;
} else {
m_pMRPPackStart = p2;
}
p2Last = p2;
p2->Load(mf, dwMeta);
}
mf.Rewind();
bRet = true;
}
free(pBuf);
fclose(f);
//if (!bRet) {
// remove(pcszFile);
//}
return true;
}
return bRet;
}
Stuff::Scalar CMRPFull::EndMissionTime() const
{
Stuff::Scalar fTime = 0.0f;
CMRPPack* pMRPP = m_pMRPPackStart;
while(pMRPP) {
if (pMRPP->m_fFrameTime > fTime)
fTime = pMRPP->m_fFrameTime;
pMRPP = pMRPP->m_pNext;
}
if (fTime > m_fFrameTime)
return fTime + 0.5;
return m_fFrameTime + 0.5f;
}
void MRP_Setup()
{
g_pfn_ONGAMEOPEN = MRP_OnGameOpen;
g_pfn_ADDPLAYERTOGAME = NET_AddPlayerToGame;
g_pfn_REMOVEPLAYERFROMGAME = NET_RemovePlayerFromGame;
g_pfn_ADDREMOVE_CONNECTION = NET_AddRemoveConnection;
g_pfn_LOCALSENDNETMESSAGE = MRP_LOCALSENDNETMESSAGE;
g_nMR = 0;
}
void MRP_Cleanup()
{
g_MRF.Reset();
g_pfn_LOCALSENDNETMESSAGE = NULL;
g_pfn_ADDREMOVE_CONNECTION = NULL;
g_pfn_REMOVEPLAYERFROMGAME = NULL;
g_pfn_ADDPLAYERTOGAME = NULL;
g_pfn_ONGAMEOPEN = NULL;
}