Esempio n. 1
0
	// Called by P4API on "change -i" command. OutBuffer is filled with changelist specification text
	void InputData(StrBuf* OutBuffer, Error* OutError)
	{
#if USE_P4_API
		FString OutputDesc;
		OutputDesc += TEXT("Change:\tnew\n\n");
		OutputDesc += TEXT("Client:\t");
		OutputDesc += TO_TCHAR(P4Client.GetClient().Text(), bIsUnicodeServer);
		OutputDesc += TEXT("\n\n");
		OutputDesc += TEXT("User:\t");
		OutputDesc += TO_TCHAR(P4Client.GetUser().Text(), bIsUnicodeServer);
		OutputDesc += TEXT("\n\n");
		OutputDesc += TEXT("Status:\tnew\n\n");
		OutputDesc += TEXT("Description:\n");
		{
			TArray<FString> DescLines;
			Description.ToString().ParseIntoArray(DescLines, TEXT("\n"), false);
			for (const FString& DescLine : DescLines)
			{
				OutputDesc += TEXT("\t");
				OutputDesc += DescLine;
				OutputDesc += TEXT("\n");
			}
		}
		OutputDesc += TEXT("\n");
		OutputDesc += TEXT("Files:\n\n");

		OutBuffer->Append(FROM_TCHAR(*OutputDesc, bIsUnicodeServer));
#endif
	}
	// Called by P4API on "change -i" command. OutBuffer is filled with changelist specification text
	void InputData(StrBuf* OutBuffer, Error* OutError)
	{
		FString OutputDesc;
		OutputDesc += TEXT("Change:\tnew\n\n");
		OutputDesc += TEXT("Client:\t");
		OutputDesc += TO_TCHAR(P4Client.GetClient().Text(), bIsUnicodeServer);
		OutputDesc += TEXT("\n\n");
		OutputDesc += TEXT("User:\t");
		OutputDesc += TO_TCHAR(P4Client.GetUser().Text(), bIsUnicodeServer);
		OutputDesc += "\n\n";
		OutputDesc += "Status:\tnew\n\n";
		OutputDesc += "Description:\n\t";
		OutputDesc += Description;
		OutputDesc += TEXT("\n\n");
		OutputDesc += TEXT("Files:\n\n");

		OutBuffer->Append(FROM_TCHAR(*OutputDesc, bIsUnicodeServer));
	}
Esempio n. 3
0
void FPerforceConnection::EstablishConnection(const FPerforceConnectionInfo& InConnectionInfo)
{
#if USE_P4_API
	// Verify Input. ServerName and UserName are required
	if ( InConnectionInfo.Port.IsEmpty() || InConnectionInfo.UserName.IsEmpty() )
	{
		return;
	}

	//Connection assumed successful
	bEstablishedConnection = true;

	UE_LOG(LogSourceControl, Verbose, TEXT("Attempting P4 connection: %s/%s"), *InConnectionInfo.Port, *InConnectionInfo.UserName);

	P4Client.SetProtocol("tag", "");
	P4Client.SetProtocol("enableStreams", "");

	//Set configuration based params
	P4Client.SetPort(TCHAR_TO_ANSI(*InConnectionInfo.Port));

	Error P4Error;
	if(InConnectionInfo.Password.Len() > 0)
	{
		UE_LOG(LogSourceControl, Verbose, TEXT(" ... applying password" ));
		P4Client.DefinePassword(TCHAR_TO_ANSI(*InConnectionInfo.Password), &P4Error);
		if(P4Error.Test())
		{
			StrBuf ErrorMessage;
			P4Error.Fmt(&ErrorMessage);
			UE_LOG(LogSourceControl, Error, TEXT("P4ERROR: Could not set password."));
			UE_LOG(LogSourceControl, Error, TEXT("%s"), ANSI_TO_TCHAR(ErrorMessage.Text()));
		}
	}

	if(InConnectionInfo.HostOverride.Len() > 0)
	{
		UE_LOG(LogSourceControl, Verbose, TEXT(" ... overriding host" ));
		P4Client.SetHost(TCHAR_TO_ANSI(*InConnectionInfo.HostOverride));
	}

	UE_LOG(LogSourceControl, Verbose, TEXT(" ... connecting" ));

	//execute the connection to perforce using the above settings
	P4Client.Init(&P4Error);

	//ensure the connection is valid
	UE_LOG(LogSourceControl, Verbose, TEXT(" ... validating connection" ));
	if (P4Error.Test())
	{
		bEstablishedConnection = false;
		StrBuf ErrorMessage;
		P4Error.Fmt(&ErrorMessage);

		UE_LOG(LogSourceControl, Error, TEXT("P4ERROR: Invalid connection to server."));
		UE_LOG(LogSourceControl, Error, TEXT("%s"), ANSI_TO_TCHAR(ErrorMessage.Text()));
	}
	else
	{
		TArray<FString> Params;
		TArray<FText> ErrorMessages;
		FP4RecordSet Records;
		bool bConnectionDropped = false;
		const bool bStandardDebugOutput = false;
		const bool bAllowRetry = true;

		UE_LOG(LogSourceControl, Verbose, TEXT(" ... checking unicode status" ));

		if (RunCommand(TEXT("info"), Params, Records, ErrorMessages, FOnIsCancelled(), bConnectionDropped, bStandardDebugOutput, bAllowRetry))
		{
			// Get character encoding
			bIsUnicode = Records[0].Find(TEXT("unicode")) != NULL;
			if(bIsUnicode)
			{
				P4Client.SetTrans(CharSetApi::UTF_8);
				UE_LOG(LogSourceControl, Verbose, TEXT(" server is unicode" ));
			}

			// Now we know our unicode status we can gather the client root
			P4Client.SetUser(FROM_TCHAR(*InConnectionInfo.UserName, bIsUnicode));

			if(InConnectionInfo.Password.Len() > 0)
			{
				Login(InConnectionInfo);
			}

			if (InConnectionInfo.Ticket.Len())
			{
				P4Client.SetPassword(FROM_TCHAR(*InConnectionInfo.Ticket, bIsUnicode));
			}
			if (InConnectionInfo.Workspace.Len())
			{
				P4Client.SetClient(FROM_TCHAR(*InConnectionInfo.Workspace, bIsUnicode));
			}

			P4Client.SetCwd(FROM_TCHAR(*FPaths::RootDir(), bIsUnicode));

			// Gather the client root
			UE_LOG(LogSourceControl, Verbose, TEXT(" ... getting info" ));
			bConnectionDropped = false;
			if (RunCommand(TEXT("info"), Params, Records, ErrorMessages, FOnIsCancelled(), bConnectionDropped, bStandardDebugOutput, bAllowRetry))
			{
				UE_LOG(LogSourceControl, Verbose, TEXT(" ... getting clientroot" ));
				ClientRoot = Records[0](TEXT("clientRoot"));

				//make sure all slashes point the same way
				ClientRoot = ClientRoot.Replace(TEXT("\\"), TEXT("/"));
			}
		}
	}
#endif
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
bool FPerforceConnection::EnsureValidConnection(FString& InOutServerName, FString& InOutUserName, FString& InOutWorkspaceName, const FPerforceConnectionInfo& InConnectionInfo)
{
	bool bIsUnicodeServer = false;
	bool bConnectionOK = false;
#if USE_P4_API
	FMessageLog SourceControlLog("SourceControl");

	FString NewServerName = InOutServerName;
	FString NewUserName = InOutUserName;
	FString NewClientSpecName = InOutWorkspaceName;

	ClientApi TestP4;
	TestP4.SetProtocol("tag", "");
	TestP4.SetProtocol("enableStreams", "");

	if (NewServerName.Len() && NewUserName.Len() && NewClientSpecName.Len())
	{
		//attempt connection with given settings
		TestP4.SetPort(TCHAR_TO_ANSI(*NewServerName));

		if(InConnectionInfo.Password.Len() > 0)
		{
			TestP4.SetPassword(TCHAR_TO_ANSI(*InConnectionInfo.Password));
		}

		if(InConnectionInfo.HostOverride.Len() > 0)
		{
			TestP4.SetHost(TCHAR_TO_ANSI(*InConnectionInfo.HostOverride));
		}
	}

	Error P4Error;
	TestP4.Init(&P4Error);

	bConnectionOK = !P4Error.Test();
	if (!bConnectionOK)
	{
		//Connection FAILED
		StrBuf ErrorMessage;
		P4Error.Fmt(&ErrorMessage);
		SourceControlLog.Error(LOCTEXT("P4ErrorConnection", "P4ERROR: Failed to connect to source control provider."));
		SourceControlLog.Error(FText::FromString(ANSI_TO_TCHAR(ErrorMessage.Text())));
		FFormatNamedArguments Arguments;
		Arguments.Add( TEXT("PortName"), FText::FromString(NewServerName) );
		Arguments.Add( TEXT("UserName"), FText::FromString(NewUserName) );
		Arguments.Add( TEXT("ClientSpecName"), FText::FromString(NewClientSpecName) );
		Arguments.Add( TEXT("Ticket"), FText::FromString(InConnectionInfo.Ticket) );
		SourceControlLog.Error(FText::Format(LOCTEXT("P4ErrorConnection_Details", "Port={PortName}, User={UserName}, ClientSpec={ClientSpecName}, Ticket={Ticket}"), Arguments));
	}

	// run an info command to determine unicode status
	if(bConnectionOK)
	{
		TArray<FText> ErrorMessages;

		bConnectionOK = CheckUnicodeStatus(TestP4, bIsUnicodeServer, ErrorMessages);
		if(!bConnectionOK)
		{
			SourceControlLog.Error(LOCTEXT("P4ErrorConnection", "P4ERROR: Could not determine server unicode status."));
			SourceControlLog.Error(ErrorMessages.Num() > 0 ? ErrorMessages[0] : LOCTEXT("P4ErrorConnection_Unknown error", "Unknown error"));
			FFormatNamedArguments Arguments;
			Arguments.Add( TEXT("PortName"), FText::FromString(NewServerName) );
			Arguments.Add( TEXT("UserName"), FText::FromString(NewUserName) );
			Arguments.Add( TEXT("ClientSpecName"), FText::FromString(NewClientSpecName) );
			Arguments.Add( TEXT("Ticket"), FText::FromString(InConnectionInfo.Ticket) );
			SourceControlLog.Error(FText::Format(LOCTEXT("P4ErrorConnection_Details", "Port={PortName}, User={UserName}, ClientSpec={ClientSpecName}, Ticket={Ticket}"), Arguments));
		}
		else
		{
			if(bIsUnicodeServer)
			{
				// set translation mode. From here onwards we need to use UTF8 when using text args
				TestP4.SetTrans(CharSetApi::UTF_8);
			}

			// now we have determined unicode status, we can set the values that can be specified in non-ansi characters
			TestP4.SetCwd(FROM_TCHAR(*FPaths::RootDir(), bIsUnicodeServer));
			TestP4.SetUser(FROM_TCHAR(*NewUserName, bIsUnicodeServer));
			TestP4.SetClient(FROM_TCHAR(*NewClientSpecName, bIsUnicodeServer));

			if(InConnectionInfo.Ticket.Len())
			{
				TestP4.SetPassword(FROM_TCHAR(*InConnectionInfo.Ticket, bIsUnicodeServer));
			}
		}
	}

	if (bConnectionOK)
	{
		// If a client spec was not specified, attempt to auto-detect it here. If the detection is not successful, neither is this connection since we need a client spec.
		if ( NewClientSpecName.IsEmpty() )
		{
			FPerforceConnectionInfo AutoCredentials = InConnectionInfo;
			AutoCredentials.Port = TO_TCHAR(TestP4.GetPort().Text(), bIsUnicodeServer);
			AutoCredentials.UserName = TO_TCHAR(TestP4.GetUser().Text(), bIsUnicodeServer);

		 	bConnectionOK = FPerforceConnection::AutoDetectWorkspace(AutoCredentials, NewClientSpecName);
			if ( bConnectionOK )
			{
				TestP4.SetClient(FROM_TCHAR(*NewClientSpecName, bIsUnicodeServer));
			}
		}
	}

	if (bConnectionOK)
	{
		TArray<FText> ErrorMessages;

		bConnectionOK = TestConnection(TestP4, NewClientSpecName, bIsUnicodeServer, ErrorMessages);
		if (!bConnectionOK)
		{
			//Login FAILED
			SourceControlLog.Error(LOCTEXT("P4ErrorConnection", "P4ERROR: Failed to connect to source control provider."));
			SourceControlLog.Error(ErrorMessages.Num() > 0 ? ErrorMessages[0] : LOCTEXT("P4ErrorConnection_InvalidWorkspace", "Invalid workspace"));
			FFormatNamedArguments Arguments;
			Arguments.Add( TEXT("PortName"), FText::FromString(NewServerName) );
			Arguments.Add( TEXT("UserName"), FText::FromString(NewUserName) );
			Arguments.Add( TEXT("ClientSpecName"), FText::FromString(NewClientSpecName) );
			Arguments.Add( TEXT("Ticket"), FText::FromString(InConnectionInfo.Ticket) );
			SourceControlLog.Error(FText::Format(LOCTEXT("P4ErrorConnection_Details", "Port={PortName}, User={UserName}, ClientSpec={ClientSpecName}, Ticket={Ticket}"), Arguments));
		}
	}

	//whether successful or not, disconnect to clean up
	TestP4.Final(&P4Error);
	if (bConnectionOK && P4Error.Test())
	{
		//Disconnect FAILED
		bConnectionOK = false;
		StrBuf ErrorMessage;
		P4Error.Fmt(&ErrorMessage);
		SourceControlLog.Error(LOCTEXT("P4ErrorFailedDisconnect", "P4ERROR: Failed to disconnect from Server."));
		SourceControlLog.Error(FText::FromString(TO_TCHAR(ErrorMessage.Text(), bIsUnicodeServer)));
	}

	//if never specified, take the default connection values
	if (NewServerName.Len() == 0)
	{
		NewServerName = TO_TCHAR(TestP4.GetPort().Text(), bIsUnicodeServer);
	}
	if (NewUserName.Len() == 0)
	{
		NewUserName = TO_TCHAR(TestP4.GetUser().Text(), bIsUnicodeServer);
	}
	if (NewClientSpecName.Len() == 0)
	{
		NewClientSpecName = TO_TCHAR(TestP4.GetClient().Text(), bIsUnicodeServer);
		if (NewClientSpecName == TO_TCHAR(TestP4.GetHost().Text(), bIsUnicodeServer))
		{
			// If the client spec name is the same as host name, assume P4 couldn't get the actual
			// spec name for this host and let GetPerforceLogin() try to find a proper one.
			bConnectionOK = false;
		}
	}

	if (bConnectionOK)
	{
		InOutServerName = NewServerName;
		InOutUserName = NewUserName;
		InOutWorkspaceName = NewClientSpecName;
	}
#endif

	return bConnectionOK;
}
Esempio n. 6
0
	void Prompt( const StrPtr& InMessage, StrBuf& OutPrompt, int NoEcho, Error* InError )
	{
#if USE_P4_API
		OutPrompt.Set(FROM_TCHAR(*Password, bIsUnicodeServer));
#endif
	}