本文整理汇总了C++中FP4RecordSet::Num方法的典型用法代码示例。如果您正苦于以下问题:C++ FP4RecordSet::Num方法的具体用法?C++ FP4RecordSet::Num怎么用?C++ FP4RecordSet::Num使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类FP4RecordSet
的用法示例。
在下文中一共展示了FP4RecordSet::Num方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: ParseDiffResults
static void ParseDiffResults(const FP4RecordSet& InRecords, TArray<FString>& OutModifiedFiles)
{
if (InRecords.Num() > 0)
{
// Iterate over each record found as a result of the command, parsing it for relevant information
for (int32 Index = 0; Index < InRecords.Num(); ++Index)
{
const FP4Record& ClientRecord = InRecords[Index];
FString FileName = ClientRecord(TEXT("clientFile"));
FPaths::NormalizeFilename(FileName);
OutModifiedFiles.Add(FileName);
}
}
}
示例2: ParseFilesResults
static void ParseFilesResults(const FP4RecordSet& InRecords, TArray< TSharedRef<ISourceControlRevision, ESPMode::ThreadSafe> >& OutRevisions, const FString& InClientRoot)
{
// Iterate over each record found as a result of the command, parsing it for relevant information
for (int32 Index = 0; Index < InRecords.Num(); ++Index)
{
const FP4Record& ClientRecord = InRecords[Index];
FString DepotFile = ClientRecord(TEXT("depotFile"));
FString RevisionNumber = ClientRecord(TEXT("rev"));
FString Date = ClientRecord(TEXT("time"));
FString ChangelistNumber = ClientRecord(TEXT("change"));
FString Action = ClientRecord(TEXT("action"));
check(RevisionNumber.Len() != 0);
// @todo: this revision is incomplete, but is sufficient for now given the usage of labels to get files, rather
// than review revision histories.
TSharedRef<FPerforceSourceControlRevision, ESPMode::ThreadSafe> Revision = MakeShareable( new FPerforceSourceControlRevision() );
Revision->FileName = DepotFile;
Revision->RevisionNumber = FCString::Atoi(*RevisionNumber);
Revision->ChangelistNumber = FCString::Atoi(*ChangelistNumber);
Revision->Action = Action;
Revision->Date = FDateTime(1970, 1, 1, 0, 0, 0, 0) + FTimespan(0, 0, FCString::Atoi(*Date));
OutRevisions.Add(Revision);
}
}
示例3: ParseRecordSetForState
/** Simple parsing of a record set to update state */
static void ParseRecordSetForState(const FP4RecordSet& InRecords, TMap<FString, EPerforceState::Type>& OutResults)
{
// Iterate over each record found as a result of the command, parsing it for relevant information
for (int32 Index = 0; Index < InRecords.Num(); ++Index)
{
const FP4Record& ClientRecord = InRecords[Index];
FString FileName = ClientRecord(TEXT("clientFile"));
FString Action = ClientRecord(TEXT("action"));
check(FileName.Len());
FString FullPath(FileName);
FPaths::NormalizeFilename(FullPath);
if(Action.Len() > 0)
{
if(Action == TEXT("add"))
{
OutResults.Add(FullPath, EPerforceState::OpenForAdd);
}
else if(Action == TEXT("edit"))
{
OutResults.Add(FullPath, EPerforceState::CheckedOut);
}
else if(Action == TEXT("delete"))
{
OutResults.Add(FullPath, EPerforceState::MarkedForDelete);
}
else if(Action == TEXT("abandoned"))
{
OutResults.Add(FullPath, EPerforceState::NotInDepot);
}
else if(Action == TEXT("reverted"))
{
FString OldAction = ClientRecord(TEXT("oldAction"));
if(OldAction == TEXT("add"))
{
OutResults.Add(FullPath, EPerforceState::NotInDepot);
}
else if(OldAction == TEXT("edit"))
{
OutResults.Add(FullPath, EPerforceState::ReadOnly);
}
else if(OldAction == TEXT("delete"))
{
OutResults.Add(FullPath, EPerforceState::ReadOnly);
}
}
else if(Action == TEXT("branch"))
{
OutResults.Add(FullPath, EPerforceState::Branched);
}
}
}
}
示例4: ParseOpenedResults
static void ParseOpenedResults(const FP4RecordSet& InRecords, const FString& ClientName, const FString& ClientRoot, TMap<FString, EPerforceState::Type>& OutResults)
{
// Iterate over each record found as a result of the command, parsing it for relevant information
for (int32 Index = 0; Index < InRecords.Num(); ++Index)
{
const FP4Record& ClientRecord = InRecords[Index];
FString ClientFileName = ClientRecord(TEXT("clientFile"));
FString Action = ClientRecord(TEXT("action"));
check(ClientFileName.Len() > 0);
// Convert the depot file name to a local file name
FString FullPath = ClientFileName;
const FString PathRoot = FString::Printf(TEXT("//%s"), *ClientName);
if (FullPath.StartsWith(PathRoot))
{
const bool bIsNullClientRootPath = (ClientRoot == TEXT("null"));
if ( bIsNullClientRootPath )
{
// Null clients use the pattern in PathRoot: //Workspace/FileName
// Here we chop off the '//Workspace/' to return the workspace filename
FullPath = FullPath.RightChop(PathRoot.Len() + 1);
}
else
{
// This is a normal workspace where we can simply replace the pathroot with the client root to form the filename
FullPath = FullPath.Replace(*PathRoot, *ClientRoot);
}
}
else
{
// This file is not in the workspace, ignore it
continue;
}
if (Action.Len() > 0)
{
if(Action == TEXT("add"))
{
OutResults.Add(FullPath, EPerforceState::OpenForAdd);
}
else if(Action == TEXT("edit"))
{
OutResults.Add(FullPath, EPerforceState::CheckedOut);
}
else if(Action == TEXT("delete"))
{
OutResults.Add(FullPath, EPerforceState::MarkedForDelete);
}
}
}
}
示例5: ParseRecordSet
/** Simple parsing of a record set into strings, one string per record */
static void ParseRecordSet(const FP4RecordSet& InRecords, TArray<FText>& OutResults)
{
const FString Delimiter = FString(TEXT(" "));
for (int32 RecordIndex = 0; RecordIndex < InRecords.Num(); ++RecordIndex)
{
const FP4Record& ClientRecord = InRecords[RecordIndex];
for(FP4Record::TConstIterator It = ClientRecord.CreateConstIterator(); It; ++It)
{
OutResults.Add(FText::FromString(It.Key() + Delimiter + It.Value()));
}
}
}
示例6: ParseGetLabelsResults
static void ParseGetLabelsResults(const FP4RecordSet& InRecords, TArray< TSharedRef<ISourceControlLabel> >& OutLabels)
{
// Iterate over each record found as a result of the command, parsing it for relevant information
for (int32 Index = 0; Index < InRecords.Num(); ++Index)
{
const FP4Record& ClientRecord = InRecords[Index];
FString LabelName = ClientRecord(TEXT("label"));
if(LabelName.Len() > 0)
{
OutLabels.Add(MakeShareable( new FPerforceSourceControlLabel(LabelName) ) );
}
}
}
示例7: ParseSubmitResults
static FText ParseSubmitResults(const FP4RecordSet& InRecords)
{
// Iterate over each record found as a result of the command, parsing it for relevant information
for (int32 Index = 0; Index < InRecords.Num(); ++Index)
{
const FP4Record& ClientRecord = InRecords[Index];
const FString SubmittedChange = ClientRecord(TEXT("submittedChange"));
if(SubmittedChange.Len() > 0)
{
return FText::Format(LOCTEXT("SubmitMessage", "Submitted changelist {0}"), FText::FromString(SubmittedChange));
}
}
return LOCTEXT("SubmitMessageUnknown", "Submitted changelist");
}
示例8: CheckUnicodeStatus
static bool CheckUnicodeStatus(ClientApi& P4Client, bool& bIsUnicodeServer, TArray<FText>& OutErrorMessages)
{
#if USE_P4_API
FP4RecordSet Records;
FP4ClientUser User(Records, false, OutErrorMessages);
P4Client.Run("info", &User);
if(Records.Num() > 0)
{
bIsUnicodeServer = Records[0].Find(TEXT("unicode")) != NULL;
}
else
{
bIsUnicodeServer = false;
}
#endif
return OutErrorMessages.Num() == 0;
}
示例9: Execute
bool FPerforceConnectWorker::Execute(FPerforceSourceControlCommand& InCommand)
{
FScopedPerforceConnection ScopedConnection(InCommand);
if (!InCommand.IsCanceled() && ScopedConnection.IsValid())
{
FPerforceConnection& Connection = ScopedConnection.GetConnection();
TArray<FString> Parameters;
FP4RecordSet Records;
Parameters.Add(TEXT("-o"));
Parameters.Add(InCommand.ConnectionInfo.Workspace);
InCommand.bCommandSuccessful = Connection.RunCommand(TEXT("client"), Parameters, Records, InCommand.ErrorMessages, FOnIsCancelled::CreateRaw(&InCommand, &FPerforceSourceControlCommand::IsCanceled), InCommand.bConnectionDropped);
// If there are error messages, user name is most likely invalid. Otherwise, make sure workspace actually
// exists on server by checking if we have it's update date.
InCommand.bCommandSuccessful &= InCommand.ErrorMessages.Num() == 0 && Records.Num() > 0 && Records[0].Contains(TEXT("Update"));
if (!InCommand.bCommandSuccessful && InCommand.ErrorMessages.Num() == 0)
{
InCommand.ErrorMessages.Add(LOCTEXT("InvalidWorkspace", "Invalid workspace."));
}
// check if we can actually work with this workspace
if(InCommand.bCommandSuccessful)
{
FText Notification;
InCommand.bCommandSuccessful = CheckWorkspaceRecordSet(Records, InCommand.ErrorMessages, Notification);
if(!InCommand.bCommandSuccessful)
{
check(InCommand.Operation->GetName() == GetName());
TSharedRef<FConnect, ESPMode::ThreadSafe> Operation = StaticCastSharedRef<FConnect>(InCommand.Operation);
Operation->SetErrorText(Notification);
}
}
if(InCommand.bCommandSuccessful)
{
ParseRecordSet(Records, InCommand.InfoMessages);
}
}
return InCommand.bCommandSuccessful;
}
示例10: ParseSyncResults
static void ParseSyncResults(const FP4RecordSet& InRecords, TMap<FString, EPerforceState::Type>& OutResults)
{
// Iterate over each record found as a result of the command, parsing it for relevant information
for (int32 Index = 0; Index < InRecords.Num(); ++Index)
{
const FP4Record& ClientRecord = InRecords[Index];
FString FileName = ClientRecord(TEXT("clientFile"));
FString Action = ClientRecord(TEXT("action"));
check(FileName.Len());
FString FullPath(FileName);
FPaths::NormalizeFilename(FullPath);
if(Action.Len() > 0)
{
if(Action == TEXT("updated"))
{
OutResults.Add(FullPath, EPerforceState::ReadOnly);
}
}
}
}
示例11: TestConnection
/**
* Runs "client" command to test if the connection is actually OK. ClientApi::Init() only checks
* if it can connect to server, doesn't verify user name nor workspace name.
*/
static bool TestConnection(ClientApi& P4Client, const FString& ClientSpecName, bool bIsUnicodeServer, TArray<FText>& OutErrorMessages)
{
FP4RecordSet Records;
FP4ClientUser User(Records, bIsUnicodeServer, OutErrorMessages);
UTF8CHAR* ClientSpecUTF8Name = nullptr;
if(bIsUnicodeServer)
{
FTCHARToUTF8 UTF8String(*ClientSpecName);
ClientSpecUTF8Name = new UTF8CHAR[UTF8String.Length() + 1];
FMemory::Memcpy(ClientSpecUTF8Name, UTF8String.Get(), UTF8String.Length() + 1);
}
else
{
ClientSpecUTF8Name = new UTF8CHAR[ClientSpecName.Len() + 1];
FMemory::Memcpy(ClientSpecUTF8Name, TCHAR_TO_ANSI(*ClientSpecName), ClientSpecName.Len() + 1);
}
const char *ArgV[] = { "-o", (char*)ClientSpecUTF8Name };
#if USE_P4_API
P4Client.SetArgv(2, const_cast<char*const*>(ArgV));
P4Client.Run("client", &User);
#endif
// clean up args
delete [] ClientSpecUTF8Name;
// If there are error messages, user name is most likely invalid. Otherwise, make sure workspace actually
// exists on server by checking if we have it's update date.
bool bConnectionOK = OutErrorMessages.Num() == 0 && Records.Num() > 0 && Records[0].Contains(TEXT("Update"));
if (!bConnectionOK && OutErrorMessages.Num() == 0)
{
OutErrorMessages.Add(LOCTEXT("InvalidWorkspace", "Invalid Workspace"));
}
return bConnectionOK;
}
示例12: ParseHistoryResults
static void ParseHistoryResults(const FP4RecordSet& InRecords, const TArray<FPerforceSourceControlState>& InStates, FPerforceUpdateStatusWorker::FHistoryMap& OutHistory)
{
if (InRecords.Num() > 0)
{
// Iterate over each record, extracting the relevant information for each
for (int32 RecordIndex = 0; RecordIndex < InRecords.Num(); ++RecordIndex)
{
const FP4Record& ClientRecord = InRecords[RecordIndex];
// Extract the file name
check(ClientRecord.Contains(TEXT("depotFile")));
FString DepotFileName = ClientRecord(TEXT("depotFile"));
FString LocalFileName = FindWorkspaceFile(InStates, DepotFileName);
TArray< TSharedRef<FPerforceSourceControlRevision, ESPMode::ThreadSafe> > Revisions;
int32 RevisionNumbers = 0;
for (;;)
{
// Extract the revision number
FString VarName = FString::Printf(TEXT("rev%d"), RevisionNumbers);
if (!ClientRecord.Contains(*VarName))
{
// No more revisions
break;
}
FString RevisionNumber = ClientRecord(*VarName);
// Extract the user name
VarName = FString::Printf(TEXT("user%d"), RevisionNumbers);
check(ClientRecord.Contains(*VarName));
FString UserName = ClientRecord(*VarName);
// Extract the date
VarName = FString::Printf(TEXT("time%d"), RevisionNumbers);
check(ClientRecord.Contains(*VarName));
FString Date = ClientRecord(*VarName);
// Extract the changelist number
VarName = FString::Printf(TEXT("change%d"), RevisionNumbers);
check(ClientRecord.Contains(*VarName));
FString ChangelistNumber = ClientRecord(*VarName);
// Extract the description
VarName = FString::Printf(TEXT("desc%d"), RevisionNumbers);
check(ClientRecord.Contains(*VarName));
FString Description = ClientRecord(*VarName);
// Extract the action
VarName = FString::Printf(TEXT("action%d"), RevisionNumbers);
check(ClientRecord.Contains(*VarName));
FString Action = ClientRecord(*VarName);
FString FileSize(TEXT("0"));
// Extract the file size
if(Action.ToLower() != TEXT("delete") && Action.ToLower() != TEXT("move/delete")) //delete actions don't have a fileSize from PV4
{
VarName = FString::Printf(TEXT("fileSize%d"), RevisionNumbers);
check(ClientRecord.Contains(*VarName));
FileSize = ClientRecord(*VarName);
}
// Extract the clientspec/workspace
VarName = FString::Printf(TEXT("client%d"), RevisionNumbers);
check(ClientRecord.Contains(*VarName));
FString ClientSpec = ClientRecord(*VarName);
// check for branch
TSharedPtr<FPerforceSourceControlRevision, ESPMode::ThreadSafe> BranchSource;
VarName = FString::Printf(TEXT("how%d,0"), RevisionNumbers);
if(ClientRecord.Contains(*VarName))
{
BranchSource = MakeShareable( new FPerforceSourceControlRevision() );
VarName = FString::Printf(TEXT("file%d,0"), RevisionNumbers);
FString BranchSourceFileName = ClientRecord(*VarName);
BranchSource->FileName = FindWorkspaceFile(InStates, BranchSourceFileName);
VarName = FString::Printf(TEXT("erev%d,0"), RevisionNumbers);
FString BranchSourceRevision = ClientRecord(*VarName);
BranchSource->RevisionNumber = FCString::Atoi(*BranchSourceRevision);
}
TSharedRef<FPerforceSourceControlRevision, ESPMode::ThreadSafe> Revision = MakeShareable( new FPerforceSourceControlRevision() );
Revision->FileName = LocalFileName;
Revision->RevisionNumber = FCString::Atoi(*RevisionNumber);
Revision->Revision = RevisionNumber;
Revision->ChangelistNumber = FCString::Atoi(*ChangelistNumber);
Revision->Description = Description;
Revision->UserName = UserName;
Revision->ClientSpec = ClientSpec;
Revision->Action = Action;
Revision->BranchSource = BranchSource;
Revision->Date = FDateTime(1970, 1, 1, 0, 0, 0, 0) + FTimespan::FromSeconds(FCString::Atoi(*Date));
Revision->FileSize = FCString::Atoi(*FileSize);
Revisions.Add(Revision);
RevisionNumbers++;
}
//.........这里部分代码省略.........
示例13: ParseUpdateStatusResults
static void ParseUpdateStatusResults(const FP4RecordSet& InRecords, const TArray<FText>& ErrorMessages, TArray<FPerforceSourceControlState>& OutStates)
{
// Iterate over each record found as a result of the command, parsing it for relevant information
for (int32 Index = 0; Index < InRecords.Num(); ++Index)
{
const FP4Record& ClientRecord = InRecords[Index];
FString FileName = ClientRecord(TEXT("clientFile"));
FString DepotFileName = ClientRecord(TEXT("depotFile"));
FString HeadRev = ClientRecord(TEXT("headRev"));
FString HaveRev = ClientRecord(TEXT("haveRev"));
FString OtherOpen = ClientRecord(TEXT("otherOpen"));
FString OpenType = ClientRecord(TEXT("type"));
FString HeadAction = ClientRecord(TEXT("headAction"));
FString Action = ClientRecord(TEXT("action"));
FString HeadType = ClientRecord(TEXT("headType"));
const bool bUnresolved = ClientRecord.Contains(TEXT("unresolved"));
FString FullPath(FileName);
FPaths::NormalizeFilename(FullPath);
OutStates.Add(FPerforceSourceControlState(FullPath));
FPerforceSourceControlState& State = OutStates.Last();
State.DepotFilename = DepotFileName;
State.State = EPerforceState::ReadOnly;
if (Action.Len() > 0 && Action == TEXT("add"))
{
State.State = EPerforceState::OpenForAdd;
}
else if (Action.Len() > 0 && Action == TEXT("delete"))
{
State.State = EPerforceState::MarkedForDelete;
}
else if (OpenType.Len() > 0)
{
if(Action.Len() > 0 && Action == TEXT("branch"))
{
State.State = EPerforceState::Branched;
}
else
{
State.State = EPerforceState::CheckedOut;
}
}
else if (OtherOpen.Len() > 0)
{
// OtherOpen just reports the number of developers that have a file open, now add a string for every entry
int32 OtherOpenNum = FCString::Atoi(*OtherOpen);
for ( int32 OpenIdx = 0; OpenIdx < OtherOpenNum; ++OpenIdx )
{
const FString OtherOpenRecordKey = FString::Printf(TEXT("otherOpen%d"), OpenIdx);
const FString OtherOpenRecordValue = ClientRecord(OtherOpenRecordKey);
State.OtherUserCheckedOut += OtherOpenRecordValue;
if(OpenIdx < OtherOpenNum - 1)
{
State.OtherUserCheckedOut += TEXT(", ");
}
}
State.State = EPerforceState::CheckedOutOther;
}
//file has been previously deleted, ok to add again
else if (HeadAction.Len() > 0 && HeadAction == TEXT("delete"))
{
State.State = EPerforceState::NotInDepot;
}
if (HeadRev.Len() > 0 && HaveRev.Len() > 0)
{
TTypeFromString<int>::FromString(State.DepotRevNumber, *HeadRev);
TTypeFromString<int>::FromString(State.LocalRevNumber, *HaveRev);
if( bUnresolved )
{
int32 ResolveActionNumber = 0;
for (;;)
{
// Extract the revision number
FString VarName = FString::Printf(TEXT("resolveAction%d"), ResolveActionNumber);
if (!ClientRecord.Contains(*VarName))
{
// No more revisions
ensureMsgf( ResolveActionNumber > 0, TEXT("Resolve is pending but no resolve actions for file %s"), *FileName );
break;
}
VarName = FString::Printf(TEXT("resolveBaseFile%d"), ResolveActionNumber);
FString ResolveBaseFile = ClientRecord(VarName);
VarName = FString::Printf(TEXT("resolveFromFile%d"), ResolveActionNumber);
FString ResolveFromFile = ClientRecord(VarName);
if(!ensureMsgf( ResolveFromFile == ResolveBaseFile, TEXT("Text cannot resolve %s with %s, we do not support cross file merging"), *ResolveBaseFile, *ResolveFromFile ) )
{
break;
}
VarName = FString::Printf(TEXT("resolveBaseRev%d"), ResolveActionNumber);
FString ResolveBaseRev = ClientRecord(VarName);
TTypeFromString<int>::FromString(State.PendingResolveRevNumber, *ResolveBaseRev);
++ResolveActionNumber;
//.........这里部分代码省略.........
示例14: RunCommand
bool FPerforceConnection::RunCommand(const FString& InCommand, const TArray<FString>& InParameters, FP4RecordSet& OutRecordSet, TArray<FText>& OutErrorMessage, FOnIsCancelled InIsCancelled, bool& OutConnectionDropped, const bool bInStandardDebugOutput, const bool bInAllowRetry)
{
#if USE_P4_API
if (!bEstablishedConnection)
{
return false;
}
FString FullCommand = InCommand;
// Prepare arguments
int32 ArgC = InParameters.Num();
UTF8CHAR** ArgV = new UTF8CHAR*[ArgC];
for (int32 Index = 0; Index < ArgC; Index++)
{
if(bIsUnicode)
{
FTCHARToUTF8 UTF8String(*InParameters[Index]);
ArgV[Index] = new UTF8CHAR[UTF8String.Length() + 1];
FMemory::Memcpy(ArgV[Index], UTF8String.Get(), UTF8String.Length() + 1);
}
else
{
ArgV[Index] = new UTF8CHAR[InParameters[Index].Len() + 1];
FMemory::Memcpy(ArgV[Index], TCHAR_TO_ANSI(*InParameters[Index]), InParameters[Index].Len() + 1);
}
if (bInStandardDebugOutput)
{
FullCommand += TEXT(" ");
FullCommand += InParameters[Index];
}
}
if (bInStandardDebugOutput)
{
UE_LOG( LogSourceControl, Log, TEXT("Attempting 'p4 %s'"), *FullCommand );
}
double SCCStartTime = FPlatformTime::Seconds();
P4Client.SetArgv(ArgC, (char**)ArgV);
FP4KeepAlive KeepAlive(InIsCancelled);
P4Client.SetBreak(&KeepAlive);
OutRecordSet.Reset();
FP4ClientUser User(OutRecordSet, bIsUnicode, OutErrorMessage);
P4Client.Run(FROM_TCHAR(*InCommand, bIsUnicode), &User);
if ( P4Client.Dropped() )
{
OutConnectionDropped = true;
}
P4Client.SetBreak(NULL);
// Free arguments
for (int32 Index = 0; Index < ArgC; Index++)
{
delete [] ArgV[Index];
}
delete [] ArgV;
if (bInStandardDebugOutput)
{
UE_LOG( LogSourceControl, VeryVerbose, TEXT("P4 execution time: %0.4f seconds. Command: %s"), FPlatformTime::Seconds() - SCCStartTime, *FullCommand );
}
#endif
return OutRecordSet.Num() > 0;
}
示例15: GetWorkspaceList
bool FPerforceConnection::GetWorkspaceList(const FPerforceConnectionInfo& InConnectionInfo, FOnIsCancelled InOnIsCanceled, TArray<FString>& OutWorkspaceList, TArray<FText>& OutErrorMessages)
{
if(bEstablishedConnection)
{
TArray<FString> Params;
bool bAllowWildHosts = !GIsBuildMachine;
Params.Add(TEXT("-u"));
Params.Add(InConnectionInfo.UserName);
FP4RecordSet Records;
bool bConnectionDropped = false;
bool bCommandOK = RunCommand(TEXT("clients"), Params, Records, OutErrorMessages, InOnIsCanceled, bConnectionDropped);
if (bCommandOK)
{
FString ApplicationPath = IFileManager::Get().ConvertToAbsolutePathForExternalAppForRead(*FPaths::GameDir()).ToLower();
FString LocalHostName = InConnectionInfo.HostOverride;
if(LocalHostName.Len() == 0)
{
// No host override, check environment variable
TCHAR P4HostEnv[256];
FPlatformMisc::GetEnvironmentVariable(TEXT("P4HOST"), P4HostEnv, ARRAY_COUNT(P4HostEnv));
LocalHostName = P4HostEnv;
}
if (LocalHostName.Len() == 0)
{
// no host name, use local machine name
LocalHostName = FString(FPlatformProcess::ComputerName()).ToLower();
}
else
{
LocalHostName = LocalHostName.ToLower();
}
for (int32 Index = 0; Index < Records.Num(); ++Index)
{
const FP4Record& ClientRecord = Records[Index];
FString ClientName = ClientRecord("client");
FString HostName = ClientRecord("Host");
FString ClientRootPath = ClientRecord("Root").ToLower();
//this clientspec has to be meant for this machine ( "" hostnames mean any host can use ths clientspec in p4 land)
bool bHostNameMatches = (LocalHostName == HostName.ToLower());
bool bHostNameWild = (HostName.Len() == 0);
if( bHostNameMatches || (bHostNameWild && bAllowWildHosts) )
{
// A workspace root could be "null" which allows the user to map depot locations to different drives.
// Allow these workspaces since we already allow workspaces mapped to drive letters.
const bool bIsNullClientRootPath = (ClientRootPath == TEXT("null"));
//make sure all slashes point the same way
ClientRootPath = ClientRootPath.Replace(TEXT("\\"), TEXT("/"));
ApplicationPath = ApplicationPath.Replace(TEXT("\\"), TEXT("/"));
if (!ClientRootPath.EndsWith(TEXT("/")))
{
ClientRootPath += TEXT("/");
}
// Only allow paths that are ACTUALLY legit for this application
if (bIsNullClientRootPath || ApplicationPath.Contains(ClientRootPath) )
{
OutWorkspaceList.Add(ClientName);
}
else
{
UE_LOG(LogSourceControl, Error, TEXT(" %s client specs rejected due to root directory mismatch (%s)"), *ClientName, *ClientRootPath);
}
//Other useful fields: Description, Owner, Host
}
else
{
UE_LOG(LogSourceControl, Error, TEXT(" %s client specs rejected due to host name mismatch (%s)"), *ClientName, *HostName);
}
}
}
return bCommandOK;
}
return false;
}