bool FStreamingNetworkPlatformFile::InitializeInternal(IPlatformFile* Inner, const TCHAR* HostIP) { // look for the commandline that will read files from over the network if (HostIP == nullptr) { UE_LOG(LogStreamingPlatformFile, Error, TEXT("No Host IP specified in the commandline.")); bIsUsable = false; return false; } // optionally get the port from the command line int32 OverridePort; if (FParse::Value(FCommandLine::Get(), TEXT("fileserverport="), OverridePort)) { UE_LOG(LogStreamingPlatformFile, Display, TEXT("Overriding file server port: %d"), OverridePort); FileServerPort = OverridePort; } // Send the filenames and timestamps to the server. FNetworkFileArchive Payload(NFS_Messages::GetFileList); FillGetFileList(Payload, true); // Send the directories over, and wait for a response. FArrayReader Response; if(SendPayloadAndReceiveResponse(Payload,Response)) { // Receive the cooked version information. int32 ServerPackageVersion = 0; int32 ServerPackageLicenseeVersion = 0; ProcessServerInitialResponse(Response, ServerPackageVersion, ServerPackageLicenseeVersion); // Make sure we can sync a file. FString TestSyncFile = FPaths::Combine(*(FPaths::EngineDir()), TEXT("Config/BaseEngine.ini")); IFileHandle* TestFileHandle = OpenRead(*TestSyncFile); if (TestFileHandle != nullptr) { uint8* FileContents = (uint8*)FMemory::Malloc(TestFileHandle->Size()); if (!TestFileHandle->Read(FileContents, TestFileHandle->Size())) { UE_LOG(LogStreamingPlatformFile, Fatal, TEXT("Could not read test file %s."), *TestSyncFile); } FMemory::Free(FileContents); delete TestFileHandle; } else { UE_LOG(LogStreamingPlatformFile, Fatal, TEXT("Could not open test file %s."), *TestSyncFile); } FCommandLine::AddToSubprocessCommandline( *FString::Printf( TEXT("-StreamingHostIP=%s"), HostIP ) ); return true; } return false; }
bool CopyFileToDevice(const FString& IPAPath, FString PathOnDevice, int PacketSize) { bool Result = false; // reconnect to the device and start the AFC service Connect(); if (!AFC::StartService(DeviceHandle, &AFCHandle)) { if (!AFC::ConnectionOpen(AFCHandle, &AFCConnection)) { // ensure the directory on the phone exists FString DirectoryOnDevice = FPaths::GetPath(PathOnDevice); CreateDirectory(DirectoryOnDevice + TEXT("/")); // transfer the file IPlatformFile& PlatformFile = IPlatformFile::GetPlatformPhysical(); IFileHandle* SourceFile = PlatformFile.OpenRead(*IPAPath); if (SourceFile != NULL) { uint64 DestinationHandle = 0; if (AFC::FileRefOpen(AFCConnection, PathOnDevice, 3, &DestinationHandle) == 0) { int TotalBytes = 0; int PacketCount = SourceFile->Size() / PacketSize; uint8* buffer = new uint8[PacketSize]; for (int Index = 0; Index < PacketCount; ++Index) { if (SourceFile->Read(buffer, PacketSize)) { TotalBytes += PacketSize; AFC::FileRefWrite(AFCConnection, DestinationHandle, buffer, PacketSize); } } if (SourceFile->Read(buffer, SourceFile->Size() - TotalBytes)) { AFC::FileRefWrite(AFCConnection, DestinationHandle, buffer, SourceFile->Size() - TotalBytes); } // flush the destination and close AFC::FileRefClose(AFCConnection, DestinationHandle); Result = true; } delete SourceFile; } // stop the AFC service and disconnect from the device AFC::ConnectionClose(AFCConnection); AFCConnection = NULL; Disconnect(); } } return Result; }
void FNetworkFileServerClientConnection::PackageFile( FString& Filename, FArchive& Out ) { // get file timestamp and send it to client FDateTime ServerTimeStamp = Sandbox->GetTimeStamp(*Filename); TArray<uint8> Contents; // open file IFileHandle* File = Sandbox->OpenRead(*Filename); if (!File) { ServerTimeStamp = FDateTime::MinValue(); // if this was a directory, this will make sure it is not confused with a zero byte file UE_LOG(LogFileServer, Warning, TEXT("Request for missing file %s."), *Filename ); } else { if (!File->Size()) { UE_LOG(LogFileServer, Warning, TEXT("Sending empty file %s...."), *Filename); } else { // read it Contents.AddUninitialized(File->Size()); File->Read(Contents.GetData(), Contents.Num()); } // close it delete File; UE_LOG(LogFileServer, Display, TEXT("Read %s, %d bytes"), *Filename, Contents.Num()); } Out << Filename; Out << ServerTimeStamp; uint64 FileSize = Contents.Num(); Out << FileSize; Out.Serialize(Contents.GetData(), FileSize); }
FArchive* FFileManagerGeneric::CreateFileReader( const TCHAR* InFilename, uint32 Flags ) { IFileHandle* Handle = GetLowLevel().OpenRead( InFilename, !!(Flags & FILEREAD_AllowWrite) ); if( !Handle ) { if( Flags & FILEREAD_NoFail ) { UE_LOG( LogFileManager, Fatal, TEXT( "Failed to read file: %s" ), InFilename ); } return NULL; } return new FArchiveFileReaderGeneric( Handle, InFilename, Handle->Size() ); }
void FNetworkFileServerClientConnection::ProcessOpenFile( FArchive& In, FArchive& Out, bool bIsWriting ) { // Get filename FString Filename; In << Filename; bool bAppend = false; bool bAllowRead = false; if (bIsWriting) { In << bAppend; In << bAllowRead; } // todo: clients from the same ip address "could" be trying to write to the same file in the same sandbox (for example multiple windows clients) // should probably have the sandbox write to separate files for each client // not important for now ConvertClientFilenameToServerFilename(Filename); if (bIsWriting) { // Make sure the directory exists... Sandbox->CreateDirectoryTree(*(FPaths::GetPath(Filename))); } TArray<FString> NewUnsolictedFiles; FileRequestDelegate.ExecuteIfBound(Filename, ConnectedPlatformName, NewUnsolictedFiles); FDateTime ServerTimeStamp = Sandbox->GetTimeStamp(*Filename); int64 ServerFileSize = 0; IFileHandle* File = bIsWriting ? Sandbox->OpenWrite(*Filename, bAppend, bAllowRead) : Sandbox->OpenRead(*Filename); if (!File) { UE_LOG(LogFileServer, Display, TEXT("Open request for %s failed for file %s."), bIsWriting ? TEXT("Writing") : TEXT("Reading"), *Filename); ServerTimeStamp = FDateTime::MinValue(); // if this was a directory, this will make sure it is not confused with a zero byte file } else { ServerFileSize = File->Size(); } uint64 HandleId = ++LastHandleId; OpenFiles.Add( HandleId, File ); Out << HandleId; Out << ServerTimeStamp; Out << ServerFileSize; }