Something went wrong. Try again.
the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
Something went wrong. Try again.
23 kB · 651 lines
C++
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651#include "stdafx.h"
#include "DQRNetworkManager.h"#include "PartyController.h"#include <collection.h>#include <ppltasks.h>#include <ws2tcpip.h>#include "..\Minecraft.World\StringHelpers.h"#include "base64.h"
#ifdef _DURANGO#include "..\Minecraft.World\DurangoStats.h"#endif
#include "ChatIntegrationLayer.h"
using namespace Concurrency;using namespace Windows::Foundation::Collections;
DQRNetworkManagerEventHandlers::DQRNetworkManagerEventHandlers(DQRNetworkManager *pDQRNet){ m_pDQRNet = pDQRNet;}
void DQRNetworkManagerEventHandlers::Setup(WXNRs::Session^ session){ try { m_dataReceivedToken = session->DataReceived += ref new Windows::Foundation::EventHandler<WXNRs::DataReceivedEventArgs^>(this, &DQRNetworkManagerEventHandlers::DataReceivedHandler); m_sessionStatusToken = session->SessionStatusUpdate += ref new Windows::Foundation::EventHandler<WXNRs::SessionStatusUpdateEventArgs^>(this, &DQRNetworkManagerEventHandlers::SessionStatusUpdateHandler); m_sessionAddressToken = session->SessionAddressDataChanged += ref new Windows::Foundation::EventHandler<WXNRs::SessionAddressDataChangedEventArgs^>(this, &DQRNetworkManagerEventHandlers::SessionAddressDataChangedHandler); m_addedSessionToken = session->AddedSessionAddress += ref new Windows::Foundation::EventHandler<WXNRs::AddedSessionAddressEventArgs^>(this, &DQRNetworkManagerEventHandlers::AddedSessionAddressHandler); m_removedSessionToken = session->RemovedSessionAddress += ref new Windows::Foundation::EventHandler<WXNRs::RemovedSessionAddressEventArgs^>(this, &DQRNetworkManagerEventHandlers::RemovedSessionAddressHandler); m_globalDataToken = session->GlobalSessionDataChanged += ref new Windows::Foundation::EventHandler<WXNRs::GlobalSessionDataChangedEventArgs^>(this, &DQRNetworkManagerEventHandlers::GlobalSessionDataChangedHandler); } catch(Platform::COMException^ ex) { // swallow exceptions } catch(...) { // swallow exceptions }}
void DQRNetworkManagerEventHandlers::Pulldown(WXNRs::Session^ session){ try { session->DataReceived -= m_dataReceivedToken; session->SessionStatusUpdate -= m_sessionStatusToken; session->SessionAddressDataChanged -= m_sessionAddressToken; session->AddedSessionAddress -= m_addedSessionToken; session->RemovedSessionAddress -= m_removedSessionToken; session->GlobalSessionDataChanged -= m_globalDataToken; } catch(Platform::COMException^ ex) { // swallow exceptions } catch(...) { // swallow exceptions }}
// This event handler is called directly by the realtime session layer, when data is received. We split this data into into data that is meant to be// handled internally by the DQRNetworkManager, and that which is meant to be passed on to the game itself as communication between players.void DQRNetworkManagerEventHandlers::DataReceivedHandler(Platform::Object^ session, WXNRs::DataReceivedEventArgs^ args){// DQRNetworkManager::LogCommentFormat(L"DataReceivedHandler session addr: 0x%x (%d bytes)",args->SessionAddress,args->Data->Length);
if (session == m_pDQRNet->m_XRNS_Session) { EnterCriticalSection(&m_pDQRNet->m_csRTSMessageQueueIncoming); DQRNetworkManager::RTS_Message rtsMessage; if( args->ChannelId == WXNRs::ChannelId::DefaultChatReceive ) { rtsMessage.m_eType = DQRNetworkManager::eRTSMessageType::RTS_MESSAGE_DATA_RECEIVED_CHAT; } else { rtsMessage.m_eType = DQRNetworkManager::eRTSMessageType::RTS_MESSAGE_DATA_RECEIVED; } rtsMessage.m_sessionAddress = args->SessionAddress; rtsMessage.m_dataSize = args->Data->Length; rtsMessage.m_pucData = (unsigned char *)malloc(rtsMessage.m_dataSize); memcpy( rtsMessage.m_pucData, args->Data->Data, rtsMessage.m_dataSize ); m_pDQRNet->m_RTSMessageQueueIncoming.push(rtsMessage); LeaveCriticalSection(&m_pDQRNet->m_csRTSMessageQueueIncoming); }}
// This event handler is called by the realtime session layer, when session address data is updated. We don't currently use session address data.void DQRNetworkManagerEventHandlers::SessionAddressDataChangedHandler(Platform::Object^ session, WXNRs::SessionAddressDataChangedEventArgs^ args){ DQRNetworkManager::LogComment(L"SessionAddressDataChangedHandler");}
// This event handler is called by the realtime session layer when a session changes status. We use this to determine that a connection has been made made to the host,// and the case when a connection has been terminated.void DQRNetworkManagerEventHandlers::SessionStatusUpdateHandler(Platform::Object^ session, WXNRs::SessionStatusUpdateEventArgs^ args){ DQRNetworkManager::LogComment(L"SessionStatusUpdateHandler"); if (m_pDQRNet->m_XRNS_Session == session) { switch(args->NewStatus) { case WXNRs::SessionStatus::Active: { DQRNetworkManager::LogComment(L"Session active"); m_pDQRNet->m_XRNS_LocalAddress = m_pDQRNet->m_XRNS_Session->LocalSessionAddress; m_pDQRNet->m_XRNS_OldestAddress = m_pDQRNet->m_XRNS_Session->OldestSessionAddress; EnterCriticalSection(&m_pDQRNet->m_csRTSMessageQueueIncoming); DQRNetworkManager::RTS_Message rtsMessage; rtsMessage.m_eType = DQRNetworkManager::eRTSMessageType::RTS_MESSAGE_STATUS_ACTIVE; rtsMessage.m_sessionAddress = 0; rtsMessage.m_dataSize = 0; rtsMessage.m_pucData = 0; m_pDQRNet->m_RTSMessageQueueIncoming.push(rtsMessage); LeaveCriticalSection(&m_pDQRNet->m_csRTSMessageQueueIncoming); } break; case WXNRs::SessionStatus::Terminated: { DQRNetworkManager::LogComment(L"Session terminated"); EnterCriticalSection(&m_pDQRNet->m_csRTSMessageQueueIncoming); DQRNetworkManager::RTS_Message rtsMessage; rtsMessage.m_eType = DQRNetworkManager::eRTSMessageType::RTS_MESSAGE_STATUS_TERMINATED; rtsMessage.m_sessionAddress = 0; rtsMessage.m_dataSize = 0; rtsMessage.m_pucData = 0; m_pDQRNet->m_RTSMessageQueueIncoming.push(rtsMessage); LeaveCriticalSection(&m_pDQRNet->m_csRTSMessageQueueIncoming); } break; case WXNRs::SessionStatus::Activating: DQRNetworkManager::LogComment(L"Session activating"); break; case WXNRs::SessionStatus::Terminating: DQRNetworkManager::LogComment(L"Session terminating"); break; } }}
// This event is called from the realtime session layer to notify any clients that a new endpoint has been connected into the network mesh.void DQRNetworkManagerEventHandlers::AddedSessionAddressHandler(Platform::Object^ session, WXNRs::AddedSessionAddressEventArgs^ args){ DQRNetworkManager::LogCommentFormat(L"AddedSessionAddressHandler session address 0x%x",args->SessionAddress); EnterCriticalSection(&m_pDQRNet->m_csRTSMessageQueueIncoming); DQRNetworkManager::RTS_Message rtsMessage; rtsMessage.m_eType = DQRNetworkManager::eRTSMessageType::RTS_MESSAGE_ADDED_SESSION_ADDRESS; rtsMessage.m_sessionAddress = args->SessionAddress; rtsMessage.m_dataSize = 0; rtsMessage.m_pucData = 0; m_pDQRNet->m_RTSMessageQueueIncoming.push(rtsMessage); LeaveCriticalSection(&m_pDQRNet->m_csRTSMessageQueueIncoming);}
// This event is called from the realtime session layer to notify any clients that an endpoint has been removed from the network mesh.void DQRNetworkManagerEventHandlers::RemovedSessionAddressHandler(Platform::Object^ session, WXNRs::RemovedSessionAddressEventArgs^ args){ DQRNetworkManager::LogCommentFormat(L"RemovedSessionAddressHandler session address 0x%x", args->SessionAddress); EnterCriticalSection(&m_pDQRNet->m_csRTSMessageQueueIncoming); DQRNetworkManager::RTS_Message rtsMessage; rtsMessage.m_eType = DQRNetworkManager::eRTSMessageType::RTS_MESSAGE_REMOVED_SESSION_ADDRESS; rtsMessage.m_sessionAddress = args->SessionAddress; rtsMessage.m_dataSize = 0; rtsMessage.m_pucData = 0; m_pDQRNet->m_RTSMessageQueueIncoming.push(rtsMessage); LeaveCriticalSection(&m_pDQRNet->m_csRTSMessageQueueIncoming);}
// This event is called from the realtime session layer when session global data has been updated. We don't currently use global session data.void DQRNetworkManagerEventHandlers::GlobalSessionDataChangedHandler(Platform::Object^ session, WXNRs::GlobalSessionDataChangedEventArgs^ args){ DQRNetworkManager::LogComment(L"GlobalSessionDataChangedHandler");}
void DQRNetworkManager::UpdateRTSStats(){ Platform::Array<unsigned int> ^sessionAddresses = nullptr; try { sessionAddresses = m_XRNS_Session->GetAllRemoteSessionAddresses(WXNRs::RemoteSessionAddressStateOptions::All, WXNRs::RemoteSessionAddressConnectivityOptions::All); } catch(Platform::COMException^ ex) { // swallow exceptions } catch(...) { // swallow exceptions }
if( sessionAddresses ) { unsigned int totalBytes = 0; unsigned int totalSends = 0; for( unsigned int i = 0; i < sessionAddresses->Length; i++ ) { try { totalBytes += m_XRNS_Session->GetSendChannelOutstandingBytes(sessionAddresses->get(i), WXNRs::ChannelId::DefaultGameSend ); totalSends += m_XRNS_Session->GetSendChannelOutstandingSends(sessionAddresses->get(i), WXNRs::ChannelId::DefaultGameSend ); } catch(Platform::COMException^ ex) { // swallow exceptions } catch(...) { // swallow exceptions } } m_RTS_Stat_totalBytes = totalBytes; m_RTS_Stat_totalSends = totalSends; } else { m_RTS_Stat_totalBytes = 0; m_RTS_Stat_totalSends = 0; }}
void DQRNetworkManager::ProcessRTSMessagesIncoming(){ EnterCriticalSection(&m_csRTSMessageQueueIncoming); while(m_RTSMessageQueueIncoming.size() > 0 ) { RTS_Message message = m_RTSMessageQueueIncoming.front(); switch( message.m_eType ) { case eRTSMessageType::RTS_MESSAGE_DATA_RECEIVED: Process_RTS_MESSAGE_DATA_RECEIVED(message); break; case eRTSMessageType::RTS_MESSAGE_DATA_RECEIVED_CHAT: Process_RTS_MESSAGE_DATA_RECEIVED_CHAT(message); break; case eRTSMessageType::RTS_MESSAGE_ADDED_SESSION_ADDRESS: Process_RTS_MESSAGE_ADDED_SESSION_ADDRESS(message); break; case eRTSMessageType::RTS_MESSAGE_REMOVED_SESSION_ADDRESS: Process_RTS_MESSAGE_REMOVED_SESSION_ADDRESS(message); break; case eRTSMessageType::RTS_MESSAGE_STATUS_ACTIVE: Process_RTS_MESSAGE_STATUS_ACTIVE(message); break; case eRTSMessageType::RTS_MESSAGE_STATUS_TERMINATED: Process_RTS_MESSAGE_STATUS_TERMINATED(message); break; default: break; } m_RTSMessageQueueIncoming.pop(); } LeaveCriticalSection(&m_csRTSMessageQueueIncoming);};
void DQRNetworkManager::Process_RTS_MESSAGE_DATA_RECEIVED(RTS_Message &message){ DQRConnectionInfo *connectionInfo; if( m_isHosting ) { connectionInfo = m_sessionAddressToConnectionInfoMapHost[message.m_sessionAddress]; } else { connectionInfo = &m_connectionInfoClient; }
// Handle any header data, and actual data, in our stream. Data is as follows: // Byte 0 Byte 1 // fccsssss ssssssss // // Where: f is 0 if this is normal data send (to be passed up to the game), or is 1 if this is to be internally processed // cc is the channel number that the data belongs to (0 to 3 representing actual player indices) // sssssssssssss is the count of data bytes to follow (range 0 - 8191) BYTE *pNextByte = message.m_pucData; BYTE *pEndByte = pNextByte + message.m_dataSize; do { BYTE byte = *pNextByte; switch( connectionInfo->m_state ) { case DQRConnectionInfo::ConnectionState_HeaderByte0: connectionInfo->m_currentChannel = ( byte >> 5 ) & 3; connectionInfo->m_internalFlag = ( ( byte & 0x80 ) == 0x80 );
// Byte transfer mode. Bits 0-4 of this byte represent the upper 5 bits of our count of bytes to transfer... lower 8-bits will follow connectionInfo->m_bytesRemaining = ((int)( byte & 0x1f )) << 8; connectionInfo->m_state = DQRConnectionInfo::ConnectionState_HeaderByte1; connectionInfo->m_internalDataState = DQRConnectionInfo::ConnectionState_InternalHeaderByte; pNextByte++; break; case DQRConnectionInfo::ConnectionState_HeaderByte1: // Add in the lower 8 bits of our byte count, the upper 5 were obtained from the first header byte. connectionInfo->m_bytesRemaining |= byte;
// If there isn't any data following, then just go back to the initial state expecting another header byte. if( connectionInfo->m_bytesRemaining == 0 ) { connectionInfo->m_state = DQRConnectionInfo::ConnectionState_HeaderByte0; } else { connectionInfo->m_state = DQRConnectionInfo::ConnectionState_ReadBytes; } pNextByte++; break; case DQRConnectionInfo::ConnectionState_ReadBytes: // At this stage we can send up to connectionInfo->m_bytesRemaining bytes, or the number of bytes that we have remaining in the data received, whichever is lowest. int bytesInBuffer = (int)(pEndByte - pNextByte); int bytesToReceive = ( ( connectionInfo->m_bytesRemaining < bytesInBuffer ) ? connectionInfo->m_bytesRemaining : bytesInBuffer );
if( connectionInfo->m_internalFlag ) { BytesReceivedInternal(connectionInfo, message.m_sessionAddress, pNextByte, bytesToReceive ); } else { BytesReceived(connectionInfo->m_smallId[connectionInfo->m_currentChannel], pNextByte, bytesToReceive ); }
// Adjust counts and pointers pNextByte += bytesToReceive; connectionInfo->m_bytesRemaining -= bytesToReceive;
// Set state back to expect a header if there is no more data bytes to receive if( connectionInfo->m_bytesRemaining == 0 ) { connectionInfo->m_state = DQRConnectionInfo::ConnectionState_HeaderByte0; } break; } } while (pNextByte != pEndByte);
free(message.m_pucData);}
void DQRNetworkManager::Process_RTS_MESSAGE_DATA_RECEIVED_CHAT(RTS_Message &message){ if( m_chat ) { m_chat->OnIncomingChatMessage(message.m_sessionAddress, Platform::ArrayReference<BYTE>(message.m_pucData, message.m_dataSize) ); free(message.m_pucData); }}
void DQRNetworkManager::Process_RTS_MESSAGE_ADDED_SESSION_ADDRESS(RTS_Message &message){ if( m_chat ) { m_chat->OnNewSessionAddressAdded(message.m_sessionAddress); }
// New session address - add a mapping for it if( m_isHosting ) { auto it = m_sessionAddressToConnectionInfoMapHost.find(message.m_sessionAddress); DQRConnectionInfo *connectionInfo; if( it == m_sessionAddressToConnectionInfoMapHost.end() ) { connectionInfo = new DQRConnectionInfo();
m_sessionAddressToConnectionInfoMapHost[message.m_sessionAddress] = connectionInfo; } else { // This shouldn't happen as we should be removing mappings as session addresses are removed. connectionInfo = it->second; connectionInfo->Reset(); }
}}
void DQRNetworkManager::Process_RTS_MESSAGE_REMOVED_SESSION_ADDRESS(RTS_Message &message){ if( m_chat ) { m_chat->RemoveRemoteConsole(message.m_sessionAddress); }
if( m_isHosting ) { auto it = m_sessionAddressToConnectionInfoMapHost.find(message.m_sessionAddress); if( it != m_sessionAddressToConnectionInfoMapHost.end() ) { delete it->second; m_sessionAddressToConnectionInfoMapHost.erase(it); RemoveRoomSyncPlayersWithSessionAddress(message.m_sessionAddress); SendRoomSyncInfo(); } } else { // As the client, if we are disonnected from the host, then it is all over. Proceed as if leaving the room. if( message.m_sessionAddress == m_hostSessionAddress ) { LeaveRoom(); } }}
void DQRNetworkManager::Process_RTS_MESSAGE_STATUS_ACTIVE(RTS_Message &message){ // When we detect that the session has become active, we start sending unreliable packets, until we get some data back. This is because there is an issue with the // realtime session layer where it is telling us that the connection is active a bit to early, and it will disconnect if it receives a packet that must be reliable in this // state. if( !m_isHosting ) { m_firstUnreliableSendTime = 0; m_hostSessionAddress = m_XRNS_OldestAddress; // Also initialise the status of this connection m_connectionInfoClient.Reset(); SetState(DQRNetworkManager::DNM_INT_STATE_JOINING_SENDING_UNRELIABLE); }}
void DQRNetworkManager::Process_RTS_MESSAGE_STATUS_TERMINATED(RTS_Message &message){ if( m_state == DQRNetworkManager::DNM_INT_STATE_JOINING_WAITING_FOR_ACTIVE_SESSION ) { m_joinCreateSessionAttempts++; if( m_joinCreateSessionAttempts > DQRNetworkManager::JOIN_CREATE_SESSION_MAX_ATTEMPTS ) { SetState(DQRNetworkManager::DNM_INT_STATE_JOINING_FAILED); } else { SetState(DQRNetworkManager::DNM_INT_STATE_JOINING_GET_SDA); } }}
int DQRNetworkManager::_RTSDoWorkThread(void* lpParameter){ DQRNetworkManager *pDQR = (DQRNetworkManager *)lpParameter; return pDQR->RTSDoWorkThread();}
static const DWORD XRNS_TERMINATE_LOCAL_SESSION_FLAG_IMMEDIATE = 0x00000001;int DQRNetworkManager::RTSDoWorkThread(){ do { if( m_XRNS_Session ) { try { m_XRNS_Session->DoWork(20); } catch(Platform::COMException^ ex) { // swallow exceptions } catch(...) { // swallow exceptions } UpdateRTSStats(); } else { Sleep(20); } ProcessRTSMessagesOutgoing(); } while(true);}
void DQRNetworkManager::ProcessRTSMessagesOutgoing(){ EnterCriticalSection(&m_csRTSMessageQueueOutgoing); while(m_RTSMessageQueueOutgoing.size() > 0 ) { RTS_Message message = m_RTSMessageQueueOutgoing.front(); switch( message.m_eType ) { case eRTSMessageType::RTS_MESSAGE_START_CLIENT: Process_RTS_MESSAGE_START_CLIENT(message); break; case eRTSMessageType::RTS_MESSAGE_START_HOST: Process_RTS_MESSAGE_START_HOST(message); break; case eRTSMessageType::RTS_MESSAGE_TERMINATE: Process_RTS_MESSAGE_TERMINATE(message); break; case eRTSMessageType::RTS_MESSAGE_SEND_DATA: Process_RTS_MESSAGE_SEND_DATA(message); break; default: break; } m_RTSMessageQueueOutgoing.pop(); } LeaveCriticalSection(&m_csRTSMessageQueueOutgoing);};
void DQRNetworkManager::Process_RTS_MESSAGE_START_CLIENT(RTS_Message &message){ if( m_XRNS_Session ) { m_eventHandlers->Pulldown(m_XRNS_Session); // Close XRNS session try { m_XRNS_Session->TerminateLocalSession(XRNS_TERMINATE_LOCAL_SESSION_FLAG_IMMEDIATE); } catch(Platform::COMException^ ex) { // swallow exceptions } catch(...) { // swallow exceptions }
m_XRNS_Session = nullptr; }
m_XRNS_Session = ref new WXNRs::Session( m_localSocketAddress, m_remoteSocketAddress, MAX_PLAYERS_IN_TEMPLATE, 0); m_XRNS_Session->MinSendRate = 512000;
LogCommentFormat(L"connect retry period %d retries %d, data retry count %d, data retry timeout %d\n",m_XRNS_Session->ConnectRetryPeriod,m_XRNS_Session->MaxConnectRetries,m_XRNS_Session->MaxDataRetries,m_XRNS_Session->MinDataRetryTimeout);
m_XRNS_Session->MaxConnectRetries = 50; // 50 at 100ms intervals = 5 seconds of attempting to connect
m_eventHandlers->Setup(m_XRNS_Session);}
void DQRNetworkManager::Process_RTS_MESSAGE_START_HOST(RTS_Message &message){ m_XRNS_Session = ref new WXNRs::Session( m_localSocketAddress, MAX_PLAYERS_IN_TEMPLATE, 0); m_XRNS_Session->MinSendRate = 512000; m_XRNS_Session->MaxConnectRetries = 50; // 50 at 100ms intervals = 5 seconds of attempting to connect m_eventHandlers->Setup(m_XRNS_Session);}
void DQRNetworkManager::Process_RTS_MESSAGE_TERMINATE(RTS_Message &message){ if( m_XRNS_Session ) { m_eventHandlers->Pulldown(m_XRNS_Session); // Close XRNS session try { m_XRNS_Session->TerminateLocalSession(XRNS_TERMINATE_LOCAL_SESSION_FLAG_IMMEDIATE); } catch(Platform::COMException^ ex) { // swallow exceptions } catch(...) { // swallow exceptions }
m_XRNS_Session = nullptr; }}
void DQRNetworkManager::Process_RTS_MESSAGE_SEND_DATA(RTS_Message &message){ if( m_XRNS_Session ) { unsigned int sessionAddress = message.m_sessionAddress;
try { if( message.m_flags & eRTSFlags::RTS_MESSAGE_FLAG_BROADCAST_MODE ) { sessionAddress = m_XRNS_Session->LocalSessionAddress; }
m_XRNS_Session->Send( ( message.m_flags & eRTSFlags::RTS_MESSAGE_FLAG_GAME_CHANNEL ) ? WXNRs::ChannelId::DefaultGameSend : WXNRs::ChannelId::DefaultChatSend, ( message.m_flags & eRTSFlags::RTS_MESSAGE_FLAG_BROADCAST_MODE ) ? WXNRs::SendExceptionType::ExcludedAddresses : WXNRs::SendExceptionType::IncludedAddresses, Platform::ArrayReference<unsigned int>(&message.m_sessionAddress, 1), Platform::ArrayReference<BYTE>(message.m_pucData, message.m_dataSize), 0, ( message.m_flags & eRTSFlags::RTS_MESSAGE_FLAG_RELIABLE ) ? WXNRs::Send_Reliability::Reliable : WXNRs::Send_Reliability::NonReliable, ( message.m_flags & eRTSFlags::RTS_MESSAGE_FLAG_SEQUENTIAL ) ? WXNRs::Send_Sequence::Sequential : WXNRs::Send_Sequence::NonSequential, WXNRs::Send_Ack::AckNormal, ( message.m_flags & eRTSFlags::RTS_MESSAGE_FLAG_COALESCE ) ? WXNRs::Send_Coalesce::CoalesceDelay : WXNRs::Send_Coalesce::CoalesceNever, WXNRs::Send_MiscState::NoMiscState ); } catch(Platform::COMException^ ex) { // swallow exceptions } catch(...) { // swallow exceptions } } free(message.m_pucData);}
void DQRNetworkManager::RTS_StartCient(){ EnterCriticalSection(&m_csRTSMessageQueueOutgoing); RTS_Message message; message.m_eType = eRTSMessageType::RTS_MESSAGE_START_CLIENT; message.m_pucData = NULL; message.m_dataSize = 0; m_RTSMessageQueueOutgoing.push(message); LeaveCriticalSection(&m_csRTSMessageQueueOutgoing);}
void DQRNetworkManager::RTS_StartHost(){ EnterCriticalSection(&m_csRTSMessageQueueOutgoing); RTS_Message message; message.m_eType = eRTSMessageType::RTS_MESSAGE_START_HOST; message.m_pucData = NULL; message.m_dataSize = 0; m_RTSMessageQueueOutgoing.push(message); LeaveCriticalSection(&m_csRTSMessageQueueOutgoing);}
void DQRNetworkManager::RTS_Terminate(){ EnterCriticalSection(&m_csRTSMessageQueueOutgoing); RTS_Message message; message.m_eType = eRTSMessageType::RTS_MESSAGE_TERMINATE; message.m_pucData = NULL; message.m_dataSize = 0; m_RTSMessageQueueOutgoing.push(message); LeaveCriticalSection(&m_csRTSMessageQueueOutgoing);}
void DQRNetworkManager::RTS_SendData(unsigned char *pucData, unsigned int dataSize, unsigned int sessionAddress, bool reliable, bool sequential, bool coalesce, bool broadcastMode, bool gameChannel ){ EnterCriticalSection(&m_csRTSMessageQueueOutgoing); RTS_Message message; message.m_eType = eRTSMessageType::RTS_MESSAGE_SEND_DATA; message.m_pucData = (unsigned char *)malloc(dataSize); memcpy(message.m_pucData, pucData, dataSize); message.m_dataSize = dataSize; message.m_sessionAddress = sessionAddress; message.m_flags = 0; if( reliable ) message.m_flags |= eRTSFlags::RTS_MESSAGE_FLAG_RELIABLE; if( sequential ) message.m_flags |= eRTSFlags::RTS_MESSAGE_FLAG_SEQUENTIAL; if( coalesce ) message.m_flags |= eRTSFlags::RTS_MESSAGE_FLAG_COALESCE; if( broadcastMode ) message.m_flags |= eRTSFlags::RTS_MESSAGE_FLAG_BROADCAST_MODE; if( gameChannel ) message.m_flags |= eRTSFlags::RTS_MESSAGE_FLAG_GAME_CHANNEL; m_RTSMessageQueueOutgoing.push(message); LeaveCriticalSection(&m_csRTSMessageQueueOutgoing);}