/** Set up as a fresh packet with the given opcode. @param aOpcode a opcode */ EXPORT_C void CObexPacket::Init (TObexOpcode aOpcode) { LOG_LINE LOG_FUNC SetOpcode (aOpcode); SetPacketSize (KObexPacketHeaderSize); iInsertPoint = Payload (); iExtractPoint = Payload (); iNotificationEvents = 0; }
void AllMerging() { // default value Merging<Reader, Writer>(Payload(), T()); Merging<Reader, Writer>(Payload(), T(), Reader::version); Merging<Reader, Writer>(InitRandom<Payload>(), T()); Merging<Reader, Writer>(InitRandom<Payload>(), T(), Reader::version); Merging<Reader, Writer>(Payload(), InitRandom<T>()); Merging<Reader, Writer>(Payload(), InitRandom<T>(), Reader::version); // random values MergingRandom<Reader, Writer, Payload, T>(); }
bool FStreamingNetworkPlatformFile::SendReadMessage(uint64 HandleId, uint8* Destination, int64 BytesToRead) { FScopeLock ScopeLock(&SynchronizationObject); // Send the filename over. FStreamingNetworkFileArchive Payload(NFS_Messages::Read); Payload << HandleId; Payload << BytesToRead; // Send the filename over FArrayReader Response; if (SendPayloadAndReceiveResponse(Payload, Response) == false) { return false; } // Get the server number of bytes read. int64 ServerBytesRead = 0; Response << ServerBytesRead; bool bSuccess = (ServerBytesRead == BytesToRead); if (bSuccess) { // Get the data. Response.Serialize(Destination, BytesToRead); } return bSuccess; }
bool FStreamingNetworkPlatformFile::MoveFile(const TCHAR* To, const TCHAR* From) { FScopeLock ScopeLock(&SynchronizationObject); FString RelativeFrom = From; MakeStandardNetworkFilename(RelativeFrom); FString RelativeTo = To; MakeStandardNetworkFilename(RelativeTo); FStreamingNetworkFileArchive Payload(NFS_Messages::MoveFile); Payload << RelativeFrom; Payload << RelativeTo; FArrayReader Response; if (SendPayloadAndReceiveResponse(Payload, Response) == false) { return false; } uint32 Success = 0; Response << Success; return !!Success; }
void FNetworkPlatformFile::PerformHeartbeat() { // send the filename over (cast away const here because we know this << will not modify the string) FNetworkFileArchive Payload(NFS_Messages::Heartbeat); // send the filename over FArrayReader Response; if (!SendPayloadAndReceiveResponse(Payload, Response)) { return; } // get any files that have been modified on the server - TArray<FString> UpdatedFiles; Response << UpdatedFiles; // delete any outdated files from the client // @todo: This may need a critical section around all calls to LowLevel in the other functions // because we don't want to delete files while other threads are using them! for (int32 FileIndex = 0; FileIndex < UpdatedFiles.Num(); FileIndex++) { UE_LOG(LogNetworkPlatformFile, Log, TEXT("Server updated file '%s', deleting local copy"), *UpdatedFiles[FileIndex]); if (InnerPlatformFile->DeleteFile(*UpdatedFiles[FileIndex]) == false) { UE_LOG(LogNetworkPlatformFile, Error, TEXT("Failed to delete %s, someone is probably accessing without FNetworkPlatformFile, or we need better thread protection"), *UpdatedFiles[FileIndex]); } } }
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 FStreamingNetworkPlatformFile::SendCloseMessage(uint64 HandleId) { FScopeLock ScopeLock(&SynchronizationObject); // Send the filename over (cast away const here because we know this << will not modify the string) FStreamingNetworkFileArchive Payload(NFS_Messages::Close); Payload << HandleId; FArrayReader Response; return SendPayloadAndReceiveResponse(Payload, Response); }
void FStreamingNetworkPlatformFile::PerformHeartbeat() { FNetworkFileArchive Payload(NFS_Messages::Heartbeat); // send the filename over FArrayReader Response; if(SendPayloadAndReceiveResponse(Payload,Response)) { return; } check(0); }
FString FStreamingNetworkPlatformFile::ConvertToAbsolutePathForExternalAppForWrite( const TCHAR* Filename ) { FScopeLock ScopeLock(&SynchronizationObject); FStreamingNetworkFileArchive Payload(NFS_Messages::ToAbsolutePathForWrite); FString RelativeFilename = Filename; MakeStandardNetworkFilename(RelativeFilename); Payload << RelativeFilename; // perform a local operation FArrayReader Response; if (SendPayloadAndReceiveResponse(Payload, Response) == true) { Response << RelativeFilename; } return RelativeFilename; }
FStreamingNetworkFileHandle* FStreamingNetworkPlatformFile::SendOpenMessage(const FString& Filename, bool bIsWriting, bool bAppend, bool bAllowRead) { FScopeLock ScopeLock(&SynchronizationObject); FStreamingNetworkFileArchive Payload(bIsWriting ? NFS_Messages::OpenWrite : NFS_Messages::OpenRead); Payload << const_cast<FString&>(Filename); if (bIsWriting) { Payload << bAppend; Payload << bAllowRead; } // Send the filename over FArrayReader Response; if (SendPayloadAndReceiveResponse(Payload, Response) == false) { return nullptr; } // This server handle ID which will be used to perform operations on this file. uint64 HandleId = 0; Response << HandleId; // Get the server file timestamp FDateTime ServerTimeStamp; Response << ServerTimeStamp; // Get the server file size int64 ServerFileSize = 0; Response << ServerFileSize; if (bIsWriting || ServerFileSize > 0) { FStreamingNetworkFileHandle* FileHandle = new FStreamingNetworkFileHandle(*this, *Filename, HandleId, ServerFileSize, bIsWriting); return FileHandle; } else { return nullptr; } }
void FStreamingNetworkPlatformFile::SetTimeStamp(const TCHAR* Filename, FDateTime DateTime) { FScopeLock ScopeLock(&SynchronizationObject); FStreamingNetworkFileArchive Payload(NFS_Messages::SetTimeStamp); FString RelativeFilename = Filename; MakeStandardNetworkFilename(RelativeFilename); Payload << RelativeFilename; Payload << DateTime; // perform a local operation FArrayReader Response; if (SendPayloadAndReceiveResponse(Payload, Response) == false) { return; } bool bSuccess = 0; Response << bSuccess; }
bool FStreamingNetworkPlatformFile::SendSeekMessage(uint64 HandleId, int64 NewPosition) { FScopeLock ScopeLock(&SynchronizationObject); // Send the filename over. FStreamingNetworkFileArchive Payload(NFS_Messages::Seek); Payload << HandleId; Payload << NewPosition; FArrayReader Response; if (SendPayloadAndReceiveResponse(Payload, Response) == false) { return false; } int64 ServerNewPosition = -1; Response << ServerNewPosition; return (ServerNewPosition == NewPosition); }
bool FNetworkPlatformFile::SendMessageToServer(const TCHAR* Message, IPlatformFile::IFileServerMessageHandler* Handler) { // handle the recompile shaders message // @todo: Maybe we should just send the string message to the server, but then we'd have to // handle the return from the server in a generic way if (FCString::Stricmp(Message, TEXT("RecompileShaders")) == 0) { FNetworkFileArchive Payload(NFS_Messages::RecompileShaders); // let the handler fill out the object Handler->FillPayload(Payload); FArrayReader Response; if (!SendPayloadAndReceiveResponse(Payload, Response)) { return false; } // locally delete any files that were modified on the server, so that any read will recache the file // this has to be done in this class, not in the Handler (which can't access these members) TArray<FString> ModifiedFiles; Response << ModifiedFiles; if( InnerPlatformFile != NULL ) { for (int32 Index = 0; Index < ModifiedFiles.Num(); Index++) { InnerPlatformFile->DeleteFile(*ModifiedFiles[Index]); CachedLocalFiles.Remove(ModifiedFiles[Index]); ServerFiles.AddFileOrDirectory(ModifiedFiles[Index], FDateTime::UtcNow()); } } // let the handler process the response directly Handler->ProcessResponse(Response); } return true; }
bool FStreamingNetworkPlatformFile::DeleteDirectoryRecursively(const TCHAR* Directory) { FScopeLock ScopeLock(&SynchronizationObject); FStreamingNetworkFileArchive Payload(NFS_Messages::DeleteDirectoryRecursively); FString RelativeDirectory = Directory; MakeStandardNetworkFilename(RelativeDirectory); Payload << RelativeDirectory; // perform a local operation FArrayReader Response; if (SendPayloadAndReceiveResponse(Payload, Response) == false) { return false; } bool bSuccess = 0; Response << bSuccess; return bSuccess; }
void FStreamingNetworkPlatformFile::GetFileInfo(const TCHAR* Filename, FFileInfo& Info) { FScopeLock ScopeLock(&SynchronizationObject); FString RelativeFilename = Filename; MakeStandardNetworkFilename(RelativeFilename); if (!CachedFileInfo.Contains(RelativeFilename)) { FStreamingNetworkFileArchive Payload(NFS_Messages::GetFileInfo); Payload << const_cast<FString&>(RelativeFilename); // if (RelativeFilename == TEXT("../../../UDKGame/Content/Maps/GDC12_Ice/GDC_2012_Throne_Cave.uasset")) // { // Info.ReadOnly = true; // } // Send the filename over FArrayReader Response; if (SendPayloadAndReceiveResponse(Payload, Response) == false) { return; } // Get info from the response Response << Info.FileExists; Response << Info.ReadOnly; Response << Info.Size; Response << Info.TimeStamp; Response << Info.AccessTimeStamp; CachedFileInfo.Add(RelativeFilename, Info); } else { Info = *(CachedFileInfo.Find(RelativeFilename)); } }
bool FNetworkPlatformFile::InitializeInternal(IPlatformFile* Inner, const TCHAR* HostIP) { // This platform file requires an inner. check(Inner != NULL); InnerPlatformFile = Inner; if (HostIP == NULL) { UE_LOG(LogNetworkPlatformFile, Error, TEXT("No Host IP specified in the commandline.")); bIsUsable = false; return false; } // Save and Intermediate directories are always local LocalDirectories.Add(FPaths::EngineDir() / TEXT("Binaries")); LocalDirectories.Add(FPaths::EngineIntermediateDir()); LocalDirectories.Add(FPaths::GameDir() / TEXT("Binaries")); LocalDirectories.Add(FPaths::GameIntermediateDir()); LocalDirectories.Add(FPaths::GameSavedDir() / TEXT("Backup")); LocalDirectories.Add(FPaths::GameSavedDir() / TEXT("Config")); LocalDirectories.Add(FPaths::GameSavedDir() / TEXT("Logs")); LocalDirectories.Add(FPaths::GameSavedDir() / TEXT("Sandboxes")); InnerPlatformFile->GetLowerLevel()->AddLocalDirectories(LocalDirectories); FNetworkFileArchive Payload(NFS_Messages::Heartbeat); FArrayReader Out; if (!SendPayloadAndReceiveResponse(Payload,Out)) bIsUsable = true; // lets see we can test whether the server is up. if (Out.Num()) { FCommandLine::AddToSubprocessCommandline( *FString::Printf( TEXT("-FileHostIP=%s"), HostIP ) ); bIsUsable = true; } return bIsUsable; }
bool FStreamingNetworkPlatformFile::CopyFile(const TCHAR* To, const TCHAR* From, EPlatformFileRead ReadFlags, EPlatformFileWrite WriteFlags) { FScopeLock ScopeLock(&SynchronizationObject); FStreamingNetworkFileArchive Payload(NFS_Messages::CopyFile); FString RelativeTo = To; MakeStandardNetworkFilename(RelativeTo); FString RelativeFrom = From; MakeStandardNetworkFilename(RelativeFrom); Payload << RelativeTo; Payload << RelativeFrom; // perform a local operation FArrayReader Response; if (SendPayloadAndReceiveResponse(Payload, Response) == false) { return false; } bool bSuccess = 0; Response << bSuccess; return bSuccess; }
bool FStreamingNetworkPlatformFile::SendWriteMessage(uint64 HandleId, const uint8* Source, int64 BytesToWrite) { FScopeLock ScopeLock(&SynchronizationObject); // Send the filename over. FStreamingNetworkFileArchive Payload(NFS_Messages::Write); Payload << HandleId; // Send the data over Payload << BytesToWrite; Payload.Serialize(const_cast<uint8*>(Source), BytesToWrite); FArrayReader Response; if (SendPayloadAndReceiveResponse(Payload, Response) == false) { return false; } // Get the number of bytes the server wrote. int64 ServerBytesWritten = 0; Response << ServerBytesWritten; return (ServerBytesWritten == BytesToWrite); }
bool CHexarcSession::Connect (CString *retsError) // Connect // // Connect to the server (if not already connected) { // Already connected? if (m_Session.IsConnected()) return true; // Need host and root URL if (m_sHost.IsBlank() || m_sRootURL.IsBlank()) { *retsError = ERR_NO_SERVER_DEFINED; return false; } // Connect to host EInetsErrors iError = m_Session.Connect(m_sHost, m_sPort); if (iError != inetsOK) { switch (iError) { case inetsDNSError: *retsError = strPatternSubst(ERR_DNS_ERROR, GetHostspec()); kernelDebugLogMessage(*retsError); return false; case inetsCannotConnect: *retsError = strPatternSubst(ERR_CONNECT_ERROR, GetHostspec()); kernelDebugLogMessage(*retsError); return false; default: *retsError = strPatternSubst(ERR_INTERNAL, GetHostspec()); kernelDebugLogMessage(*retsError); return false; } } // Compose a connect payload CJSONValue Payload(CJSONValue::typeObject); Payload.InsertHandoff(FIELD_CLIENT_ID, CJSONValue(m_sClientID)); Payload.InsertHandoff(FIELD_CLIENT_VERSION, CJSONValue(GetClientVersion())); Payload.InsertHandoff(FIELD_PROTOCOL_VERSION, CJSONValue(TRANS_SERVICE_VERSION)); if (!m_sUsername.IsBlank()) Payload.InsertHandoff(FIELD_USERNAME, CJSONValue(m_sUsername)); // Now issue the connect command CHTTPMessage Request; InitRequest(METHOD_POST, FUNC_CONNECT_CLIENT, &Request); Request.SetBody(new CJSONMessage(Payload)); // Send the request and wait for response CHTTPMessage Response; if (iError = m_Session.Send(Request, &Response)) { m_Session.Disconnect(); *retsError = strPatternSubst(ERR_REQUEST_FAILED, GetHostspec()); kernelDebugLogMessage(*retsError); return false; } // If we got a 301 redirect then we try the whole thing again if (Response.GetStatusCode() == 301) { m_Session.Disconnect(); // LATER: Set up the new host and recurse // LATER: Keep track of recursion count, in case of ping-pong redirects *retsError = CONSTLIT("LATER: Redirect"); kernelDebugLogMessage(*retsError); return false; } // If we get an error, return else if (Response.GetStatusCode() != 200) { m_Session.Disconnect(); *retsError = strPatternSubst(ERR_FROM_SERVER, GetHostspec(), Response.GetStatusMsg()); kernelDebugLogMessage(*retsError); return false; } // Get the JSON response CJSONValue ResponseData; if (!GetJSONResponse(Response, &ResponseData, retsError)) { m_Session.Disconnect(); *retsError = strPatternSubst(ERR_INVALID_JSON, GetHostspec(), *retsError); return false; } // If this is an error, then return it if (CHexarc::IsError(ResponseData, NULL, retsError)) { m_Session.Disconnect(); kernelDebugLogMessage(*retsError); return false; } // LATER: Process return value (challenge) // Done return true; }
bool Connect (const CString &sHostspec, CHTTPClientSession &Session) { CString sHost; CString sPort; urlParseHostspec(sHostspec, &sHost, &sPort); EInetsErrors iError = Session.Connect(sHost, sPort); if (iError != inetsOK) { switch (iError) { case inetsDNSError: printf("Unable to resolve IP address for: %s\n", sHost.GetASCIIZPointer()); return false; case inetsCannotConnect: printf("Unable to connect to: %s\n", sHostspec.GetASCIIZPointer()); return false; default: printf("Unknown error connecting to: %s\n", sHostspec.GetASCIIZPointer()); return false; } } // Use a constant clientID (representing TransData) BYTE ClientIDBytes[4] = { 0, 1, 0, 1 }; CIntegerIP ClientID(4, ClientIDBytes); CString sClientID = ClientID.AsBase64(); // Compose a connect payload CJSONValue Payload(CJSONValue::typeObject); Payload.InsertHandoff(FIELD_CLIENT_ID, CJSONValue(sClientID)); Payload.InsertHandoff(FIELD_CLIENT_VERSION, CJSONValue(CLIENT_TYPE)); Payload.InsertHandoff(FIELD_PROTOCOL_VERSION, CJSONValue(TRANS_SERVICE_VERSION)); // Now issue the connect command CHTTPMessage Request; InitRequest(sHost, METHOD_POST, FUNC_CONNECT, &Request); Request.SetBody(new CJSONMessage(Payload)); // Send the request and wait for response CHTTPMessage Response; if (iError = Session.Send(Request, &Response)) { Session.Disconnect(); printf("Unable to send to: %s\n", sHostspec.GetASCIIZPointer()); return false; } // If we got a 301 redirect then we try the whole thing again if (Response.GetStatusCode() == 301) { Session.Disconnect(); // LATER: Set up the new host and recurse // LATER: Keep track of recursion count, in case of ping-pong redirects printf("REDIRECT\n"); return false; } // If we get an error, return else if (Response.GetStatusCode() != 200) { Session.Disconnect(); printf("[%d] %s\n", Response.GetStatusCode(), Response.GetStatusMsg().GetASCIIZPointer()); return false; } // Get the JSON response CString sError; CJSONValue ResponseData; if (!GetJSONResponse(Response, &ResponseData, &sError)) { Session.Disconnect(); printf("Unable to parse JSON reply: %s\n", sError.GetASCIIZPointer()); return false; } // Done printf("Connected to %s\n", sHostspec.GetASCIIZPointer()); return true; }
void FNetworkPlatformFile::InitializeAfterSetActive() { double NetworkFileStartupTime = 0.0; { SCOPE_SECONDS_COUNTER(NetworkFileStartupTime); // send the filenames and timestamps to the server FNetworkFileArchive Payload(NFS_Messages::GetFileList); FillGetFileList(Payload, false); // send the directories over, and wait for a response FArrayReader Response; if (!SendPayloadAndReceiveResponse(Payload, Response)) { delete Transport; return; } else { // receive the cooked version information int32 ServerPackageVersion = 0; int32 ServerPackageLicenseeVersion = 0; ProcessServerInitialResponse(Response, ServerPackageVersion, ServerPackageLicenseeVersion); // receive a list of the cache files and their timestamps TMap<FString, FDateTime> ServerCachedFiles; Response << ServerCachedFiles; bool bDeleteAllFiles = true; // Check the stored cooked version FString CookedVersionFile = FPaths::GeneratedConfigDir() / TEXT("CookedVersion.txt"); if (InnerPlatformFile->FileExists(*CookedVersionFile) == true) { IFileHandle* FileHandle = InnerPlatformFile->OpenRead(*CookedVersionFile); if (FileHandle != NULL) { int32 StoredPackageCookedVersion; int32 StoredPackageCookedLicenseeVersion; if (FileHandle->Read((uint8*)&StoredPackageCookedVersion, sizeof(int32)) == true) { if (FileHandle->Read((uint8*)&StoredPackageCookedLicenseeVersion, sizeof(int32)) == true) { if ((ServerPackageVersion == StoredPackageCookedVersion) && (ServerPackageLicenseeVersion == StoredPackageCookedLicenseeVersion)) { bDeleteAllFiles = false; } else { UE_LOG(LogNetworkPlatformFile, Display, TEXT("Engine version mismatch: Server %d.%d, Stored %d.%d\n"), ServerPackageVersion, ServerPackageLicenseeVersion, StoredPackageCookedVersion, StoredPackageCookedLicenseeVersion); } } } delete FileHandle; } } else { UE_LOG(LogNetworkPlatformFile, Display, TEXT("Cooked version file missing: %s\n"), *CookedVersionFile); } if (bDeleteAllFiles == true) { // Make sure the config file exists... InnerPlatformFile->CreateDirectoryTree(*(FPaths::GeneratedConfigDir())); // Update the cooked version file IFileHandle* FileHandle = InnerPlatformFile->OpenWrite(*CookedVersionFile); if (FileHandle != NULL) { FileHandle->Write((const uint8*)&ServerPackageVersion, sizeof(int32)); FileHandle->Write((const uint8*)&ServerPackageLicenseeVersion, sizeof(int32)); delete FileHandle; } } // list of directories to skip TArray<FString> DirectoriesToSkip; TArray<FString> DirectoriesToNotRecurse; // use the timestamp grabbing visitor to get all the content times FLocalTimestampDirectoryVisitor Visitor(*InnerPlatformFile, DirectoriesToSkip, DirectoriesToNotRecurse, false); TArray<FString> RootContentPaths; FPackageName::QueryRootContentPaths( RootContentPaths ); for( TArray<FString>::TConstIterator RootPathIt( RootContentPaths ); RootPathIt; ++RootPathIt ) { const FString& RootPath = *RootPathIt; const FString& ContentFolder = FPackageName::LongPackageNameToFilename(RootPath); InnerPlatformFile->IterateDirectory( *ContentFolder, Visitor); } // delete out of date files using the server cached files for (TMap<FString, FDateTime>::TIterator It(ServerCachedFiles); It; ++It) { bool bDeleteFile = bDeleteAllFiles; FString ServerFile = It.Key(); // Convert the filename to the client version ConvertServerFilenameToClientFilename(ServerFile); // Set it in the visitor file times list Visitor.FileTimes.Add(ServerFile, FDateTime::MinValue()); if (bDeleteFile == false) { // Check the time stamps... // get local time FDateTime LocalTime = InnerPlatformFile->GetTimeStamp(*ServerFile); // If local time == MinValue than the file does not exist in the cache. if (LocalTime != FDateTime::MinValue()) { FDateTime ServerTime = It.Value(); // delete if out of date // We will use 1.0 second as the tolerance to cover any platform differences in resolution FTimespan TimeDiff = LocalTime - ServerTime; double TimeDiffInSeconds = TimeDiff.GetTotalSeconds(); bDeleteFile = (TimeDiffInSeconds > 1.0) || (TimeDiffInSeconds < -1.0); if (bDeleteFile == true) { if (InnerPlatformFile->FileExists(*ServerFile) == true) { UE_LOG(LogNetworkPlatformFile, Display, TEXT("Deleting cached file: TimeDiff %5.3f, %s"), TimeDiffInSeconds, *It.Key()); } else { // It's a directory bDeleteFile = false; } } } } if (bDeleteFile == true) { InnerPlatformFile->DeleteFile(*ServerFile); } } // Any content files we have locally that were not cached, delete them for (TMap<FString, FDateTime>::TIterator It(Visitor.FileTimes); It; ++It) { if (It.Value() != FDateTime::MinValue()) { // This was *not* found in the server file list... delete it UE_LOG(LogNetworkPlatformFile, Display, TEXT("Deleting cached file: %s"), *It.Key()); InnerPlatformFile->DeleteFile(*It.Key()); } } // make sure we can sync a file FString TestSyncFile = FPaths::Combine(*(FPaths::EngineDir()), TEXT("Config/BaseEngine.ini")); InnerPlatformFile->SetReadOnly(*TestSyncFile, false); InnerPlatformFile->DeleteFile(*TestSyncFile); if (InnerPlatformFile->FileExists(*TestSyncFile)) { UE_LOG(LogNetworkPlatformFile, Fatal, TEXT("Could not delete file sync test file %s."), *TestSyncFile); } EnsureFileIsLocal(TestSyncFile); if (!InnerPlatformFile->FileExists(*TestSyncFile) || InnerPlatformFile->FileSize(*TestSyncFile) < 1) { UE_LOG(LogNetworkPlatformFile, Fatal, TEXT("Could not sync test file %s."), *TestSyncFile); } } } FPlatformMisc::LowLevelOutputDebugStringf(TEXT("Network file startup time: %5.3f seconds\n"), NetworkFileStartupTime); }
void FNetworkPlatformFile::EnsureFileIsLocal(const FString& Filename) { double StartTime; float ThisTime; StartTime = FPlatformTime::Seconds(); { FScopeLock ScopeLock(&SynchronizationObject); // have we already cached this file? if (CachedLocalFiles.Find(Filename) != NULL) { return; } } if ( FinishedAsyncNetworkReadUnsolicitedFiles ) { delete FinishedAsyncNetworkReadUnsolicitedFiles; // wait here for any async unsolicited files to finish reading being read from the network FinishedAsyncNetworkReadUnsolicitedFiles = NULL; } if( FinishedAsyncWriteUnsolicitedFiles) { delete FinishedAsyncWriteUnsolicitedFiles; // wait here for any async unsolicited files to finish writing to disk FinishedAsyncWriteUnsolicitedFiles = NULL; } FScopeLock ScopeLock(&SynchronizationObject); ThisTime = 1000.0f * float(FPlatformTime::Seconds() - StartTime); //UE_LOG(LogNetworkPlatformFile, Display, TEXT("Lock and wait for old async writes %6.2fms"), ThisTime); // have we already cached this file? (test again, since some other thread might have done this between waits) if (CachedLocalFiles.Find(Filename) != NULL) { return; } // even if an error occurs later, we still want to remember not to try again CachedLocalFiles.Add(Filename); StartTime = FPlatformTime::Seconds(); // no need to read it if it already exists // @todo: Handshake with server to delete files that are out of date if (InnerPlatformFile->FileExists(*Filename)) { return; } ThisTime = 1000.0f * float(FPlatformTime::Seconds() - StartTime); //UE_LOG(LogNetworkPlatformFile, Display, TEXT("Check for local file %6.2fms - %s"), ThisTime, *Filename); // this is a bit of a waste if we aren't doing cook on the fly, but we assume missing asset files are relatively rare bool bIsCookable = GConfig && GConfig->IsReadyForUse() && FPackageName::IsPackageExtension(*FPaths::GetExtension(Filename, true)); // we only copy files that actually exist on the server, can greatly reduce network traffic for, say, // the INT file each package tries to load if (!bIsCookable && ServerFiles.FindFile(Filename) == NULL) { // Uncomment this to have the server file list dumped // the first time a file requested is not found. #if 0 static bool sb_DumpedServer = false; if (sb_DumpedServer == false) { FPlatformMisc::LowLevelOutputDebugStringf(TEXT("Dumping server files... %s not found\n"), *Filename); for (TMap<FString, FServerTOC::FDirectory*>::TIterator ServerDumpIt(ServerFiles.Directories); ServerDumpIt; ++ServerDumpIt) { FServerTOC::FDirectory& Directory = *ServerDumpIt.Value(); for (FServerTOC::FDirectory::TIterator DirDumpIt(Directory); DirDumpIt; ++DirDumpIt) { FPlatformMisc::LowLevelOutputDebugStringf(TEXT("%10s - %s\n"), *(DirDumpIt.Value().ToString()), *(DirDumpIt.Key())); } } sb_DumpedServer = true; } #endif return; } // send the filename over (cast away const here because we know this << will not modify the string) FNetworkFileArchive Payload(NFS_Messages::SyncFile); Payload << (FString&)Filename; StartTime = FPlatformTime::Seconds(); // allocate array reader on the heap, because the SyncWriteFile function will delete it FArrayReader Response; if (!SendPayloadAndReceiveResponse(Payload, Response)) { UE_LOG(LogNetworkPlatformFile, Fatal, TEXT("Receive failure!")); return; } ThisTime = 1000.0f * float(FPlatformTime::Seconds() - StartTime); //UE_LOG(LogNetworkPlatformFile, Display, TEXT("Send and receive %6.2fms"), ThisTime); StartTime = FPlatformTime::Seconds(); FString ReplyFile; Response << ReplyFile; ConvertServerFilenameToClientFilename(ReplyFile); check(ReplyFile == Filename); // get the server file timestamp FDateTime ServerTimeStamp; Response << ServerTimeStamp; // write the file in chunks, synchronously SyncWriteFile(&Response, ReplyFile, ServerTimeStamp, *InnerPlatformFile); int32 NumUnsolictedFiles; Response << NumUnsolictedFiles; if (NumUnsolictedFiles) { check( FinishedAsyncNetworkReadUnsolicitedFiles == NULL ); check( FinishedAsyncWriteUnsolicitedFiles == NULL ); FinishedAsyncNetworkReadUnsolicitedFiles = new FScopedEvent; FinishedAsyncWriteUnsolicitedFiles = new FScopedEvent; AsyncReadUnsolicitedFiles(NumUnsolictedFiles, *this, *InnerPlatformFile, ServerEngineDir, ServerGameDir, FinishedAsyncNetworkReadUnsolicitedFiles, FinishedAsyncWriteUnsolicitedFiles); } ThisTime = 1000.0f * float(FPlatformTime::Seconds() - StartTime); //UE_LOG(LogNetworkPlatformFile, Display, TEXT("Write file to local %6.2fms"), ThisTime); }
/************************************************************************ CMinPack minimzation: *************************************************************************/ void SkeletonFitting::updateCMP(Joint* joint) { // TODO: use same minimization method also with MT_CMINPACK_CCD, just exchange the function if (!joint) { WARN << "joint invalid" << ENDL; // should never happen return; } // TODO: implement simple steepest descent method using the same functions const int i = 0; // if this is the root joint, also update the position if (!joint->getPrevJoint()) { const double tol = 0.000001; const double factor = 0.01; const double eps = 0.00001; const int iterFac = 50; cv::Point3d addPos(0, 0, 0); double addSize = 0; if (i == 0) { minimize(&Payload(joint, 0), funcPos, 1, 1, &addPos.x, tol, iterFac, factor, eps); minimize(&Payload(joint, 1), funcPos, 1, 1, &addPos.y, tol, iterFac, factor, eps); minimize(&Payload(joint, 2), funcPos, 1, 1, &addPos.z, tol, iterFac, factor, eps); if (m_minimizeSize) minimize(&Payload(joint, 2), funcSize, 1, 1, &addSize, tol, iterFac, factor, eps); } else { /*minimizeSteepestDesc(&Payload(joint, 0), funcPos, 1, 1, &addPos.x); minimizeSteepestDesc(&Payload(joint, 1), funcPos, 1, 1, &addPos.y); minimizeSteepestDesc(&Payload(joint, 2), funcPos, 1, 1, &addPos.z); if (m_minimizeSize) minimizeSteepestDesc(&Payload(joint, 2), funcSize, 1, 1, &addSize);*/ } joint->addPos3d(addPos); joint->addBoneSize(addSize); joint->updateForward(false); // changing position doesn't need constraint checking } // update joint angles const double tol = 0.001; const int iterFac = 50; double factor = 100; double eps = 0.001; switch (joint->getClass()) { case JC_BALLANDSOCKET: { // update ball and socket joints JointBallAndSocket* jointBAS = (JointBallAndSocket*)joint; // update angles cv::Point3d addRot(0, 0, 0); if (i == 0) { minimize(&Payload(joint, 0), funcBAS, 1, 1, &addRot.x, tol, iterFac, factor, eps); minimize(&Payload(joint, 1), funcBAS, 1, 1, &addRot.y, tol, iterFac, factor, eps); minimize(&Payload(joint, 2), funcBAS, 1, 1, &addRot.z, tol, iterFac, factor, eps); } else { //minimizeSteepestDesc(&Payload(joint, 0), funcBAS, 1, 1, &addRot.x); //minimizeSteepestDesc(&Payload(joint, 1), funcBAS, 1, 1, &addRot.y); //minimizeSteepestDesc(&Payload(joint, 2), funcBAS, 1, 1, &addRot.z); } jointBAS->addOrientation(addRot); jointBAS->updateForward(true); break; } case JC_HINGE: { // update hinge joints JointHinge* jointHinge = (JointHinge*)joint; // update angles double addAngle = 0; if (i == 0) { minimize(&Payload(joint, 0), funcHinge, 1, 1, &addAngle, tol, iterFac, factor, eps); } else { //minimizeSteepestDesc(&Payload(joint, 0), funcHinge, 1, 1, &addAngle); } jointHinge->addAngle(addAngle); jointHinge->updateForward(true); break; } case JC_ENDCONNECTOR: // no need to update end connector joints, their position is only // affected by their subordinate joints break; case JC_CONNECTOR: // does also not need to be updated break; default: WARN << "unknown joint type: " << (int)joint->getClass() << ENDL; break; } // if this is not the root joint, update the next previous joint if (joint->getPrevJoint()) updateCMP(joint->getPrevJoint()); }