int main(void) { char ch; #ifdef USE_TCP RakNet::PacketizedTCP tcp1; #else RakNet::RakPeerInterface *rakPeer; #endif // directoryDeltaTransfer is the main plugin that does the work for this sample. RakNet::DirectoryDeltaTransfer directoryDeltaTransfer; // The fileListTransfer plugin is used by the DirectoryDeltaTransfer plugin and must also be registered (you could use this yourself too if you wanted, of course). RakNet::FileListTransfer fileListTransfer; // Read files in parts, rather than the whole file from disk at once RakNet::IncrementalReadInterface iri; directoryDeltaTransfer.SetDownloadRequestIncrementalReadInterface(&iri, 1000000); #ifdef USE_TCP tcp1.AttachPlugin(&directoryDeltaTransfer); tcp1.AttachPlugin(&fileListTransfer); #else rakPeer = RakNet::RakPeerInterface::GetInstance(); rakPeer->AttachPlugin(&directoryDeltaTransfer); rakPeer->AttachPlugin(&fileListTransfer); // Get download progress notifications. Handled by the plugin. rakPeer->SetSplitMessageProgressInterval(100); #endif directoryDeltaTransfer.SetFileListTransferPlugin(&fileListTransfer); printf("This sample demonstrates the plugin to incrementally transfer compressed\n"); printf("deltas of directories. In essence, it's a simple autopatcher.\n"); printf("Unlike the full autopatcher, it has no dependencies. It is suitable for\n"); printf("patching from non-dedicated servers at runtime.\n"); printf("Difficulty: Intermediate\n\n"); printf("Enter listen port. Enter for default. If running two instances on the\nsame computer, use 0 for the client.\n"); unsigned short localPort; char str[256]; Gets(str, sizeof(str)); if (str[0]==0) localPort=60000; else localPort=atoi(str); RakNet::SocketDescriptor socketDescriptor(localPort,0); #ifdef USE_TCP bool b=tcp1.Start(localPort,8); RakAssert(b); #else if (rakPeer->Startup(8,&socketDescriptor, 1)!=RakNet::RAKNET_STARTED) { RakNet::RakPeerInterface::DestroyInstance(rakPeer); printf("RakNet initialize failed. Possibly duplicate port.\n"); return 1; } rakPeer->SetMaximumIncomingConnections(8); #endif printf("Commands:\n"); printf("(S)et application directory.\n"); printf("(A)dd allowed uploads from subdirectory.\n"); printf("(D)ownload from subdirectory.\n"); printf("(C)lear allowed uploads.\n"); printf("C(o)nnect to another system.\n"); printf("(Q)uit.\n"); RakNet::SystemAddress sysAddrZero=RakNet::UNASSIGNED_SYSTEM_ADDRESS; RakNet::TimeMS nextStatTime = RakNet::GetTimeMS() + 1000; RakNet::Packet *p; while (1) { /* if (//directoryDeltaTransfer.GetNumberOfFilesForUpload()>0 && RakNet::GetTimeMS() > nextStatTime) { // If sending, periodically show connection stats char statData[2048]; RakNetStatistics *statistics = rakPeer->GetStatistics(rakPeer->GetSystemAddressFromIndex(0)); // if (statistics->messagesOnResendQueue>0 || statistics->internalOutputQueueSize>0) if (rakPeer->GetSystemAddressFromIndex(0)!=RakNet::UNASSIGNED_SYSTEM_ADDRESS) { StatisticsToString(statistics, statData, 2); printf("%s\n", statData); } nextStatTime=RakNet::GetTimeMS()+5000; } */ // Process packets #ifdef USE_TCP p=tcp1.Receive(); #else p=rakPeer->Receive(); #endif #ifdef USE_TCP RakNet::SystemAddress sa; sa=tcp1.HasNewIncomingConnection(); if (sa!=RakNet::UNASSIGNED_SYSTEM_ADDRESS) { printf("ID_NEW_INCOMING_CONNECTION\n"); sysAddrZero=sa; } if (tcp1.HasLostConnection()!=RakNet::UNASSIGNED_SYSTEM_ADDRESS) printf("ID_DISCONNECTION_NOTIFICATION\n"); if (tcp1.HasFailedConnectionAttempt()!=RakNet::UNASSIGNED_SYSTEM_ADDRESS) printf("ID_CONNECTION_ATTEMPT_FAILED\n"); sa=tcp1.HasCompletedConnectionAttempt(); if (sa!=RakNet::UNASSIGNED_SYSTEM_ADDRESS) { printf("ID_CONNECTION_REQUEST_ACCEPTED\n"); sysAddrZero=sa; } #endif while (p) { #ifdef USE_TCP tcp1.DeallocatePacket(p); tcp1.Receive(); #else if (p->data[0]==ID_NEW_INCOMING_CONNECTION) { printf("ID_NEW_INCOMING_CONNECTION\n"); sysAddrZero=p->systemAddress; } else if (p->data[0]==ID_CONNECTION_REQUEST_ACCEPTED) { printf("ID_CONNECTION_REQUEST_ACCEPTED\n"); sysAddrZero=p->systemAddress; } else if (p->data[0]==ID_DISCONNECTION_NOTIFICATION) printf("ID_DISCONNECTION_NOTIFICATION\n"); else if (p->data[0]==ID_CONNECTION_LOST) printf("ID_CONNECTION_LOST\n"); else if (p->data[0]==ID_CONNECTION_ATTEMPT_FAILED) printf("ID_CONNECTION_ATTEMPT_FAILED\n"); rakPeer->DeallocatePacket(p); p=rakPeer->Receive(); #endif } if (kbhit()) { ch=getch(); if (ch=='s') { printf("Enter application directory\n"); Gets(str, sizeof(str)); if (str[0]==0) strcpy(str, "C:/Temp"); directoryDeltaTransfer.SetApplicationDirectory(str); printf("This directory will be prefixed to upload and download subdirectories.\n"); } else if (ch=='a') { printf("Enter uploads subdirectory\n"); Gets(str, sizeof(str)); directoryDeltaTransfer.AddUploadsFromSubdirectory(str); printf("%i files for upload.\n", directoryDeltaTransfer.GetNumberOfFilesForUpload()); } else if (ch=='d') { char subdir[256]; char outputSubdir[256]; printf("Enter remote subdirectory to download from.\n"); printf("This directory may be any uploaded directory, or a subdir therein.\n"); Gets(subdir,sizeof(subdir)); printf("Enter subdirectory to output to.\n"); Gets(outputSubdir,sizeof(outputSubdir)); unsigned short setId; setId=directoryDeltaTransfer.DownloadFromSubdirectory(subdir, outputSubdir, true, sysAddrZero, &transferCallback, HIGH_PRIORITY, 0, 0); if (setId==(unsigned short)-1) printf("Download failed. Host unreachable.\n"); else printf("Downloading set %i\n", setId); } else if (ch=='c') { directoryDeltaTransfer.ClearUploads(); printf("Uploads cleared.\n"); } else if (ch=='o') { char host[256]; printf("Enter host IP: "); Gets(host,sizeof(host)); if (host[0]==0) strcpy(host, "127.0.0.1"); unsigned short remotePort; printf("Enter host port: "); Gets(str, sizeof(str)); if (str[0]==0) remotePort=60000; else remotePort=atoi(str); #ifdef USE_TCP tcp1.Connect(host,remotePort,false); #else rakPeer->Connect(host, remotePort, 0, 0); #endif printf("Connecting.\n"); } else if (ch=='q') { printf("Bye!\n"); #ifdef USE_TCP tcp1.Stop(); #else rakPeer->Shutdown(1000,0); #endif break; } } // Keeps the threads responsive RakSleep(0); } #ifdef USE_TCP #else RakNet::RakPeerInterface::DestroyInstance(rakPeer); #endif return 0; }
int main(int argc, char **argv) { printf("A simple client interface for the advanced autopatcher.\n"); printf("Use DirectoryDeltaTransfer for a simpler version of an autopatcher.\n"); printf("Difficulty: Intermediate\n\n"); printf("Client starting..."); RakNet::SystemAddress serverAddress=RakNet::UNASSIGNED_SYSTEM_ADDRESS; RakNet::AutopatcherClient autopatcherClient; RakNet::FileListTransfer fileListTransfer; autopatcherClient.SetFileListTransferPlugin(&fileListTransfer); unsigned short localPort=0; if (argc>=6) { localPort=atoi(argv[5]); } #ifdef USE_TCP RakNet::PacketizedTCP packetizedTCP; if (packetizedTCP.Start(localPort,1)==false) { printf("Failed to start TCP. Is the port already in use?"); return 1; } packetizedTCP.AttachPlugin(&autopatcherClient); packetizedTCP.AttachPlugin(&fileListTransfer); #else RakNet::RakPeerInterface *rakPeer; rakPeer = RakNet::RakPeerInterface::GetInstance(); RakNet::SocketDescriptor socketDescriptor(localPort,0); rakPeer->Startup(1,&socketDescriptor, 1); // Plugin will send us downloading progress notifications if a file is split to fit under the MTU 10 or more times rakPeer->SetSplitMessageProgressInterval(10); rakPeer->AttachPlugin(&autopatcherClient); rakPeer->AttachPlugin(&fileListTransfer); #endif printf("started\n"); char buff[512]; if (argc<2) { printf("Enter server IP: "); Gets(buff,sizeof(buff)); if (buff[0]==0) //strcpy(buff, "94.198.81.195"); strcpy(buff, "127.0.0.1"); } else strcpy(buff, argv[1]); #ifdef USE_TCP packetizedTCP.Connect(buff,60000,false); #else rakPeer->Connect(buff, 60000, 0, 0); #endif printf("Connecting...\n"); char appDir[512]; if (argc<3) { printf("Enter application directory: "); Gets(appDir,sizeof(appDir)); if (appDir[0]==0) { strcpy(appDir, "D:/temp2"); } } else strcpy(appDir, argv[2]); char appName[512]; if (argc<4) { printf("Enter application name: "); Gets(appName,sizeof(appName)); if (appName[0]==0) strcpy(appName, "TestApp"); } else strcpy(appName, argv[3]); bool patchImmediately=argc>=5 && argv[4][0]=='1'; if (patchImmediately==false) printf("Hit 'q' to quit, 'p' to patch, 'c' to cancel the patch. 'r' to reconnect. 'd' to disconnect.\n"); else printf("Hit 'q' to quit, 'c' to cancel the patch.\n"); char ch; RakNet::Packet *p; while (1) { #ifdef USE_TCP RakNet::SystemAddress notificationAddress; notificationAddress=packetizedTCP.HasCompletedConnectionAttempt(); if (notificationAddress!=RakNet::UNASSIGNED_SYSTEM_ADDRESS) { printf("ID_CONNECTION_REQUEST_ACCEPTED\n"); serverAddress=notificationAddress; } notificationAddress=packetizedTCP.HasNewIncomingConnection(); if (notificationAddress!=RakNet::UNASSIGNED_SYSTEM_ADDRESS) printf("ID_NEW_INCOMING_CONNECTION\n"); notificationAddress=packetizedTCP.HasLostConnection(); if (notificationAddress!=RakNet::UNASSIGNED_SYSTEM_ADDRESS) printf("ID_CONNECTION_LOST\n"); p=packetizedTCP.Receive(); while (p) { if (p->data[0]==ID_AUTOPATCHER_REPOSITORY_FATAL_ERROR) { char buff[256]; RakNet::BitStream temp(p->data, p->length, false); temp.IgnoreBits(8); RakNet::StringCompressor::Instance()->DecodeString(buff, 256, &temp); printf("ID_AUTOPATCHER_REPOSITORY_FATAL_ERROR\n"); printf("%s\n", buff); } else if (p->data[0]==ID_AUTOPATCHER_FINISHED) { printf("ID_AUTOPATCHER_FINISHED with server time %f\n", autopatcherClient.GetServerDate()); double srvDate=autopatcherClient.GetServerDate(); FILE *fp = fopen("srvDate", "wb"); fwrite(&srvDate,sizeof(double),1,fp); fclose(fp); } else if (p->data[0]==ID_AUTOPATCHER_RESTART_APPLICATION) printf("Launch \"AutopatcherClientRestarter.exe autopatcherRestart.txt\"\nQuit this application immediately after to unlock files.\n"); packetizedTCP.DeallocatePacket(p); p=packetizedTCP.Receive(); } #else p=rakPeer->Receive(); while (p) { if (p->data[0]==ID_DISCONNECTION_NOTIFICATION) printf("ID_DISCONNECTION_NOTIFICATION\n"); else if (p->data[0]==ID_CONNECTION_LOST) printf("ID_CONNECTION_LOST\n"); else if (p->data[0]==ID_CONNECTION_REQUEST_ACCEPTED) { printf("ID_CONNECTION_REQUEST_ACCEPTED\n"); serverAddress=p->systemAddress; } else if (p->data[0]==ID_CONNECTION_ATTEMPT_FAILED) printf("ID_CONNECTION_ATTEMPT_FAILED\n"); else if (p->data[0]==ID_NO_FREE_INCOMING_CONNECTIONS) printf("ID_NO_FREE_INCOMING_CONNECTIONS\n"); else if (p->data[0]==ID_AUTOPATCHER_REPOSITORY_FATAL_ERROR) { char buff[256]; RakNet::BitStream temp(p->data, p->length, false); temp.IgnoreBits(8); RakNet::StringCompressor::Instance()->DecodeString(buff, 256, &temp); printf("ID_AUTOPATCHER_REPOSITORY_FATAL_ERROR\n"); printf("%s\n", buff); } else if (p->data[0]==ID_AUTOPATCHER_FINISHED) { printf("ID_AUTOPATCHER_FINISHED with server time %f\n", autopatcherClient.GetServerDate()); double srvDate=autopatcherClient.GetServerDate(); FILE *fp = fopen("srvDate", "wb"); fwrite(&srvDate,sizeof(double),1,fp); fclose(fp); } else if (p->data[0]==ID_AUTOPATCHER_RESTART_APPLICATION) printf("Launch \"AutopatcherClientRestarter.exe autopatcherRestart.txt\"\nQuit this application immediately after to unlock files.\n"); rakPeer->DeallocatePacket(p); p=rakPeer->Receive(); } #endif if (kbhit()) ch=getch(); else ch=0; if (ch=='q') break; else if (ch=='r') { #ifdef USE_TCP packetizedTCP.Connect(buff,60000,false); #else rakPeer->Connect(buff, 60000, 0, 0); #endif } else if (ch=='d') { #ifdef USE_TCP packetizedTCP.CloseConnection(serverAddress); #else rakPeer->CloseConnection(serverAddress, true); #endif } else if (ch=='p' || (serverAddress!=RakNet::UNASSIGNED_SYSTEM_ADDRESS && patchImmediately==true)) { patchImmediately=false; char restartFile[512]; strcpy(restartFile, appDir); strcat(restartFile, "/autopatcherRestart.txt"); double lastUpdateDate; FILE *fp = fopen("srvDate", "rb"); if (fp) { fread(&lastUpdateDate, sizeof(lastUpdateDate), 1, fp); fclose(fp); } else lastUpdateDate=0; if (autopatcherClient.PatchApplication(appName, appDir, lastUpdateDate, serverAddress, &transferCallback, restartFile, argv[0])) { printf("Patching process starting.\n"); } else { printf("Failed to start patching.\n"); } } else if (ch=='c') { autopatcherClient.Clear(); printf("Autopatcher cleared.\n"); } RakSleep(30); } // Dereference so the destructor doesn't crash autopatcherClient.SetFileListTransferPlugin(0); #ifdef USE_TCP packetizedTCP.Stop(); #else rakPeer->Shutdown(500,0); RakNet::RakPeerInterface::DestroyInstance(rakPeer); #endif return 1; }