void NatPunchthroughClient::SendOutOfBand(SystemAddress sa, MessageID oobId) { if (sa==UNASSIGNED_SYSTEM_ADDRESS) return; if (sa.GetPort()==0) return; RakNet::BitStream oob; oob.Write(oobId); oob.Write(sp.sessionId); // RakAssert(sp.sessionId<100); if (oobId==ID_NAT_ESTABLISH_BIDIRECTIONAL) oob.Write(sa.GetPort()); char ipAddressString[32]; sa.ToString(false, ipAddressString); rakPeerInterface->SendOutOfBand((const char*) ipAddressString,sa.GetPort(),(const char*) oob.GetData(),oob.GetNumberOfBytesUsed()); if (natPunchthroughDebugInterface) { sa.ToString(true,ipAddressString); char guidString[128]; sp.targetGuid.ToString(guidString); // server - diff = my time // server = myTime + diff RakNet::Time clockDifferential = rakPeerInterface->GetClockDifferential(sp.facilitator); RakNet::Time serverTime = RakNet::GetTime() + clockDifferential; if (oobId==ID_NAT_ESTABLISH_UNIDIRECTIONAL) natPunchthroughDebugInterface->OnClientMessage(RakNet::RakString("%I64d: %s: OOB ID_NAT_ESTABLISH_UNIDIRECTIONAL to guid %s, system address %s.\n", serverTime, TestModeToString(sp.testMode), guidString, ipAddressString)); else natPunchthroughDebugInterface->OnClientMessage(RakNet::RakString("%I64d: %s: OOB ID_NAT_ESTABLISH_BIDIRECTIONAL to guid %s, system address %s.\n", serverTime, TestModeToString(sp.testMode), guidString, ipAddressString)); } }
void NatPunchthroughClient::SendOutOfBand(SystemAddress sa, MessageID oobId) { if (sa==UNASSIGNED_SYSTEM_ADDRESS) return; if (sa.GetPort()==0) return; RakNet::BitStream oob; oob.Write(oobId); oob.Write(sp.sessionId); // RakAssert(sp.sessionId<100); if (oobId==ID_NAT_ESTABLISH_BIDIRECTIONAL) oob.Write(sa.GetPort()); char ipAddressString[32]; sa.ToString(false, ipAddressString); rakPeerInterface->SendOutOfBand((const char*) ipAddressString,sa.GetPort(),(const char*) oob.GetData(),oob.GetNumberOfBytesUsed()); if (natPunchthroughDebugInterface) { sa.ToString(true,ipAddressString); char guidString[128]; sp.targetGuid.ToString(guidString); if (oobId==ID_NAT_ESTABLISH_UNIDIRECTIONAL) natPunchthroughDebugInterface->OnClientMessage(RakNet::RakString("Sent OOB ID_NAT_ESTABLISH_UNIDIRECTIONAL to guid %s, system address %s.", guidString, ipAddressString)); else natPunchthroughDebugInterface->OnClientMessage(RakNet::RakString("Sent OOB ID_NAT_ESTABLISH_BIDIRECTIONAL to guid %s, system address %s.", guidString, ipAddressString)); } }
void NatPunchthroughClient::SendTTL(const SystemAddress &sa) { if (sa==UNASSIGNED_SYSTEM_ADDRESS) return; if (sa.GetPort()==0) return; char ipAddressString[32]; sa.ToString(false, ipAddressString); // TTL of 1 doesn't get past the router, 2 might hit the other system on a LAN rakPeerInterface->SendTTL(ipAddressString,sa.GetPort(), 2); }
void NatPunchthroughClient::OnNewConnection(const SystemAddress &systemAddress, RakNetGUID rakNetGUID, bool isIncoming) { (void) rakNetGUID; (void) isIncoming; // Try to track new port mappings on the router. Not reliable, but better than nothing. SystemAddress ourExternalId = rakPeerInterface->GetExternalID(systemAddress); if (ourExternalId!=UNASSIGNED_SYSTEM_ADDRESS && nextExternalPort==0) nextExternalPort=ourExternalId.GetPort(); /* unsigned int i; i=0; while (i < groupRequestsInProgress.Size()) { if (groupRequestsInProgress[i].guid==rakNetGUID) { groupRequestsInProgress.RemoveAtIndexFast(i); } else { i++; } } */ }
ACTIONSCRIPT_CALLABLE_FUNCTION(RoomsBrowserGFx3_RakNet, f2c_JoinByFilter) { if (pparams.GetArgCount()<1) return; RakNet::JoinByFilter_Func func; func.userName=loginUsername; func.gameIdentifier=titleName; func.roomMemberMode=RMM_ANY_PLAYABLE; bool roomIsFromServer=pparams[0].GetBool(); double roomGuid=pparams[1].GetNumber(); if (roomIsFromServer) { // See RoomTypes.h for other default columns func.query.AddQuery_NUMERIC( DefaultRoomColumns::GetColumnName(DefaultRoomColumns::TC_ROOM_ID), roomGuid); roomsPlugin->ExecuteFunc(&func); } else { SystemAddress sa; sa.FromString(pparams[2].GetString()); char ipPart[32]; sa.ToString(false,ipPart); rakPeer->Connect(ipPart,sa.GetPort(),0,0); } }
void CommandParserInterface::ReturnResult(SystemAddress res, const char *command, TransportInterface *transport, const SystemAddress &systemAddress) { char addr[128]; systemAddress.ToString(false,addr,static_cast<size_t>(128)); char addr2[128]; res.ToString(false,addr2,static_cast<size_t>(128)); transport->Send(systemAddress, "%s returned %s %s:%i\r\n", command,addr,addr2,res.GetPort()); }
void Router2::SendOOBFromRakNetPort(OutOfBandIdentifiers oob, BitStream *extraData, SystemAddress sa) { RakNet::BitStream oobBs; oobBs.Write((unsigned char)oob); if (extraData) { extraData->ResetReadPointer(); oobBs.Write(*extraData); } char ipAddressString[32]; sa.ToString(false, ipAddressString); rakPeerInterface->SendOutOfBand((const char*) ipAddressString,sa.GetPort(),(const char*) oobBs.GetData(),oobBs.GetNumberOfBytesUsed()); }
void FullyConnectedMesh2::ConnectToRemoteNewIncomingConnections(Packet *packet) { unsigned int count; RakNet::BitStream bsIn(packet->data, packet->length, false); bsIn.IgnoreBytes(sizeof(MessageID)); bsIn.Read(count); SystemAddress remoteAddress; RakNetGUID remoteGuid; char str[64]; for (unsigned int i=0; i < count; i++) { bsIn.Read(remoteAddress); bsIn.Read(remoteGuid); remoteAddress.ToString(false,str); rakPeerInterface->Connect(str,remoteAddress.GetPort(),connectionPassword.C_String(),(int) connectionPassword.GetLength()); } }
int Lobby2Client_Steam_Impl::RakNetSendTo( const char *data, int length, const SystemAddress &systemAddress ) { bool objectExists; unsigned int i = roomMembersByAddr.GetIndexFromKey(systemAddress, &objectExists); if (objectExists) { if (SteamNetworking()->SendP2PPacket(roomMembersByAddr[i].steamIDRemote, data, length, k_EP2PSendUnreliable)) return length; else return 0; } else if (systemAddress.GetPort()!=STEAM_UNUSED_PORT) { // return SocketLayer::SendTo_PC(s,data,length,systemAddress,_FILE_AND_LINE_); return -1; } return 0; }
void UDPForwarder::UpdateThreaded(void) { fd_set readFD; //fd_set exceptionFD; FD_ZERO(&readFD); // FD_ZERO(&exceptionFD); timeval tv; int selectResult; tv.tv_sec=0; tv.tv_usec=0; RakNet::TimeMS curTime = RakNet::GetTimeMS(); SOCKET largestDescriptor=0; DataStructures::DefaultIndexType i; // Remove unused entries i=0; while (i < forwardList.GetSize()) { if (curTime > forwardList[i]->timeLastDatagramForwarded && // Account for timestamp wrap curTime > forwardList[i]->timeLastDatagramForwarded+forwardList[i]->timeoutOnNoDataMS) { RakNet::OP_DELETE(forwardList[i],_FILE_AND_LINE_); forwardList.RemoveAtIndex(i,_FILE_AND_LINE_); } else i++; } if (forwardList.GetSize()==0) return; for (i=0; i < forwardList.GetSize(); i++) { #ifdef _MSC_VER #pragma warning( disable : 4127 ) // warning C4127: conditional expression is constant #endif FD_SET(forwardList[i]->socket, &readFD); // FD_SET(forwardList[i]->readSocket, &exceptionFD); if (forwardList[i]->socket > largestDescriptor) largestDescriptor = forwardList[i]->socket; } selectResult=(int) select((int) largestDescriptor+1, &readFD, 0, 0, &tv); char data[ MAXIMUM_MTU_SIZE ]; sockaddr_storage their_addr; sockaddr* sockAddrPtr; socklen_t sockLen; socklen_t* socketlenPtr=(socklen_t*) &sockLen; sockaddr_in *sockAddrIn; sockaddr_in6 *sockAddrIn6; SystemAddress receivedAddr; sockLen=sizeof(their_addr); sockAddrPtr=(sockaddr*) &their_addr; if (selectResult > 0) { DataStructures::Queue<ForwardEntry*> entriesToRead; ForwardEntry *forwardEntry; for (i=0; i < forwardList.GetSize(); i++) { forwardEntry = forwardList[i]; // I do this because I'm updating the forwardList, and don't want to lose FD_ISSET as the list is no longer in order if (FD_ISSET(forwardEntry->socket, &readFD)) entriesToRead.Push(forwardEntry,_FILE_AND_LINE_); } while (entriesToRead.IsEmpty()==false) { forwardEntry=entriesToRead.Pop(); const int flag=0; int receivedDataLen, len=0; receivedDataLen = recvfrom( forwardEntry->socket, data, MAXIMUM_MTU_SIZE, flag, sockAddrPtr, socketlenPtr ); if (receivedDataLen<0) { #if defined(_WIN32) && defined(_DEBUG) && !defined(_XBOX) && !defined(X360) DWORD dwIOError = WSAGetLastError(); if (dwIOError!=WSAECONNRESET && dwIOError!=WSAEINTR && dwIOError!=WSAETIMEDOUT) { LPVOID messageBuffer; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dwIOError, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), // Default language ( LPTSTR ) & messageBuffer, 0, NULL ); // something has gone wrong here... RAKNET_DEBUG_PRINTF( "recvfrom failed:Error code - %d\n%s", dwIOError, messageBuffer ); //Free the buffer. LocalFree( messageBuffer ); } #endif continue; } if (their_addr.ss_family==AF_INET) { sockAddrIn=(sockaddr_in *)&their_addr; sockAddrIn6=0; memcpy(&receivedAddr.address.addr4,sockAddrIn,sizeof(sockaddr_in)); // receivedAddr.address.addr4.sin_port=ntohs( sockAddrIn->sin_port ); } else { sockAddrIn=0; sockAddrIn6=(sockaddr_in6 *)&their_addr; memcpy(&receivedAddr.address.addr6,sockAddrIn6,sizeof(sockaddr_in6)); // receivedAddr.address.addr6.sin6_port=ntohs( sockAddrIn6->sin6_port ); } if (forwardEntry->srcAndDest.source.EqualsExcludingPort(receivedAddr) && forwardEntry->updatedSourcePort==false && forwardEntry->srcAndDest.dest.GetPort()!=receivedAddr.GetPort()) { forwardEntry->updatedSourcePort=true; if (forwardEntry->srcAndDest.source.GetPort()!=receivedAddr.GetPort()) { DataStructures::DefaultIndexType index; SrcAndDest srcAndDest(forwardEntry->srcAndDest.dest, forwardEntry->srcAndDest.source); index=forwardList.GetIndexOf(srcAndDest); forwardList.RemoveAtIndex(index,_FILE_AND_LINE_); forwardEntry->srcAndDest.source.SetPort(receivedAddr.GetPort()); forwardList.Push(forwardEntry,forwardEntry->srcAndDest,_FILE_AND_LINE_); } } if (forwardEntry->srcAndDest.source.EqualsExcludingPort(receivedAddr) && forwardEntry->srcAndDest.source.GetPort()==receivedAddr.GetPort()) { // Forward to dest len=0; if (forwardEntry->srcAndDest.dest.address.addr4.sin_family==AF_INET) { do { len = sendto( forwardEntry->socket, data, receivedDataLen, 0, ( const sockaddr* ) & forwardEntry->srcAndDest.dest.address.addr4, sizeof( sockaddr_in ) ); } while ( len == 0 ); } else { do { len = sendto( forwardEntry->socket, data, receivedDataLen, 0, ( const sockaddr* ) & forwardEntry->srcAndDest.dest.address.addr6, sizeof( sockaddr_in ) ); } while ( len == 0 ); } // printf("1. Forwarding after %i ms\n", curTime-forwardEntry->timeLastDatagramForwarded); forwardEntry->timeLastDatagramForwarded=curTime; } if (forwardEntry->srcAndDest.dest.EqualsExcludingPort(receivedAddr) && forwardEntry->updatedDestPort==false && forwardEntry->srcAndDest.source.GetPort()!=receivedAddr.GetPort()) { forwardEntry->updatedDestPort=true; if (forwardEntry->srcAndDest.dest.GetPort()!=receivedAddr.GetPort()) { DataStructures::DefaultIndexType index; SrcAndDest srcAndDest(forwardEntry->srcAndDest.source, forwardEntry->srcAndDest.dest); index=forwardList.GetIndexOf(srcAndDest); forwardList.RemoveAtIndex(index,_FILE_AND_LINE_); forwardEntry->srcAndDest.dest.SetPort(receivedAddr.GetPort()); forwardList.Push(forwardEntry,forwardEntry->srcAndDest,_FILE_AND_LINE_); } } if (forwardEntry->srcAndDest.dest.EqualsExcludingPort(receivedAddr) && forwardEntry->srcAndDest.dest.GetPort()==receivedAddr.GetPort()) { // Forward to source len=0; if (forwardEntry->srcAndDest.source.address.addr4.sin_family==AF_INET) { do { len = sendto( forwardEntry->socket, data, receivedDataLen, 0, ( const sockaddr* ) & forwardEntry->srcAndDest.source.address.addr4, sizeof( sockaddr_in ) ); } while ( len == 0 ); } else { do { len = sendto( forwardEntry->socket, data, receivedDataLen, 0, ( const sockaddr* ) & forwardEntry->srcAndDest.source.address.addr6, sizeof( sockaddr_in ) ); } while ( len == 0 ); } // printf("2. Forwarding after %i ms\n", curTime-forwardEntry->timeLastDatagramForwarded); forwardEntry->timeLastDatagramForwarded=curTime; } } } }
PluginReceiveResult Router2::OnReceive(Packet *packet) { SystemAddress sa; RakNet::BitStream bs(packet->data,packet->length,false); if (packet->data[0]==ID_ROUTER_2_INTERNAL) { switch (packet->data[1]) { case ID_ROUTER_2_QUERY_FORWARDING: { OnQueryForwarding(packet); return RR_STOP_PROCESSING_AND_DEALLOCATE; } case ID_ROUTER_2_REPLY_FORWARDING: { OnQueryForwardingReply(packet); return RR_STOP_PROCESSING_AND_DEALLOCATE; } case ID_ROUTER_2_REQUEST_FORWARDING: { if (debugInterface) { char buff[512]; char buff2[32]; packet->systemAddress.ToString(true,buff2); debugInterface->ShowDiagnostic(FormatStringTS(buff,"Got ID_ROUTER_2_REQUEST_FORWARDING on ip %s from %I64d, ", buff2,packet->guid.g)); } OnRequestForwarding(packet); return RR_STOP_PROCESSING_AND_DEALLOCATE; } case ID_ROUTER_2_INCREASE_TIMEOUT: { /// The routed system wants more time to stay alive on no communication, in case the router drops or crashes rakPeerInterface->SetTimeoutTime(rakPeerInterface->GetTimeoutTime(packet->systemAddress)+10000, packet->systemAddress); return RR_STOP_PROCESSING_AND_DEALLOCATE; } } } else if (packet->data[0]==ID_OUT_OF_BAND_INTERNAL && packet->length>=2) { switch (packet->data[1]) { case ID_ROUTER_2_REPLY_TO_SENDER_PORT: { RakNet::BitStream bsOut; bsOut.Write(packet->guid); SendOOBFromRakNetPort(ID_ROUTER_2_MINI_PUNCH_REPLY, &bsOut, packet->systemAddress); if (debugInterface) { char buff[512]; char buff2[32]; sa.ToString(false,buff2); debugInterface->ShowDiagnostic(FormatStringTS(buff,"Got ID_ROUTER_2_REPLY_TO_SENDER_PORT %i on address %s, replying with ID_ROUTER_2_MINI_PUNCH_REPLY at %s:%i\n", sa.GetPort(), buff2, _FILE_AND_LINE_)); // packet->systemAddress.ToString(true,buff2); // debugInterface->ShowDiagnostic(FormatStringTS(buff,"Got ID_ROUTER_2_REPLY_TO_SENDER_PORT on address %s (%I64d), " // "replying with ID_ROUTER_2_MINI_PUNCH_REPLY at %s:%i\n", buff2,packet->guid.g, __FILE__, __LINE__)); } return RR_STOP_PROCESSING_AND_DEALLOCATE; } case ID_ROUTER_2_REPLY_TO_SPECIFIED_PORT: { RakNet::BitStream bsOut; bsOut.Write(packet->guid); bs.IgnoreBytes(2); sa=packet->systemAddress; unsigned short port; bs.Read(port); sa.SetPort(port); RakAssert(sa.GetPort()!=0); SendOOBFromRakNetPort(ID_ROUTER_2_MINI_PUNCH_REPLY, &bsOut, sa); if (debugInterface) { char buff[512]; char buff2[32]; sa.ToString(false,buff2); debugInterface->ShowDiagnostic(FormatStringTS(buff,"Got ID_ROUTER_2_REPLY_TO_SPECIFIED_PORT %i on address %s, " "replying with ID_ROUTER_2_MINI_PUNCH_REPLY at %s:%i\n", sa.GetPort(), buff2, __FILE__, __LINE__)); } return RR_STOP_PROCESSING_AND_DEALLOCATE; } case ID_ROUTER_2_MINI_PUNCH_REPLY: OnMiniPunchReply(packet); return RR_STOP_PROCESSING_AND_DEALLOCATE; case ID_ROUTER_2_MINI_PUNCH_REPLY_BOUNCE: OnMiniPunchReplyBounce(packet); return RR_STOP_PROCESSING_AND_DEALLOCATE; } } else if (packet->data[0]==ID_ROUTER_2_FORWARDING_ESTABLISHED) { // printf("Got ID_ROUTER_2_FORWARDING_ESTABLISHED\n"); if (OnForwardingSuccess(packet)==false) return RR_STOP_PROCESSING_AND_DEALLOCATE; } else if (packet->data[0]==ID_ROUTER_2_REROUTED) { OnRerouted(packet); } else if (packet->data[0]==ID_CONNECTION_REQUEST_ACCEPTED) { unsigned int forwardingIndex; forwardedConnectionListMutex.Lock(); for (forwardingIndex=0; forwardingIndex < forwardedConnectionList.Size(); forwardingIndex++) { if (forwardedConnectionList[forwardingIndex].endpointGuid==packet->guid && forwardedConnectionList[forwardingIndex].weInitiatedForwarding) break; } if (forwardingIndex<forwardedConnectionList.Size()) { forwardedConnectionListMutex.Unlock(); // We connected to this system through a forwarding system // Have the endpoint take longer to drop us, in case the intermediary system drops RakNet::BitStream bsOut; bsOut.Write((MessageID)ID_ROUTER_2_INTERNAL); bsOut.Write((unsigned char) ID_ROUTER_2_INCREASE_TIMEOUT); rakPeerInterface->Send(&bsOut,HIGH_PRIORITY,RELIABLE,0,packet->guid,false); if (debugInterface) { char buff[512]; debugInterface->ShowDiagnostic(FormatStringTS(buff,"Got ID_CONNECTION_REQUEST_ACCEPTED, " "sending ID_ROUTER_2_INCREASE_TIMEOUT to the %I64d at %s:%i\n", packet->guid.g, __FILE__, __LINE__)); } // Also take longer ourselves rakPeerInterface->SetTimeoutTime(rakPeerInterface->GetTimeoutTime(packet->systemAddress)+10000, packet->systemAddress); } else { // ~Gwynn: Fix for Receive hanging up problem on Windows XP // See http://blog.delphi-jedi.net/2008/04/23/the-case-of-the-unexplained-dead-lock-in-a-single-thread/ for details forwardedConnectionListMutex.Unlock(); } } else if (packet->data[0]==ID_ROUTER_2_FORWARDING_NO_PATH) { if (packet->wasGeneratedLocally==false) return RR_STOP_PROCESSING_AND_DEALLOCATE; } return RR_CONTINUE_PROCESSING; }
void Bethesda::InitializeVaultMP(RakPeerInterface* peer, SystemAddress server, const string& name, const string& pwd, bool multiinst, unsigned int inittime) { Bethesda::password = pwd; Bethesda::multiinst = multiinst; Bethesda::inittime = inittime; Bethesda::modfiles.clear(); initialized = false; #ifdef VAULTMP_DEBUG Debug::SetDebugHandler("vaultmp"); debug.note("Vault-Tec Multiplayer Mod client debug log (", CLIENT_VERSION, ")"); debug.note("Connecting to server: ", server.ToString(), " (name: ", name.c_str(), ", password: "******"Visit www.vaultmp.com for help and upload this log if you experience problems with the mod."); debug.note("-----------------------------------------------------------------------------------------------------"); #endif GameFactory::Initialize(); API::Initialize(); GameFactory::Operate<Player>(GameFactory::Create<Player>(PLAYER_REFERENCE, PLAYER_BASE), [&name](Player* player) { player->SetEnabled(true); player->SetName(name); }); Network::Flush(); Network::ToggleDequeue(true); try { if (peer->Connect(server.ToString(false), server.GetPort(), DEDICATED_VERSION, sizeof(DEDICATED_VERSION), 0, 0, 3, 500, 0) == CONNECTION_ATTEMPT_STARTED) { bool query = true; while (query) { while (Network::Dispatch(peer)); for (Packet* packet = peer->Receive(); packet; peer->DeallocatePacket(packet), packet = peer->Receive()) { if (packet->data[0] == ID_DISCONNECTION_NOTIFICATION) query = false; else if (packet->data[0] == ID_CONNECTION_REQUEST_ACCEPTED) Game::server = peer->GetGuidFromSystemAddress(server); try { Network::Dispatch(peer, NetworkClient::ProcessPacket(packet)); } catch (...) { peer->DeallocatePacket(packet); Network::Dispatch(peer, NetworkClient::ProcessEvent(ID_EVENT_CLIENT_ERROR)); peer->CloseConnection(server, true, CHANNEL_SYSTEM, HIGH_PRIORITY); throw; } } if (!query) throw VaultException("Server closed connection").stacktrace(); if (initialized && !Interface::IsAvailable()) { Network::Dispatch(peer, NetworkClient::ProcessEvent(ID_EVENT_INTERFACE_LOST)); peer->CloseConnection(server, true, CHANNEL_SYSTEM, HIGH_PRIORITY); query = false; if (!Interface::HasShutdown()) throw VaultException("Interface lost, game closed unexpectedly").stacktrace(); } this_thread::sleep_for(chrono::milliseconds(1)); } } else throw VaultException("Could not establish connection to server").stacktrace(); } catch (...) { Bethesda::Terminate(peer); #ifdef VAULTMP_DEBUG debug.print("Network thread is going to terminate (ERROR)"); #endif throw; } Bethesda::Terminate(peer); #ifdef VAULTMP_DEBUG debug.print("Network thread is going to terminate (no error occured)"); #endif }
unsigned short SocketLayer::GetLocalPort(SOCKET s) { SystemAddress sa; GetSystemAddress(s,&sa); return sa.GetPort(); }
void Bethesda::InitializeVaultMP(RakPeerInterface* peer, SystemAddress server, string name, string pwd, unsigned char game, bool multiinst, bool steam) { Bethesda::game = game; Bethesda::password = pwd; Bethesda::multiinst = multiinst; Bethesda::steam = steam; Bethesda::savegame = Savegame(); Bethesda::modfiles.clear(); ZeroMemory(module, sizeof(module)); Game::game = game; initialized = false; #ifdef VAULTMP_DEBUG debug = new Debug((char*) "vaultmp"); debug->PrintFormat("Vault-Tec Multiplayer Mod client debug log (%s)", false, CLIENT_VERSION); debug->PrintFormat("Connecting to server: %s (name: %s, password: %s, game: %s)", false, server.ToString(), name.c_str(), pwd.c_str(), game == FALLOUT3 ? (char*) "Fallout 3" : (char*) "Fallout New Vegas"); debug->Print("Visit www.vaultmp.com for help and upload this log if you experience problems with the mod.", false); debug->Print("-----------------------------------------------------------------------------------------------------", false); //debug->PrintSystem(); API::SetDebugHandler(debug); VaultException::SetDebugHandler(debug); NetworkClient::SetDebugHandler(debug); Interface::SetDebugHandler(debug); Lockable::SetDebugHandler(debug); Reference::SetDebugHandler(debug); Object::SetDebugHandler(debug); Item::SetDebugHandler(debug); Container::SetDebugHandler(debug); Actor::SetDebugHandler(debug); Player::SetDebugHandler(debug); Game::SetDebugHandler(debug); GameFactory::SetDebugHandler(debug); //Network::SetDebugHandler(debug); #endif GameFactory::Initialize(game); API::Initialize(game); NetworkID id = GameFactory::CreateInstance(ID_PLAYER, PLAYER_REFERENCE, PLAYER_BASE); FactoryObject reference = GameFactory::GetObject(id); Player* self = vaultcast<Player>(reference); self->SetEnabled(true); self->SetName(name); GameFactory::LeaveReference(reference); Network::Flush(); Network::ToggleDequeue(true); try { if (peer->Connect(server.ToString(false), server.GetPort(), DEDICATED_VERSION, sizeof(DEDICATED_VERSION), 0, 0, 3, 500, 0) == CONNECTION_ATTEMPT_STARTED) { bool query = true; Packet* packet; while (query) { while (Network::Dispatch(peer)); for (packet = peer->Receive(); packet; peer->DeallocatePacket(packet), packet = peer->Receive()) { if (packet->data[0] == ID_DISCONNECTION_NOTIFICATION) query = false; else if (packet->data[0] == ID_CONNECTION_REQUEST_ACCEPTED) Game::server = peer->GetGuidFromSystemAddress(server); try { Network::Dispatch(peer, NetworkClient::ProcessPacket(packet)); } catch (...) { peer->DeallocatePacket(packet); Network::Dispatch(peer, NetworkClient::ProcessEvent(ID_EVENT_CLIENT_ERROR)); peer->CloseConnection(server, true, CHANNEL_SYSTEM, HIGH_PRIORITY); throw; } } if (!query) throw VaultException("Server closed connection"); if (initialized && !Interface::IsAvailable()) { Network::Dispatch(peer, NetworkClient::ProcessEvent(ID_EVENT_INTERFACE_LOST)); peer->CloseConnection(server, true, CHANNEL_SYSTEM, HIGH_PRIORITY); query = false; } this_thread::sleep_for(chrono::milliseconds(1)); } } else throw VaultException("Could not establish connection to server"); } catch (...) { Bethesda::Terminate(peer); #ifdef VAULTMP_DEBUG debug->Print("Network thread is going to terminate (ERROR)", true); #endif throw; } Bethesda::Terminate(peer); #ifdef VAULTMP_DEBUG debug->Print("Network thread is going to terminate (no error occured)", true); #endif }
void Bethesda::InitializeVaultMP( RakPeerInterface* peer, SystemAddress server, string name, string pwd, unsigned char game ) { Bethesda::game = game; Bethesda::password = pwd; Bethesda::savegame = Savegame(); Bethesda::modfiles.clear(); Game::game = game; initialized = false; #ifdef VAULTMP_DEBUG debug = new Debug( ( char* ) "vaultmp" ); debug->PrintFormat( "Vault-Tec Multiplayer Mod client debug log (%s)", false, CLIENT_VERSION ); debug->PrintFormat( "Connecting to server: %s (name: %s, password: %s, game: %s)", false, server.ToString(), name.c_str(), pwd.c_str(), game == FALLOUT3 ? ( char* ) "Fallout 3" : game == NEWVEGAS ? ( char* ) "Fallout New Vegas" : ( char* ) "TES Oblivion" ); debug->Print( "Visit www.vaultmp.com for help and upload this log if you experience problems with the mod.", false ); debug->Print( "-----------------------------------------------------------------------------------------------------", false ); //debug->PrintSystem(); API::SetDebugHandler( debug ); VaultException::SetDebugHandler( debug ); CriticalSection::SetDebugHandler( debug ); NetworkClient::SetDebugHandler( debug ); Interface::SetDebugHandler( debug ); Lockable::SetDebugHandler( debug ); Object::SetDebugHandler( debug ); Item::SetDebugHandler( debug ); Container::SetDebugHandler( debug ); Actor::SetDebugHandler( debug ); Player::SetDebugHandler( debug ); Game::SetDebugHandler( debug ); GameFactory::SetDebugHandler( debug ); #endif GameFactory::Initialize( game ); API::Initialize( game ); NetworkID id = GameFactory::CreateInstance( ID_PLAYER, PLAYER_REFERENCE, PLAYER_BASE ); FactoryObject reference = GameFactory::GetObject( id ); Player* self = vaultcast<Player>( reference ); self->SetEnabled( true ); self->SetName( name ); GameFactory::LeaveReference( reference ); self = NULL; // lets make sure that we dont use this by accident somewhere (old version code did so) Network::Flush(); try { if ( peer->Connect( server.ToString( false ), server.GetPort(), DEDICATED_VERSION, sizeof( DEDICATED_VERSION ), 0, 0, 3, 500, 0 ) == CONNECTION_ATTEMPT_STARTED ) { bool query = true; Packet* packet; while ( query ) { NetworkResponse response; while ( ( response = Network::Next() ).size() ) Network::Dispatch( peer, response ); for ( packet = peer->Receive(); packet; peer->DeallocatePacket( packet ), packet = peer->Receive() ) { if ( packet->data[0] == ID_DISCONNECTION_NOTIFICATION ) query = false; else if ( packet->data[0] == ID_CONNECTION_REQUEST_ACCEPTED ) Game::server = peer->GetGuidFromSystemAddress( server ); try { response = NetworkClient::ProcessPacket( packet ); Network::Dispatch( peer, response ); } catch ( ... ) { peer->DeallocatePacket( packet ); response = NetworkClient::ProcessEvent( ID_EVENT_CLIENT_ERROR ); Network::Dispatch( peer, response ); peer->CloseConnection( server, true, CHANNEL_SYSTEM, HIGH_PRIORITY ); throw; } } if ( initialized && !Interface::IsAvailable() ) { NetworkResponse response = NetworkClient::ProcessEvent( ID_EVENT_INTERFACE_LOST ); Network::Dispatch( peer, response ); peer->CloseConnection( server, true, CHANNEL_SYSTEM, HIGH_PRIORITY ); throw VaultException( "Lost connection to interface" ); } RakSleep( 2 ); } } else throw VaultException( "Could not establish connection to server" ); } catch ( ... ) { Sleep( 200 ); Packet* packet = NULL; while ( packet = peer->Receive() ) peer->DeallocatePacket( packet ); // disconnection notification might still arrive Interface::Terminate(); GameFactory::DestroyAllInstances(); API::Terminate(); #ifdef VAULTMP_DEBUG debug->Print( "Network thread is going to terminate (ERROR)", true ); #endif throw; } Interface::Terminate(); GameFactory::DestroyAllInstances(); API::Terminate(); #ifdef VAULTMP_DEBUG debug->Print( "Network thread is going to terminate (no error occured)", true ); #endif }
bool Lobby2Client_Steam_Impl::IsOverrideAddress(const SystemAddress &systemAddress) const { return (systemAddress.GetPort() == STEAM_UNUSED_PORT); }
int main(void) { RakPeerInterface *peers[NUM_PEERS]; int peerIndex; float nextAction; int i; printf("This is just a test app to run a bit of everything to test for crashes.\n"); printf("Difficulty: Intermediate\n\n"); char data[8096]; int seed = 12345; printf("Using seed %i\n", seed); seedMT(seed); for (i=0; i < NUM_PEERS; i++) { peers[i]=RakNet::RakPeerInterface::GetInstance(); peers[i]->SetMaximumIncomingConnections(CONNECTIONS_PER_SYSTEM); RakNet::SocketDescriptor socketDescriptor(60000+i, 0); peers[i]->Startup(NUM_PEERS, &socketDescriptor, 1); peers[i]->SetOfflinePingResponse("Offline Ping Data", (int)strlen("Offline Ping Data")+1); } for (i=0; i < NUM_PEERS; i++) { peers[i]->Connect("127.0.0.1", 60000+(randomMT()%NUM_PEERS), 0, 0); } RakNet::TimeMS endTime = RakNet::GetTimeMS()+600000; while (RakNet::GetTimeMS()<endTime) { nextAction = frandomMT(); if (nextAction < .04f) { // Initialize peerIndex=randomMT()%NUM_PEERS; RakNet::SocketDescriptor socketDescriptor(60000+peerIndex, 0); peers[peerIndex]->Startup(NUM_PEERS, &socketDescriptor, 1); peers[peerIndex]->Connect("127.0.0.1", 60000+randomMT() % NUM_PEERS, 0, 0); } else if (nextAction < .09f) { // Connect peerIndex=randomMT()%NUM_PEERS; peers[peerIndex]->Connect("127.0.0.1", 60000+randomMT() % NUM_PEERS, 0, 0); } else if (nextAction < .10f) { // Disconnect peerIndex=randomMT()%NUM_PEERS; // peers[peerIndex]->Shutdown(randomMT() % 100); } else if (nextAction < .12f) { // GetConnectionList peerIndex=randomMT()%NUM_PEERS; SystemAddress remoteSystems[NUM_PEERS]; unsigned short numSystems=NUM_PEERS; peers[peerIndex]->GetConnectionList(remoteSystems, &numSystems); if (numSystems>0) { #ifdef _DO_PRINTF printf("%i: ", 60000+numSystems); for (i=0; i < numSystems; i++) { printf("%i: ", remoteSystems[i].GetPort()); } printf("\n"); #endif } } else if (nextAction < .14f) { // Send int dataLength; PacketPriority priority; PacketReliability reliability; unsigned char orderingChannel; SystemAddress target; bool broadcast; // data[0]=ID_RESERVED1+(randomMT()%10); data[0]=ID_USER_PACKET_ENUM; dataLength=3+(randomMT()%8000); // dataLength=600+(randomMT()%7000); priority=(PacketPriority)(randomMT()%(int)NUMBER_OF_PRIORITIES); reliability=(PacketReliability)(randomMT()%((int)RELIABLE_SEQUENCED+1)); orderingChannel=randomMT()%32; if ((randomMT()%NUM_PEERS)==0) target=RakNet::UNASSIGNED_SYSTEM_ADDRESS; else target=peers[peerIndex]->GetSystemAddressFromIndex(randomMT()%NUM_PEERS); broadcast=(bool)(randomMT()%2); #ifdef _VERIFY_RECIPIENTS broadcast=false; // Temporarily in so I can check recipients #endif peerIndex=randomMT()%NUM_PEERS; sprintf(data+3, "dataLength=%i priority=%i reliability=%i orderingChannel=%i target=%i broadcast=%i\n", dataLength, priority, reliability, orderingChannel, target.GetPort(), broadcast); //unsigned short localPort=60000+i; #ifdef _VERIFY_RECIPIENTS memcpy((char*)data+1, (char*)&target.port, sizeof(unsigned short)); #endif data[dataLength-1]=0; peers[peerIndex]->Send(data, dataLength, priority, reliability, orderingChannel, target, broadcast); } else if (nextAction < .18f) { int dataLength; PacketPriority priority; PacketReliability reliability; unsigned char orderingChannel; SystemAddress target; bool broadcast; data[0]=ID_USER_PACKET_ENUM+(randomMT()%10); dataLength=3+(randomMT()%8000); // dataLength=600+(randomMT()%7000); priority=(PacketPriority)(randomMT()%(int)NUMBER_OF_PRIORITIES); reliability=(PacketReliability)(randomMT()%((int)RELIABLE_SEQUENCED+1)); orderingChannel=randomMT()%32; peerIndex=randomMT()%NUM_PEERS; if ((randomMT()%NUM_PEERS)==0) target=RakNet::UNASSIGNED_SYSTEM_ADDRESS; else target=peers[peerIndex]->GetSystemAddressFromIndex(randomMT()%NUM_PEERS); broadcast=(bool)(randomMT()%2); #ifdef _VERIFY_RECIPIENTS broadcast=false; // Temporarily in so I can check recipients #endif sprintf(data+3, "dataLength=%i priority=%i reliability=%i orderingChannel=%i target=%i broadcast=%i\n", dataLength, priority, reliability, orderingChannel, target.GetPort(), broadcast); #ifdef _VERIFY_RECIPIENTS memcpy((char*)data, (char*)&target.port, sizeof(unsigned short)); #endif data[dataLength-1]=0; } else if (nextAction < .181f) { // CloseConnection SystemAddress target; peerIndex=randomMT()%NUM_PEERS; target=peers[peerIndex]->GetSystemAddressFromIndex(randomMT()%NUM_PEERS); peers[peerIndex]->CloseConnection(target, (bool)(randomMT()%2), 0); } else if (nextAction < .20f) { // Offline Ping peerIndex=randomMT()%NUM_PEERS; peers[peerIndex]->Ping("127.0.0.1", 60000+(randomMT()%NUM_PEERS), (bool)(randomMT()%2)); } else if (nextAction < .21f) { // Online Ping SystemAddress target; target=peers[peerIndex]->GetSystemAddressFromIndex(randomMT()%NUM_PEERS); peerIndex=randomMT()%NUM_PEERS; peers[peerIndex]->Ping(target); } else if (nextAction < .24f) { } else if (nextAction < .25f) { // GetStatistics SystemAddress target, mySystemAddress; RakNetStatistics *rss; mySystemAddress=peers[peerIndex]->GetInternalID(); target=peers[peerIndex]->GetSystemAddressFromIndex(randomMT()%NUM_PEERS); peerIndex=randomMT()%NUM_PEERS; rss=peers[peerIndex]->GetStatistics(mySystemAddress); if (rss) { StatisticsToString(rss, data, 0); #ifdef _DO_PRINTF printf("Statistics for local system %i:\n%s", mySystemAddress.GetPort(), data); #endif } rss=peers[peerIndex]->GetStatistics(target); if (rss) { StatisticsToString(rss, data, 0); #ifdef _DO_PRINTF printf("Statistics for target system %i:\n%s", target.GetPort(), data); #endif } } for (i=0; i < NUM_PEERS; i++) peers[i]->DeallocatePacket(peers[i]->Receive()); #ifdef _WIN32 Sleep(0); #else usleep(0); #endif } for (i=0; i < NUM_PEERS; i++) RakNet::RakPeerInterface::DestroyInstance(peers[i]); return 0; }