/* * Original work: Copyright (c) 2014, Oculus VR, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * RakNet License.txt file in the licenses directory of this source tree. An additional grant * of patent rights can be found in the RakNet Patents.txt file in the same directory. * * * Modified work: Copyright (c) 2016-2018, SLikeSoft UG (haftungsbeschränkt) * * This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style * license found in the license.txt file in the root directory of this source tree. */ #include "slikenet/peerinterface.h" #include #include "slikenet/Kbhit.h" #include #include #include // used for std::numeric_limits #include "slikenet/BitStream.h" #include "slikenet/MessageIdentifiers.h" #include "slikenet/Router2.h" #include "slikenet/sleep.h" #include "slikenet/GetTime.h" #include "slikenet/Rand.h" #include "slikenet/assert.h" #include "slikenet/SocketLayer.h" #include "slikenet/Getche.h" #include "slikenet/Gets.h" #include "slikenet/linux_adapter.h" #include "slikenet/osx_adapter.h" using namespace SLNet; // Global just to make the sample easier to write RakNetGUID endpointGuid; RakPeerInterface *endpoint=0, *router=0; RakPeerInterface *rakPeer; Router2 *router2Plugin; void ReadAllPackets(void) { char str[64], str2[64]; Packet *packet; for (packet=rakPeer->Receive(); packet; rakPeer->DeallocatePacket(packet), packet=rakPeer->Receive()) { packet->guid.ToString(str, 64); packet->systemAddress.ToString(true,str2,static_cast(64)); if (packet->data[0]==ID_NEW_INCOMING_CONNECTION) { printf("ID_NEW_INCOMING_CONNECTION from %s on %s\n", str, str2); } else if (packet->data[0]==ID_CONNECTION_REQUEST_ACCEPTED) { printf("ID_CONNECTION_REQUEST_ACCEPTED from %s on %s\n", str, str2); } else if (packet->data[0]==ID_ROUTER_2_FORWARDING_NO_PATH) { printf("No path to endpoint exists. Routing failed.\n"); } else if (packet->data[0]==ID_CONNECTION_LOST) { printf("ID_CONNECTION_LOST from %s\n", str); } else if (packet->data[0]==ID_USER_PACKET_ENUM+1) { printf("Got ID_USER_PACKET_ENUM from %s\n", str); } else if (packet->data[0]==ID_ROUTER_2_FORWARDING_ESTABLISHED) { SLNet::BitStream bs(packet->data, packet->length, false); bs.IgnoreBytes(sizeof(MessageID)); bs.Read(endpointGuid); printf("Routing through %s to %s successful. Connecting.\n", str, endpointGuid.ToString()); unsigned short sourceToDestPort; bs.Read(sourceToDestPort); char ipAddressString[32]; packet->systemAddress.ToString(false, ipAddressString,static_cast(32)); rakPeer->Connect(ipAddressString, sourceToDestPort, 0,0); } else if (packet->data[0]==ID_ROUTER_2_REROUTED) { // You could read the endpointGuid and sourceToDestPoint if you wanted to SLNet::BitStream bs(packet->data, packet->length, false); bs.IgnoreBytes(sizeof(MessageID)); RakNetGUID endpointGuid2; bs.Read(endpointGuid2); endpointGuid2.ToString(str, 64); SystemAddress intermediateAddress=packet->systemAddress; unsigned short port; bs.Read(port); intermediateAddress.SetPortHostOrder(port); char str3[32]; intermediateAddress.ToString(true, str3, static_cast(32)); printf("Connection to %s rerouted through %s\n", str, str3); // Test sending a message to the endpoint SLNet::BitStream bsOut; MessageID id = ID_USER_PACKET_ENUM+1; bsOut.Write(id); rakPeer->Send(&bsOut,HIGH_PRIORITY,RELIABLE_ORDERED,0,endpointGuid2,false); } } } int main(void) { printf("Demonstration of the router2 plugin.\n"); printf("The router2 plugin allows you to connect to a system, routing messages through\n"); printf("a third system. This is useful if you can connect to the second system, but not\n"); printf("the third, due to NAT issues.\n"); printf("1. Start 4 instances, A, B, C, D\n"); printf("2. Connect A to B and C, B to C, and D to B and C.\n"); printf("3. On A press 'r' to start routing to D\n"); printf("4. Once connected, close the router that did the routing to reroute.\n"); printf("Difficulty: Advanced\n\n");; endpointGuid=UNASSIGNED_RAKNET_GUID; char str[64], str2[64]; rakPeer= SLNet::RakPeerInterface::GetInstance(); rakPeer->SetMaximumIncomingConnections(32); SocketDescriptor sd(0,0); rakPeer->Startup(32,&sd,1); printf("Enter 'c' to connect, 'r' to start routing, 'q' to quit.\n"); rakPeer->GetGuidFromSystemAddress(UNASSIGNED_SYSTEM_ADDRESS).ToString(str, 64); printf("My GUID is %s\n", str); printf("Started on port %i\n", rakPeer->GetSocket(UNASSIGNED_SYSTEM_ADDRESS)->GetBoundAddress().GetPort()); rakPeer->SetTimeoutTime(3000,UNASSIGNED_SYSTEM_ADDRESS); router2Plugin = new Router2; // Router2DebugInterface r2di; // router2Plugin->SetDebugInterface(&r2di); rakPeer->AttachPlugin(router2Plugin); router2Plugin->SetMaximumForwardingRequests(1); printf("Sample running. Press 'q' to quit\n"); for(;;) { if (_kbhit()) { int ch=_getch(); if (ch=='q') break; if (ch=='r') { do { printf("Enter destination guid: "); Gets(str2,sizeof(str2)); } while (str2[0]==0); RakNetGUID destinationGuid; destinationGuid.FromString(str2); router2Plugin->EstablishRouting(destinationGuid); } if (ch=='c') { printf("Enter IP address to connect to: "); Gets(str,sizeof(str)); if (str[0]==0) strcpy_s(str, "127.0.0.1"); int intRemotePort = 0; do { printf("Enter port to connect to: "); Gets(str2,sizeof(str2)); intRemotePort = atoi(str2); if ((intRemotePort < 0) || (intRemotePort > std::numeric_limits::max())) { printf("Specified remote port %d is outside valid bounds [0, %u]", intRemotePort, std::numeric_limits::max()); intRemotePort = 0; } } while (intRemotePort == 0); // Connect rakPeer->Connect(str, static_cast(intRemotePort),0,0); } } RakSleep(30); ReadAllPackets(); } SLNet::RakPeerInterface::DestroyInstance(rakPeer); delete router2Plugin; }