void SPropertyEditorAsset::Construct( const FArguments& InArgs, const TSharedPtr<FPropertyEditor>& InPropertyEditor )
{
	PropertyEditor = InPropertyEditor;
	PropertyHandle = InArgs._PropertyHandle;
	OnSetObject = InArgs._OnSetObject;
	OnShouldFilterAsset = InArgs._OnShouldFilterAsset;

	UProperty* Property = nullptr;
	if(PropertyEditor.IsValid())
	{
		Property = PropertyEditor->GetPropertyNode()->GetProperty();
		
		bAllowClear = !(Property->PropertyFlags & CPF_NoClear);
		ObjectClass = GetObjectPropertyClass(Property);
		bIsActor = ObjectClass->IsChildOf( AActor::StaticClass() );
	}
	else
	{
		bAllowClear = InArgs._AllowClear;
		ObjectPath = InArgs._ObjectPath;
		ObjectClass = InArgs._Class;
		bIsActor = ObjectClass->IsChildOf( AActor::StaticClass() );

		if (PropertyHandle.IsValid() && PropertyHandle->IsValidHandle())
		{
			Property = PropertyHandle->GetProperty();
		}
		else
		{
			CustomClassFilters.Add(ObjectClass);
		}
	}

	// Account for the allowed classes specified in the property metadata
	if (Property)
	{
		FString ClassFilterString;
		if (UArrayProperty* ArrayParent = Cast<UArrayProperty>(Property->GetOuter()))
		{
			ClassFilterString = ArrayParent->GetMetaData("AllowedClasses");
		}
		else
		{
			ClassFilterString = Property->GetMetaData("AllowedClasses");
		}

		if (ClassFilterString.IsEmpty())
		{
			CustomClassFilters.Add(ObjectClass);
		}
		else
		{
			TArray<FString> CustomClassFilterNames;
			ClassFilterString.ParseIntoArray(CustomClassFilterNames, TEXT(","), true);

			for (auto It = CustomClassFilterNames.CreateIterator(); It; ++It)
			{
				FString& ClassName = *It;
				// User can potentially list class names with leading or trailing whitespace
				ClassName.Trim();
				ClassName.TrimTrailing();

				UClass* Class = FindObject<UClass>(ANY_PACKAGE, *ClassName);

				if (!Class)
				{
					Class = LoadObject<UClass>(nullptr, *ClassName);
				}

				if (Class)
				{
					// If the class is an interface, expand it to be all classes in memory that implement the class.
					if (Class->HasAnyClassFlags(CLASS_Interface))
					{
						for (TObjectIterator<UClass> ClassIt; ClassIt; ++ClassIt)
						{
							UClass* const ClassWithInterface = (*ClassIt);
							if (ClassWithInterface->ImplementsInterface(Class))
							{
								CustomClassFilters.Add(ClassWithInterface);
							}
						}
					}
					else
					{
						CustomClassFilters.Add(Class);
					}
				}
			}
		}
	}

	if (InArgs._NewAssetFactories.IsSet())
	{
		NewAssetFactories = InArgs._NewAssetFactories.GetValue();
	}
	else if (CustomClassFilters.Num() > 1 || !CustomClassFilters.Contains(UObject::StaticClass()))
	{
		NewAssetFactories = PropertyCustomizationHelpers::GetNewAssetFactoriesForClasses(CustomClassFilters);
	}
	
	TSharedPtr<SHorizontalBox> ValueContentBox = NULL;
	ChildSlot
	[
		SNew( SAssetDropTarget )
		.OnIsAssetAcceptableForDrop( this, &SPropertyEditorAsset::OnAssetDraggedOver )
		.OnAssetDropped( this, &SPropertyEditorAsset::OnAssetDropped )
		[
			SAssignNew( ValueContentBox, SHorizontalBox )	
		]
	];

	TAttribute<bool> IsEnabledAttribute(this, &SPropertyEditorAsset::CanEdit);
	TAttribute<FText> TooltipAttribute(this, &SPropertyEditorAsset::OnGetToolTip);

	if (Property && Property->HasAllPropertyFlags(CPF_DisableEditOnTemplate))
	{
		// There are some cases where editing an Actor Property is not allowed, such as when it is contained within a struct or a CDO
		TArray<UObject*> ObjectList;
		PropertyEditor->GetPropertyHandle()->GetOuterObjects(ObjectList);

		// If there is no objects, that means we must have a struct asset managing this property
		if (ObjectList.Num() == 0)
		{
			IsEnabledAttribute.Set(false);
			TooltipAttribute.Set(LOCTEXT("VariableHasDisableEditOnTemplate", "Editing this value in structure's defaults is not allowed"));
		}
		else
		{
			// Go through all the found objects and see if any are a CDO, we can't set an actor in a CDO default.
			for (UObject* Obj : ObjectList)
			{
				if (Obj->HasAllFlags(RF_ClassDefaultObject))
				{
					IsEnabledAttribute.Set(false);
					TooltipAttribute.Set(LOCTEXT("VariableHasDisableEditOnTemplateTooltip", "Editing this value in a Class Default Object is not allowed"));
					break;
				}

			}
		}
	}
	bool bOldEnableAttribute = IsEnabledAttribute.Get();
	if (bOldEnableAttribute && !InArgs._EnableContentPicker)
	{
		IsEnabledAttribute.Set(false);
	}

	AssetComboButton = SNew(SComboButton)
		.ToolTipText(TooltipAttribute)
		.ButtonStyle( FEditorStyle::Get(), "PropertyEditor.AssetComboStyle" )
		.ForegroundColor(FEditorStyle::GetColor("PropertyEditor.AssetName.ColorAndOpacity"))
		.OnGetMenuContent( this, &SPropertyEditorAsset::OnGetMenuContent )
		.OnMenuOpenChanged( this, &SPropertyEditorAsset::OnMenuOpenChanged )
		.IsEnabled( IsEnabledAttribute )
		.ContentPadding(2.0f)
		.ButtonContent()
		[
			// Show the name of the asset or actor
			SNew(STextBlock)
			.TextStyle( FEditorStyle::Get(), "PropertyEditor.AssetClass" )
			.Font( FEditorStyle::GetFontStyle( PropertyEditorConstants::PropertyFontStyle ) )
			.Text(this,&SPropertyEditorAsset::OnGetAssetName)
		];

	if (bOldEnableAttribute && !InArgs._EnableContentPicker)
	{
		IsEnabledAttribute.Set(true);
	}

	TSharedRef<SHorizontalBox> ButtonBox = SNew( SHorizontalBox );
	
	TSharedPtr<SVerticalBox> CustomContentBox;

	if( ShouldDisplayThumbnail(InArgs) )
	{
		FObjectOrAssetData Value; 
		GetValue( Value );

		AssetThumbnail = MakeShareable( new FAssetThumbnail( Value.AssetData, InArgs._ThumbnailSize.X, InArgs._ThumbnailSize.Y, InArgs._ThumbnailPool ) );

		ValueContentBox->AddSlot()
		.Padding( 0.0f, 0.0f, 2.0f, 0.0f )
		.AutoWidth()
		[
			SAssignNew( ThumbnailBorder, SBorder )
			.Padding( 5.0f )
			.BorderImage( this, &SPropertyEditorAsset::GetThumbnailBorder )
			.OnMouseDoubleClick( this, &SPropertyEditorAsset::OnAssetThumbnailDoubleClick )
			[
				SNew( SBox )
				.ToolTipText(TooltipAttribute)
				.WidthOverride( InArgs._ThumbnailSize.X ) 
				.HeightOverride( InArgs._ThumbnailSize.Y )
				[
					AssetThumbnail->MakeThumbnailWidget()
				]
			]
		];


		ValueContentBox->AddSlot()
		[
			SNew( SBox )
			.VAlign( VAlign_Center )
			[
				SAssignNew( CustomContentBox, SVerticalBox )
				+ SVerticalBox::Slot()
				[
					AssetComboButton.ToSharedRef()
				]
				+ SVerticalBox::Slot()
				.AutoHeight()
				.Padding( 0.0f, 2.0f, 4.0f, 2.0f )
				[
					ButtonBox
				]
			]
		];
	}
	else
	{
		ValueContentBox->AddSlot()
		[
			SAssignNew( CustomContentBox, SVerticalBox )
			+SVerticalBox::Slot()
			.VAlign( VAlign_Center )
			[
				SNew( SHorizontalBox )
				+ SHorizontalBox::Slot()
				[
					AssetComboButton.ToSharedRef()
				]
				+ SHorizontalBox::Slot()
				.AutoWidth()
				.Padding( 4.f, 0.f )
				[
					ButtonBox
				]
			]
		];
	}

	if( InArgs._CustomContentSlot.Widget != SNullWidget::NullWidget )
	{
		CustomContentBox->AddSlot()
		.VAlign( VAlign_Center )
		.Padding( FMargin( 0.0f, 2.0f ) )
		[
			InArgs._CustomContentSlot.Widget
		];
	}

	if( !bIsActor && InArgs._DisplayUseSelected )
	{
		ButtonBox->AddSlot()
		.VAlign(VAlign_Center)
		.AutoWidth()
		.Padding( 2.0f, 0.0f )
		[
			PropertyCustomizationHelpers::MakeUseSelectedButton( FSimpleDelegate::CreateSP( this, &SPropertyEditorAsset::OnUse ), FText(), IsEnabledAttribute )
		];
	}

	if( InArgs._DisplayBrowse )
	{
		ButtonBox->AddSlot()
		.Padding( 2.0f, 0.0f )
		.AutoWidth()
		.VAlign(VAlign_Center)
		[
			PropertyCustomizationHelpers::MakeBrowseButton(
				FSimpleDelegate::CreateSP( this, &SPropertyEditorAsset::OnBrowse ),
				TAttribute<FText>( this, &SPropertyEditorAsset::GetOnBrowseToolTip )
				)
		];
	}

	if( bIsActor )
	{
		TSharedRef<SWidget> ActorPicker = PropertyCustomizationHelpers::MakeInteractiveActorPicker( FOnGetAllowedClasses::CreateSP(this, &SPropertyEditorAsset::OnGetAllowedClasses), FOnShouldFilterActor(), FOnActorSelected::CreateSP( this, &SPropertyEditorAsset::OnActorSelected ) );
		ActorPicker->SetEnabled( IsEnabledAttribute );

		ButtonBox->AddSlot()
		.Padding( 2.0f, 0.0f )
		.AutoWidth()
		.VAlign(VAlign_Center)
		[
			ActorPicker
		];
	}

	if(InArgs._ResetToDefaultSlot.Widget != SNullWidget::NullWidget )
	{
		TSharedRef<SWidget> ResetToDefaultWidget  = InArgs._ResetToDefaultSlot.Widget;
		ResetToDefaultWidget->SetEnabled( IsEnabledAttribute );

		ButtonBox->AddSlot()
		.Padding( 4.0f, 0.0f )
		.AutoWidth()
		.VAlign(VAlign_Center)
		[
			ResetToDefaultWidget
		];
	}
}
void FPropertyTable::PasteTextAtCell( const FString& Text, const TSharedRef< IPropertyTableCell >& Cell )
{
	if ( !SelectedCells.Contains( Cell ) )
	{
		return;
	}

	int32 CurrentRowIdx = 0;
	int32 CurrentColumnIdx = 0;
	TSharedPtr< IPropertyTableCell > FirstCellInRow = Cell;
	TSharedPtr< IPropertyTableCell > TargetCell = Cell;

	// Parse into row strings
	TArray<FString> RowStrings;
	Text.ParseIntoArray(RowStrings, TEXT("\n"), true);

	// Parse row strings into individual cell strings
	TArray<FString> CellStrings;
	RowStrings[CurrentRowIdx++].ParseIntoArray(CellStrings, TEXT("\t"), false);

	// Get the maximum paste operations before displaying the slow task
	int32 NumPasteOperationsBeforeWarning = GetDefault<UEditorPerProjectUserSettings>()->PropertyMatrix_NumberOfPasteOperationsBeforeWarning;
	
	const bool bShowCancelButton = false;
	const bool bShowProgressDialog = SelectedCells.Num() > NumPasteOperationsBeforeWarning;
	GWarn->BeginSlowTask(LOCTEXT("UpdatingPropertiesSlowTaskLabel", "Updating properties..."), bShowProgressDialog, bShowCancelButton);

	if ( RowStrings.Num() == 1 && CellStrings.Num() == 1 )
	{
		int32 CurrentCellIndex = 0;
		for( auto CellIter = SelectedCells.CreateIterator(); CellIter; ++CellIter )
		{
			SetCellValue( *CellIter, CellStrings[0] );
			
			if ( bShowProgressDialog )
			{
				GWarn->UpdateProgress(CurrentCellIndex, SelectedCells.Num());
				CurrentCellIndex++;
			}
		}
	}
	else if ( StartingCellSelectionRange.IsValid() && EndingCellSelectionRange.IsValid() )
	{
		// Paste values into cells
		while ( TargetCell.IsValid() && SelectedCells.Contains( TargetCell.ToSharedRef() ) && CurrentColumnIdx < CellStrings.Num() )
		{
			SetCellValue( TargetCell.ToSharedRef(), CellStrings[CurrentColumnIdx++] );

			// Move to next column
			TargetCell = GetNextCellInRow(TargetCell.ToSharedRef());

			if ( ( !TargetCell.IsValid() || !SelectedCells.Contains( TargetCell.ToSharedRef() ) || CurrentColumnIdx == CellStrings.Num() ) && CurrentRowIdx < RowStrings.Num() )
			{
				// Move to next row
				TargetCell = GetNextCellInColumn(FirstCellInRow.ToSharedRef());

				if ( TargetCell.IsValid() && SelectedCells.Contains( TargetCell.ToSharedRef() ) )
				{
					// Prepare data to operate on next row
					CurrentColumnIdx = 0;
					FirstCellInRow = TargetCell;
					RowStrings[CurrentRowIdx++].ParseIntoArray(CellStrings, TEXT("\t"), false);
				
					if ( bShowProgressDialog )
					{
						GWarn->UpdateProgress(CurrentRowIdx, RowStrings.Num());
					}
				}
			}
		}
	}
	
	GWarn->EndSlowTask();

}
bool UGatherTextFromSourceCommandlet::FMacroDescriptor::ParseArgsFromMacro(const FString& Text, TArray<FString>& Args, FSourceFileParseContext& Context) const
{
	// Attempt to parse something of the format
	// NAME(param0, param1, param2, etc)

	bool Success = false;

	FString RemainingText = Text.RightChop(GetToken().Len()).Trim();
	int32 OpenBracketIdx = RemainingText.Find(TEXT("("));
	if (0 > OpenBracketIdx)
	{
		UE_LOG(LogGatherTextFromSourceCommandlet, Warning, TEXT("Missing bracket '(' in %s macro in %s(%d):%s"), *GetToken(), *Context.Filename, Context.LineNumber, *MungeLogOutput(Context.LineText));
		//Dont assume this is an error. It's more likely trying to parse something it shouldn't be.
		return false;
	}
	else
	{
		Args.Empty();

		bool bInDblQuotes = false;
		bool bInSglQuotes = false;
		int32 BracketStack = 1;
		bool bEscapeNextChar = false;

		const TCHAR* ArgStart = *RemainingText + OpenBracketIdx + 1;
		const TCHAR* Cursor = ArgStart;
		for (; 0 < BracketStack && '\0' != *Cursor; ++Cursor)
		{
			if (bEscapeNextChar)
			{
				bEscapeNextChar = false;
			}
			else if ((bInDblQuotes || bInSglQuotes) && !bEscapeNextChar && '\\' == *Cursor)
			{
				bEscapeNextChar = true;
			}
			else if (bInDblQuotes)
			{
				if ('\"' == *Cursor)
				{
					bInDblQuotes = false;
				}
			}
			else if (bInSglQuotes)
			{
				if ('\'' == *Cursor)
				{
					bInSglQuotes = false;
				}
			}
			else if ('\"' == *Cursor)
			{
				bInDblQuotes = true;
			}
			else if ('\'' == *Cursor)
			{
				bInSglQuotes = true;
			}
			else if ('(' == *Cursor)
			{
				++BracketStack;
			}
			else if (')' == *Cursor)
			{
				--BracketStack;

				if (0 > BracketStack)
				{
					UE_LOG(LogGatherTextFromSourceCommandlet, Warning, TEXT("Unexpected bracket ')' in %s macro in %s(%d):%s"), *GetToken(), *Context.Filename, Context.LineNumber, *MungeLogOutput(Context.LineText));
					return false;
				}
			}
			else if (1 == BracketStack && ',' == *Cursor)
			{
				// create argument from ArgStart to Cursor and set Start next char
				Args.Add(FString(Cursor - ArgStart, ArgStart));
				ArgStart = Cursor + 1;
			}
		}

		if (0 == BracketStack)
		{
			Args.Add(FString(Cursor - ArgStart - 1, ArgStart));
		}
		else
		{
			Args.Add(FString(ArgStart));
		}

		Success = 0 < Args.Num() ? true : false;	
	}

	return Success;
}
Exemplo n.º 4
0
bool FXmlFile::LoadFile(const FString& InFile, EConstructMethod::Type ConstructMethod)
{
	// Remove any file stuff if it already exists
	Clear();

	// So far no error (Early so it can be overwritten below by errors)
	ErrorMessage = NSLOCTEXT("XmlParser", "LoadSuccess", "XmlFile was loaded successfully").ToString();

	TArray<FString> Input;
	if(ConstructMethod == EConstructMethod::ConstructFromFile)
	{
		// Create file reader
		TUniquePtr<FArchive> FileReader(IFileManager::Get().CreateFileReader(*InFile));
		if(!FileReader)
		{
			ErrorMessage = NSLOCTEXT("XmlParser", "FileLoadFail", "Failed to load the file").ToString();
			ErrorMessage += TEXT("\"");
			ErrorMessage += InFile;
			ErrorMessage += TEXT("\"");
			return false;
		}

		// Create buffer for file input
		uint32 BufferSize = FileReader->TotalSize();
		void* Buffer = FMemory::Malloc(BufferSize);
		FileReader->Serialize(Buffer, BufferSize);

		// Parse file buffer into an array of lines
		if (!FindCharSizeAndSplitLines(Input, Buffer, BufferSize))
		{
			ErrorMessage = NSLOCTEXT("XmlParser", "InvalidFormatFail", "Failed to parse the file (Unsupported character encoding)").ToString();
			ErrorMessage += TEXT("\"");
			ErrorMessage += InFile;
			ErrorMessage += TEXT("\"");
			return false;
		}

		// Release resources
		FMemory::Free(Buffer);
	}
	else
	{
		// Parse input buffer into an array of lines
		SplitLines(Input, *InFile, *InFile + InFile.Len());
	}

	// Pre-process the input
	PreProcessInput(Input);

	// Tokenize the input
	TArray<FString> Tokens = Tokenize(Input);

	// Parse the input & create the nodes
	CreateNodes(Tokens);

	// All done with creation, set up necessary information
	if(bFileLoaded == true)
	{
		if(ConstructMethod == EConstructMethod::ConstructFromFile)
		{
			LoadedFile = InFile;
		}
	}
	else
	{
		LoadedFile = TEXT("");
		RootNode = nullptr;
	}

	// Now check the status flag of the creation. It may have actually failed, but given us a 
	// partially created representation
	if(bCreationFailed)
	{
		Clear();
	}

	return bFileLoaded;
}
	/**
	 * A utility function to help separate a package name and asset name out 
	 * from a full asset object path.
	 * 
	 * @param  AssetObjPathIn	The asset object path you want split.
	 * @param  PackagePathOut	The first half of the in string (the package portion).
	 * @param  AssetNameOut		The second half of the in string (the asset name portion).
	 */
	static void SplitPackagePathAndAssetName(FString const& AssetObjPathIn, FString& PackagePathOut, FString& AssetNameOut)
	{
		AssetObjPathIn.Split(TEXT("."), &PackagePathOut, &AssetNameOut);
	}
Exemplo n.º 6
0
DWORD CDirEnumerator::GetNextFile(NFind::CFileInfo &fi, bool &filled, FString &resPath)
{
  filled = false;
  resPath.Empty();
  for (;;)
  {
    if (Enumerators.IsEmpty())
    {
      if (Index >= FilePaths.Size())
        return S_OK;
      const FString &path = FilePaths[Index++];
      int pos = path.ReverseFind(FCHAR_PATH_SEPARATOR);
      if (pos >= 0)
        resPath.SetFrom(path, pos + 1);

      #ifdef _WIN32
      if (BasePrefix.IsEmpty() && path.Len() == 2 && path[1] == ':')
      {
        // we use "c:" item as directory item
        fi.Clear();
        fi.Name = path;
        fi.SetAsDir();
        fi.Size = 0;
      }
      else
      #endif
      if (!fi.Find(BasePrefix + path))
      {
        DWORD error = GetNormalizedError();
        resPath = path;
        return error;
      }
      break;
    }
    bool found;
    if (Enumerators.Back().Next(fi, found))
    {
      if (found)
      {
        resPath = Prefixes.Back();
        break;
      }
    }
    else
    {
      DWORD error = GetNormalizedError();
      resPath = Prefixes.Back();
      Enumerators.DeleteBack();
      Prefixes.DeleteBack();
      return error;
    }
    Enumerators.DeleteBack();
    Prefixes.DeleteBack();
  }
  resPath += fi.Name;
  if (EnterToDirs && fi.IsDir())
  {
    FString s = resPath;
    s += FCHAR_PATH_SEPARATOR;
    Prefixes.Add(s);
    s += FCHAR_ANY_MASK;
    Enumerators.Add(NFind::CEnumerator(BasePrefix + s));
  }
  filled = true;
  return S_OK;
}
Exemplo n.º 7
0
bool FDesktopPlatformBase::EnumerateProjectsKnownByEngine(const FString &Identifier, bool bIncludeNativeProjects, TArray<FString> &OutProjectFileNames)
{
	// Get the engine root directory
	FString RootDir;
	if (!GetEngineRootDirFromIdentifier(Identifier, RootDir))
	{
		return false;
	}

	FString GameAgnosticConfigDir = GetEngineSavedConfigDirectory(Identifier);

	if (GameAgnosticConfigDir.Len() == 0)
	{
		return false;
	}

	// Find all the created project directories. Start with the default project creation path.
	TArray<FString> SearchDirectories;
	SearchDirectories.AddUnique(GetDefaultProjectCreationPath());

	// Load the config file
	FConfigFile GameAgnosticConfig;
	FConfigCacheIni::LoadExternalIniFile(GameAgnosticConfig, TEXT("EditorSettings"), NULL, *GameAgnosticConfigDir, false);

	// Find the editor game-agnostic settings
	FConfigSection* Section = GameAgnosticConfig.Find(TEXT("/Script/UnrealEd.EditorSettings"));

	if (Section == NULL)
	{
		FConfigCacheIni::LoadExternalIniFile(GameAgnosticConfig, TEXT("EditorGameAgnostic"), NULL, *GameAgnosticConfigDir, false);
		Section = GameAgnosticConfig.Find(TEXT("/Script/UnrealEd.EditorGameAgnosticSettings"));
	}

	if(Section != NULL)
	{
		// Add in every path that the user has ever created a project file. This is to catch new projects showing up in the user's project folders
		TArray<FString> AdditionalDirectories;
		Section->MultiFind(TEXT("CreatedProjectPaths"), AdditionalDirectories);
		for(int Idx = 0; Idx < AdditionalDirectories.Num(); Idx++)
		{
			FPaths::NormalizeDirectoryName(AdditionalDirectories[Idx]);
			SearchDirectories.AddUnique(AdditionalDirectories[Idx]);
		}

		// Also add in all the recently opened projects
		TArray<FString> RecentlyOpenedFiles;
		Section->MultiFind(TEXT("RecentlyOpenedProjectFiles"), RecentlyOpenedFiles);
		for(int Idx = 0; Idx < RecentlyOpenedFiles.Num(); Idx++)
		{
			FPaths::NormalizeFilename(RecentlyOpenedFiles[Idx]);
			OutProjectFileNames.AddUnique(RecentlyOpenedFiles[Idx]);
		}		
	}

	// Find all the other projects that are in the search directories
	for(int Idx = 0; Idx < SearchDirectories.Num(); Idx++)
	{
		TArray<FString> ProjectFolders;
		IFileManager::Get().FindFiles(ProjectFolders, *(SearchDirectories[Idx] / TEXT("*")), false, true);

		for(int32 FolderIdx = 0; FolderIdx < ProjectFolders.Num(); FolderIdx++)
		{
			TArray<FString> ProjectFiles;
			IFileManager::Get().FindFiles(ProjectFiles, *(SearchDirectories[Idx] / ProjectFolders[FolderIdx] / TEXT("*.uproject")), true, false);

			for(int32 FileIdx = 0; FileIdx < ProjectFiles.Num(); FileIdx++)
			{
				OutProjectFileNames.AddUnique(SearchDirectories[Idx] / ProjectFolders[FolderIdx] / ProjectFiles[FileIdx]);
			}
		}
	}

	// Find all the native projects, and either add or remove them from the list depending on whether we want native projects
	const FUProjectDictionary &Dictionary = GetCachedProjectDictionary(RootDir);
	if(bIncludeNativeProjects)
	{
		TArray<FString> NativeProjectPaths = Dictionary.GetProjectPaths();
		for(int Idx = 0; Idx < NativeProjectPaths.Num(); Idx++)
		{
			if(!NativeProjectPaths[Idx].Contains(TEXT("/Templates/")))
			{
				OutProjectFileNames.AddUnique(NativeProjectPaths[Idx]);
			}
		}
	}
	else
	{
		TArray<FString> NativeProjectPaths = Dictionary.GetProjectPaths();
		for(int Idx = 0; Idx < NativeProjectPaths.Num(); Idx++)
		{
			OutProjectFileNames.Remove(NativeProjectPaths[Idx]);
		}
	}

	return true;
}
Exemplo n.º 8
0
	int IntFromString(const FString& InStr)
	{
		return std::atoi(InStr.c_str());
	}
Exemplo n.º 9
0
bool FAssetEditorManager::OpenEditorForAsset(UObject* Asset, const EToolkitMode::Type ToolkitMode, TSharedPtr< IToolkitHost > OpenedFromLevelEditor )
{
	check(Asset);
	// @todo toolkit minor: When "Edit Here" happens in a different level editor from the one that an asset is already
	//    being edited within, we should decide whether to disallow "Edit Here" in that case, or to close the old asset
	//    editor and summon it in the new level editor, or to just foreground the old level editor (current behavior)

	const bool bBringToFrontIfOpen = true;

	// Don't open asset editors for cooked packages
	if (UPackage* Package = Asset->GetOutermost())
	{
		if (Package->bIsCookedForEditor)
		{
			return false;
		}
	}
	
	AssetEditorRequestOpenEvent.Broadcast(Asset);

	if( FindEditorForAsset(Asset, bBringToFrontIfOpen) != nullptr )
	{
		// This asset is already open in an editor! (the call to FindEditorForAsset above will bring it to the front)
		return true;
	}
	else
	{
		GWarn->BeginSlowTask( LOCTEXT("OpenEditor", "Opening Editor..."), true);
	}


	FAssetToolsModule& AssetToolsModule = FModuleManager::LoadModuleChecked<FAssetToolsModule>(TEXT("AssetTools"));

	TWeakPtr<IAssetTypeActions> AssetTypeActions = AssetToolsModule.Get().GetAssetTypeActionsForClass( Asset->GetClass() );
	
	auto ActualToolkitMode = ToolkitMode;
	if( AssetTypeActions.IsValid() )
	{
		if( AssetTypeActions.Pin()->ShouldForceWorldCentric() )
		{
			// This asset type prefers a specific toolkit mode
			ActualToolkitMode = EToolkitMode::WorldCentric;

			if( !OpenedFromLevelEditor.IsValid() )
			{
				// We don't have a level editor to spawn in world-centric mode, so we'll find one now
				// @todo sequencer: We should eventually eliminate this code (incl include dependencies) or change it to not make assumptions about a single level editor
				OpenedFromLevelEditor = FModuleManager::LoadModuleChecked< FLevelEditorModule >( "LevelEditor" ).GetFirstLevelEditor();
			}
		}
	}
	
	if( ActualToolkitMode != EToolkitMode::WorldCentric && OpenedFromLevelEditor.IsValid() )
	{
		// @todo toolkit minor: Kind of lame use of a static variable here to prime the new asset editor.  This was done to avoid refactoring a few dozen files for a very minor change.
		FAssetEditorToolkit::SetPreviousWorldCentricToolkitHostForNewAssetEditor( OpenedFromLevelEditor.ToSharedRef() );
	}

	// Disallow opening an asset editor for classes
	bool bCanSummonSimpleAssetEditor = !Asset->IsA<UClass>();

	if( AssetTypeActions.IsValid() )
	{
		TArray<UObject*> AssetsToEdit;
		AssetsToEdit.Add(Asset);

		// Some assets (like UWorlds) may be destroyed and recreated as part of opening. To protect against this, keep the path to the asset and try to re-find it if it disappeared.
		TWeakObjectPtr<UObject> WeakAsset = Asset;
		const FString AssetPath = Asset->GetPathName();

		AssetTypeActions.Pin()->OpenAssetEditor(AssetsToEdit, ActualToolkitMode == EToolkitMode::WorldCentric ? OpenedFromLevelEditor : TSharedPtr<IToolkitHost>());
		
		// If the Asset was destroyed, attempt to find it if it was recreated
		if ( !WeakAsset.IsValid() && !AssetPath.IsEmpty() )
		{
			Asset = FindObject<UObject>(nullptr, *AssetPath);
		}

		AssetEditorOpenedEvent.Broadcast(Asset);
	}
	else if( bCanSummonSimpleAssetEditor )
	{
		// No asset type actions for this asset. Just use a properties editor.
		FSimpleAssetEditor::CreateEditor(ActualToolkitMode, ActualToolkitMode == EToolkitMode::WorldCentric ? OpenedFromLevelEditor : TSharedPtr<IToolkitHost>(), Asset);
	}

	GWarn->EndSlowTask();
	return true;
}
Exemplo n.º 10
0
bool RemoveUniformBuffersFromSource(FString& SourceCode)
{
	static const FString StaticStructToken(TEXT("static const struct"));
	int32 StaticStructTokenPos = SourceCode.Find(StaticStructToken, ESearchCase::CaseSensitive, ESearchDir::FromStart);
	while (StaticStructTokenPos != INDEX_NONE)
	{
		static const FString CloseBraceSpaceToken(TEXT("} "));
		int32 CloseBraceSpaceTokenPos = SourceCode.Find(CloseBraceSpaceToken, ESearchCase::CaseSensitive, ESearchDir::FromStart, StaticStructTokenPos + StaticStructToken.Len());
		if (CloseBraceSpaceTokenPos == INDEX_NONE)
		{
			check(0);	//@todo-rco: ERROR
			return false;
		}

		int32 NamePos = CloseBraceSpaceTokenPos + CloseBraceSpaceToken.Len();
		static const FString SpaceEqualsToken(TEXT(" ="));
		int32 SpaceEqualsTokenPos = SourceCode.Find(SpaceEqualsToken, ESearchCase::CaseSensitive, ESearchDir::FromStart, NamePos);
		if (SpaceEqualsTokenPos == INDEX_NONE)
		{
			check(0);	//@todo-rco: ERROR
			return false;
		}

		FString UniformBufferName = SourceCode.Mid(NamePos, SpaceEqualsTokenPos - NamePos);
		check(UniformBufferName.Len() > 0);

		static const FString CloseBraceSemicolorToken(TEXT("};"));
		int32 CloseBraceSemicolonTokenPos = SourceCode.Find(CloseBraceSemicolorToken, ESearchCase::CaseSensitive, ESearchDir::FromStart, SpaceEqualsTokenPos + SpaceEqualsToken.Len());
		if (CloseBraceSemicolonTokenPos == INDEX_NONE)
		{
			check(0);	//@todo-rco: ERROR
			return false;
		}

		// Comment out this UB
		auto& SourceCharArray = SourceCode.GetCharArray();
		SourceCharArray[StaticStructTokenPos] = TCHAR('/');
		SourceCharArray[StaticStructTokenPos + 1] = TCHAR('*');
		SourceCharArray[CloseBraceSemicolonTokenPos] = TCHAR('*');
		SourceCharArray[CloseBraceSemicolonTokenPos + 1] = TCHAR('/');

		// Find & Replace this UB
		FString UBSource = UniformBufferName + FString(TEXT("."));
		FString UBDest = UniformBufferName + FString(TEXT("_"));
		SourceCode.ReplaceInline(*UBSource, *UBDest, ESearchCase::CaseSensitive);


		// Find next UB
		StaticStructTokenPos = SourceCode.Find(StaticStructToken, ESearchCase::CaseSensitive, ESearchDir::FromStart, CloseBraceSemicolonTokenPos + 2);
	}

	return true;
}
Exemplo n.º 11
0
void FMapInfoParser::ParseDoomEdNums()
{
	TMap<int, bool> defined;
	int error = 0;

	MapinfoEdMapItem editem;

	editem.filename = sc.ScriptName;

	ParseOpenBrace();
	while (true)
	{
		if (sc.CheckString("}")) return;
		else if (sc.CheckNumber())
		{
			int ednum = sc.Number;
			sc.MustGetStringName("=");
			sc.MustGetString();

			bool *def = defined.CheckKey(ednum);
			if (def != NULL)
			{
				sc.ScriptMessage("Editor Number %d defined more than once", ednum);
				error++;
			}
			defined[ednum] = true;
			if (sc.String[0] == '$')
			{
				// todo: add special stuff like playerstarts and sound sequence overrides here, too.
				editem.classname = NAME_None;
				editem.special = sc.MustMatchString(SpecialMapthingNames) + 1; // todo: assign proper constants
			}
			else
			{
				editem.classname = sc.String;
				editem.special = -1;
			}
			memset(editem.args, 0, sizeof(editem.args));
			editem.argsdefined = 0;

			int minargs = 0;
			int maxargs = 5;
			FString specialname;
			if (sc.CheckString(","))
			{
				editem.argsdefined = 5; // mark args as used - if this is done we need to prevent assignment of map args in P_SpawnMapThing.
				if (editem.special < 0) editem.special = 0;
				if (!sc.CheckNumber())
				{
					sc.MustGetString();
					specialname = sc.String;	// save for later error reporting.
					editem.special = P_FindLineSpecial(sc.String, &minargs, &maxargs);
					if (editem.special == 0 || minargs == -1)
					{
						sc.ScriptMessage("Invalid special %s for Editor Number %d", sc.String, ednum);
						error++;
						minargs = 0;
						maxargs = 5;
					}
					if (!sc.CheckString(","))
					{
						// special case: Special without arguments
						if (minargs != 0)
						{
							sc.ScriptMessage("Incorrect number of args for special %s, min = %d, max = %d, found = 0", specialname.GetChars(), minargs, maxargs);
							error++;
						}
						DoomEdFromMapinfo.Insert(ednum, editem);
						continue;
					}
					sc.MustGetNumber();
				}
				int i = 0;
				while (i < 5)
				{
					editem.args[i] = sc.Number;
					i++;
					if (!sc.CheckString(",")) break;
					// special check for the ambient sounds which combine the arg being set here with the ones on the mapthing.
					if (sc.CheckString("+"))
					{
						editem.argsdefined = i;
						break;
					}
					sc.MustGetNumber();

				}
				if (specialname.IsNotEmpty() && (i < minargs || i > maxargs))
				{
					sc.ScriptMessage("Incorrect number of args for special %s, min = %d, max = %d, found = %d", specialname.GetChars(), minargs, maxargs, i);
					error++;
				}
			}
			DoomEdFromMapinfo.Insert(ednum, editem);
		}
		else
		{
			sc.ScriptError("Number expected");
		}
	}
	if (error > 0)
	{
		sc.ScriptError("%d errors encountered in DoomEdNum definition", error);
	}
}
Exemplo n.º 12
0
MapData *P_OpenMapData(const char * mapname, bool justcheck)
{
	MapData * map = new MapData;
	FileReader * wadReader = nullptr;
	bool externalfile = !strnicmp(mapname, "file:", 5);
	
	if (externalfile)
	{
		mapname += 5;
		if (!FileExists(mapname))
		{
			delete map;
			return NULL;
		}
		map->resource = FResourceFile::OpenResourceFile(mapname, true);
		wadReader = map->resource->GetReader();
	}
	else
	{
		FString fmt;
		int lump_wad;
		int lump_map;
		int lump_name = -1;
		
		// Check for both *.wad and *.map in order to load Build maps
		// as well. The higher one will take precedence.
		// Names with more than 8 characters will only be checked as .wad and .map.
		if (strlen(mapname) <= 8) lump_name = Wads.CheckNumForName(mapname);
		fmt.Format("maps/%s.wad", mapname);
		lump_wad = Wads.CheckNumForFullName(fmt);
		fmt.Format("maps/%s.map", mapname);
		lump_map = Wads.CheckNumForFullName(fmt);
		
		if (lump_name > lump_wad && lump_name > lump_map && lump_name != -1)
		{
			int lumpfile = Wads.GetLumpFile(lump_name);
			int nextfile = Wads.GetLumpFile(lump_name+1);

			map->lumpnum = lump_name;

			if (lumpfile != nextfile)
			{
				// The following lump is from a different file so whatever this is,
				// it is not a multi-lump Doom level so let's assume it is a Build map.
				map->MapLumps[0].Reader = Wads.ReopenLumpReader(lump_name);
				if (!P_IsBuildMap(map))
				{
					delete map;
					return NULL;
				}
				return map;
			}

			// This case can only happen if the lump is inside a real WAD file.
			// As such any special handling for other types of lumps is skipped.
			map->MapLumps[0].Reader = Wads.ReopenLumpReader(lump_name);
			strncpy(map->MapLumps[0].Name, Wads.GetLumpFullName(lump_name), 8);
			map->Encrypted = Wads.IsEncryptedFile(lump_name);
			map->InWad = true;

			if (map->Encrypted)
			{ // If it's encrypted, then it's a Blood file, presumably a map.
				if (!P_IsBuildMap(map))
				{
					delete map;
					return NULL;
				}
				return map;
			}

			int index = 0;

			if (stricmp(Wads.GetLumpFullName(lump_name + 1), "TEXTMAP") != 0)
			{
				for(int i = 1;; i++)
				{
					// Since levels must be stored in WADs they can't really have full
					// names and for any valid level lump this always returns the short name.
					const char * lumpname = Wads.GetLumpFullName(lump_name + i);
					try
					{
						index = GetMapIndex(mapname, index, lumpname, !justcheck);
					}
					catch(...)
					{
						delete map;
						throw;
					}
					if (index == -2)
					{
						delete map;
						return NULL;
					}
					if (index == ML_BEHAVIOR) map->HasBehavior = true;

					// The next lump is not part of this map anymore
					if (index < 0) break;

					map->MapLumps[index].Reader = Wads.ReopenLumpReader(lump_name + i);
					strncpy(map->MapLumps[index].Name, lumpname, 8);
				}
			}
			else
			{
				map->isText = true;
				map->MapLumps[1].Reader = Wads.ReopenLumpReader(lump_name + 1);
				for(int i = 2;; i++)
				{
					const char * lumpname = Wads.GetLumpFullName(lump_name + i);

					if (lumpname == NULL)
					{
						I_Error("Invalid map definition for %s", mapname);
					}
					else if (!stricmp(lumpname, "ZNODES"))
					{
						index = ML_GLZNODES;
					}
					else if (!stricmp(lumpname, "BLOCKMAP"))
					{
						// there is no real point in creating a blockmap but let's use it anyway
						index = ML_BLOCKMAP;
					}
					else if (!stricmp(lumpname, "REJECT"))
					{
						index = ML_REJECT;
					}
					else if (!stricmp(lumpname, "DIALOGUE"))
					{
						index = ML_CONVERSATION;
					}
					else if (!stricmp(lumpname, "BEHAVIOR"))
					{
						index = ML_BEHAVIOR;
						map->HasBehavior = true;
					}
					else if (!stricmp(lumpname, "ENDMAP"))
					{
						break;
					}
					else continue;
					map->MapLumps[index].Reader = Wads.ReopenLumpReader(lump_name + i);
					strncpy(map->MapLumps[index].Name, lumpname, 8);
				}
			}
			return map;
		}
		else
		{
			if (lump_map > lump_wad)
			{
				lump_wad = lump_map;
			}
			if (lump_wad == -1)
			{
				delete map;
				return NULL;
			}
			map->lumpnum = lump_wad;
			auto reader = Wads.ReopenLumpReader(lump_wad);
			map->resource = FResourceFile::OpenResourceFile(Wads.GetLumpFullName(lump_wad), reader, true);
			wadReader = map->resource->GetReader();
		}
	}
	uint32_t id;

	// Although we're using the resource system, we still want to be sure we're
	// reading from a wad file.
	wadReader->Seek(0, FileReader::SeekSet);
	wadReader->Read(&id, sizeof(id));
	
	if (id == IWAD_ID || id == PWAD_ID)
	{
		char maplabel[9]="";
		int index=0;

		map->MapLumps[0].Reader = map->resource->GetLump(0)->NewReader();
		strncpy(map->MapLumps[0].Name, map->resource->GetLump(0)->Name, 8);

		for(uint32_t i = 1; i < map->resource->LumpCount(); i++)
		{
			const char* lumpname = map->resource->GetLump(i)->Name;

			if (i == 1 && !strnicmp(lumpname, "TEXTMAP", 8))
			{
				map->isText = true;
				map->MapLumps[ML_TEXTMAP].Reader = map->resource->GetLump(i)->NewReader();
				strncpy(map->MapLumps[ML_TEXTMAP].Name, lumpname, 8);
				for(int i = 2;; i++)
				{
					lumpname = map->resource->GetLump(i)->Name;
					if (!strnicmp(lumpname, "ZNODES",8))
					{
						index = ML_GLZNODES;
					}
					else if (!strnicmp(lumpname, "BLOCKMAP",8))
					{
						// there is no real point in creating a blockmap but let's use it anyway
						index = ML_BLOCKMAP;
					}
					else if (!strnicmp(lumpname, "REJECT",8))
					{
						index = ML_REJECT;
					}
					else if (!strnicmp(lumpname, "DIALOGUE",8))
					{
						index = ML_CONVERSATION;
					}
					else if (!strnicmp(lumpname, "BEHAVIOR",8))
					{
						index = ML_BEHAVIOR;
						map->HasBehavior = true;
					}
					else if (!strnicmp(lumpname, "ENDMAP",8))
					{
						return map;
					}
					else continue;
					map->MapLumps[index].Reader = map->resource->GetLump(i)->NewReader();
					strncpy(map->MapLumps[index].Name, lumpname, 8);
				}
			}

			if (i>0)
			{
				try
				{
					index = GetMapIndex(maplabel, index, lumpname, !justcheck);
				}
				catch(...)
				{
					delete map;
					throw;
				}
				if (index == -2)
				{
					delete map;
					return NULL;
				}
				if (index == ML_BEHAVIOR) map->HasBehavior = true;

				// The next lump is not part of this map anymore
				if (index < 0) break;
			}
			else
			{
				strncpy(maplabel, lumpname, 8);
				maplabel[8]=0;
			}

			map->MapLumps[index].Reader = map->resource->GetLump(i)->NewReader();
			strncpy(map->MapLumps[index].Name, lumpname, 8);
		}
	}
	else
	{
		// This is a Build map and not subject to WAD consistency checks.
		//map->MapLumps[0].Size = wadReader->GetLength();
		if (!P_IsBuildMap(map))
		{
			delete map;
			return NULL;
		}
	}
	return map;		
}
Exemplo n.º 13
0
void UJanusExporterTool::Export()
{
	TArray<UObject*> ObjectsToExport;

	FString Root = FString(ExportPath); // copy so we dont mess with the original reference
	FString Index = "<html>\n\t<head>\n\t\t<title>Unreal Export</title>\n\t</head>\n\t<body>\n\t\t<FireBoxRoom>\n\t\t\t<Assets>";

	TArray<AActor*> ActorsExported;
	TArray<UStaticMesh*> StaticMeshesExp;
	TArray<FString> TexturesExp;
	TArray<FString> MaterialsExported;

	for (TObjectIterator<AActor> Itr; Itr; ++Itr)
	{
		AActor *Actor = *Itr;

		FString Name = Actor->GetName();
		/*if (!Name.StartsWith("SM_Floor_R"))
		{
			continue;
		}*/

		if (Actor->IsHiddenEd())
		{
			continue;
		}

		ActorsExported.Add(Actor);

		TArray<UStaticMeshComponent*> StaticMeshes;
		Actor->GetComponents<UStaticMeshComponent>(StaticMeshes);
		for (int32 i = 0; i < StaticMeshes.Num(); i++)
		{
			UStaticMeshComponent* Component = StaticMeshes[i];
			UStaticMesh *Mesh = Component->StaticMesh;
			if (!Mesh)
			{
				continue;
			}

			if (Component->LODData.Num() > 0)
				//if (false)
			{
				FStaticMeshComponentLODInfo* LODInfo = &Component->LODData[0];
				FLightMap* LightMap = LODInfo->LightMap;
				FShadowMap* ShadowMap = LODInfo->ShadowMap;
				if (LightMap != NULL)
				{
					FLightMap2D* LightMap2D = LightMap->GetLightMap2D();
					UTexture2D* Texture = LightMap2D->GetTexture(0); // 0 = HQ LightMap
					FString TexName = Texture->GetName();
					if (TexturesExp.Contains(TexName))
					{
						continue;
					}

					TexturesExp.Add(TexName);
					ExportPNG(Texture, Root);
				}
				if (ShadowMap != NULL)
				{
					FShadowMap2D* ShadowMap2D = ShadowMap->GetShadowMap2D();
					UShadowMapTexture2D* ShadowTex = ShadowMap2D->GetTexture();
					FString TexName = ShadowTex->GetName();
					if (TexturesExp.Contains(TexName))
					{
						continue;
					}

					TexturesExp.Add(TexName);
					ExportPNG(ShadowTex, Root);
				}
			}

			if (!StaticMeshesExp.Contains(Mesh))
			{
				StaticMeshesExp.Add(Mesh);
				ExportFBX(Mesh, Root);
			}

			TArray<UMaterialInterface*> Materials = Component->GetMaterials();
			for (int32 j = 0; j < Materials.Num(); j++)
			{
				UMaterialInterface* Material = Materials[j];
				if (!Material)
				{
					continue;
				}

				FString MatName = Material->GetName();

				if (MaterialsExported.Contains(MatName))
				{
					continue;
				}

				MaterialsExported.Add(MatName);
				ExportMaterial(Root, Material, &TexturesExp);
			}
		}
	}

	// Models before textures so we can start showing the scene faster (textures take too long to load)
	for (int32 i = 0; i < StaticMeshesExp.Num(); i++)
	{
		UStaticMesh *mesh = StaticMeshesExp[i];

		Index.Append("\n\t\t\t\t<AssetObject id=\"" + mesh->GetName() + "\" src=\"" + mesh->GetName() + ".fbx\" />");
	}

	for (int32 i = 0; i < TexturesExp.Num(); i++)
	{
		FString Path = TexturesExp[i];

		Index.Append("\n\t\t\t\t<AssetImage id=\"" + Path + "\" src=\"" + Path + ".png\" />");
	}

	Index.Append("\n\t\t\t</Assets>\n\t\t\t<Room>");

	for (int32 i = 0; i < ActorsExported.Num(); i++)
	{
		AActor *Actor = ActorsExported[i];

		TArray<UStaticMeshComponent*> StaticMeshes;
		Actor->GetComponents<UStaticMeshComponent>(StaticMeshes);
		for (int32 i = 0; i < StaticMeshes.Num(); i++)
		{
			UStaticMeshComponent* Component = StaticMeshes[i];
			UStaticMesh *Mesh = Component->StaticMesh;
			if (!Mesh)
			{
				continue;
			}

			FString ImageID = "";

			TArray<UMaterialInterface*> Materials = Component->GetMaterials();
			for (int32 j = 0; j < Materials.Num(); j++)
			{
				UMaterialInterface* Material = Materials[j];
				if (!Material)
				{
					continue;
				}
				ImageID = Material->GetName() + "_BaseColor";
				break;
			}

			if (ImageID == "")
			{
				Index.Append("\n\t\t\t\t<Object collision_id=\"" + Mesh->GetName() + "\" id=\"" + Mesh->GetName() + "\" lighting=\"true\" pos=\"");
			}
			else
			{
				Index.Append("\n\t\t\t\t<Object collision_id=\"" + Mesh->GetName() + "\" id=\"" + Mesh->GetName() + "\" image_id=\"" + ImageID + "\" lighting=\"true\" pos=\"");
			}

			FRotator Rot = Actor->GetActorRotation();
			FVector XDir = Rot.RotateVector(FVector::RightVector);
			FVector YDir = Rot.RotateVector(FVector::UpVector);
			FVector ZDir = Rot.RotateVector(FVector::ForwardVector);

			FVector Pos = Actor->GetActorLocation() * UniformScale;
			FVector Sca = Actor->GetActorScale();

			Pos = ChangeSpace(Pos);
			Sca = ChangeSpaceScalar(Sca) * UniformScale;

			XDir = ChangeSpace(XDir);
			YDir = ChangeSpace(YDir);
			ZDir = ChangeSpace(ZDir);
			FVector Sign = GetSignVector(Sca);

			Index.Append(FString::SanitizeFloat(Pos.X) + " " + FString::SanitizeFloat(Pos.Y) + " " + FString::SanitizeFloat(Pos.Z));
			if (Sca.X < 0 || Sca.Y < 0 || Sca.Z < 0)
			{
				Index.Append("\" cull_face=\"front");
			}

			Index.Append("\" scale=\"");
			Index.Append(FString::SanitizeFloat(Sca.X) + " " + FString::SanitizeFloat(Sca.Y) + " " + FString::SanitizeFloat(Sca.Z));

			Index.Append("\" xdir=\"");
			Index.Append(FString::SanitizeFloat(XDir.X) + " " + FString::SanitizeFloat(XDir.Y) + " " + FString::SanitizeFloat(XDir.Z));

			Index.Append("\" ydir=\"");
			Index.Append(FString::SanitizeFloat(YDir.X) + " " + FString::SanitizeFloat(YDir.Y) + " " + FString::SanitizeFloat(YDir.Z));

			Index.Append("\" zdir=\"");
			Index.Append(FString::SanitizeFloat(ZDir.X) + " " + FString::SanitizeFloat(ZDir.Y) + " " + FString::SanitizeFloat(ZDir.Z));

			Index.Append("\" />");
		}
	}

	Index.Append("\n\t\t\t</Room>\n\t\t</FireBoxRoom>\n\t</body>\n</html>");

	FString IndexPath = FString(ExportPath).Append("index.html");
	FFileHelper::SaveStringToFile(Index, *IndexPath);
}
bool UOnlineHotfixManager::HotfixIniFile(const FString& FileName, const FString& IniData)
{
	FConfigFile* ConfigFile = GetConfigFile(FileName);
	// Merge the string into the config file
	ConfigFile->CombineFromBuffer(IniData);
	TArray<UClass*> Classes;
	TArray<UObject*> PerObjectConfigObjects;
	int32 StartIndex = 0;
	int32 EndIndex = 0;
	// Find the set of object classes that were affected
	while (StartIndex >= 0 && StartIndex < IniData.Len() && EndIndex >= StartIndex)
	{
		// Find the next section header
		StartIndex = IniData.Find(TEXT("["), ESearchCase::IgnoreCase, ESearchDir::FromStart, StartIndex);
		if (StartIndex > -1)
		{
			// Find the ending section identifier
			EndIndex = IniData.Find(TEXT("]"), ESearchCase::IgnoreCase, ESearchDir::FromStart, StartIndex);
			if (EndIndex > StartIndex)
			{
				int32 PerObjectNameIndex = IniData.Find(TEXT(" "), ESearchCase::IgnoreCase, ESearchDir::FromStart, StartIndex);
				// Per object config entries will have a space in the name, but classes won't
				if (PerObjectNameIndex == -1 || PerObjectNameIndex > EndIndex)
				{
					if (IniData.StartsWith(TEXT("[/Script/"), ESearchCase::IgnoreCase))
					{
						const int32 ScriptSectionTag = 9;
						// Snip the text out and try to find the class for that
						const FString PackageClassName = IniData.Mid(StartIndex + ScriptSectionTag, EndIndex - StartIndex - ScriptSectionTag);
						// Find the class for this so we know what to update
						UClass* Class = FindObject<UClass>(nullptr, *PackageClassName, true);
						if (Class)
						{
							// Add this to the list to check against
							Classes.Add(Class);
						}
					}
				}
				// Handle the per object config case by finding the object for reload
				else
				{
					const int32 Count = PerObjectNameIndex - StartIndex - 1;
					const FString PerObjectName = IniData.Mid(StartIndex + 1, Count);
					// Explicitly search the transient package (won't update non-transient objects)
					UObject* PerObject = FindObject<UObject>(ANY_PACKAGE, *PerObjectName, false);
					if (PerObject != nullptr)
					{
						PerObjectConfigObjects.Add(PerObject);
					}
				}
				StartIndex = EndIndex;
			}
		}
	}

	int32 NumObjectsReloaded = 0;
	const double StartTime = FPlatformTime::Seconds();
	if (Classes.Num())
	{
		// Now that we have a list of classes to update, we can iterate objects and reload
		for (FObjectIterator It; It; ++It)
		{
			UClass* Class = It->GetClass();
			if (Class->HasAnyClassFlags(CLASS_Config))
			{
				// Check to see if this class is in our list (yes, potentially n^2, but not in practice)
				for (int32 ClassIndex = 0; ClassIndex < Classes.Num(); ClassIndex++)
				{
					if (It->IsA(Classes[ClassIndex]))
					{
						// Force a reload of the config vars
						It->ReloadConfig();
						NumObjectsReloaded++;
						break;
					}
				}
			}
		}
	}
	// Reload any PerObjectConfig objects that were affected
	for (auto ReloadObject : PerObjectConfigObjects)
	{
		ReloadObject->ReloadConfig();
		NumObjectsReloaded++;
	}
	UE_LOG(LogHotfixManager, Log, TEXT("Updating config from %s took %f seconds and reloaded %d objects"),
		*FileName, FPlatformTime::Seconds() - StartTime, NumObjectsReloaded);
	return true;
}
Exemplo n.º 15
0
bool FAndroidMediaPlayer::Open(const FString& Url)
{
	if (Url.IsEmpty())
	{
		return false;
	}

	if (MediaState != EMediaState::Idle)
	{
		return false;
	}

	if (Url.StartsWith(TEXT("http:")) || Url.StartsWith(TEXT("https:")) ||
		Url.StartsWith(TEXT("rtsp:")) || Url.StartsWith(TEXT("file:")))
	{
		// Direct open media at a "remote" URL.
		JavaMediaPlayer->SetDataSource(Url);
		MediaState = EMediaState::Initialized;
	}
	else
	{
		// Use the platform file layer to open the media file. We
		// need to access Android specific information to allow
		// for playing media that is embedded in the APK, OBBs,
		// and/or PAKs.

		// Construct a canonical path for the movie.
		FString MoviePath = Url;
		FPaths::NormalizeFilename(MoviePath);

		// Don't bother trying to play it if we can't find it.
		if (!IAndroidPlatformFile::GetPlatformPhysical().FileExists(*MoviePath))
		{
			return false;
		}

		// Get information about the movie.
		int64 FileOffset = IAndroidPlatformFile::GetPlatformPhysical().FileStartOffset(*MoviePath);
		int64 FileSize = IAndroidPlatformFile::GetPlatformPhysical().FileSize(*MoviePath);
		FString FileRootPath = IAndroidPlatformFile::GetPlatformPhysical().FileRootPath(*MoviePath);

		// Play the movie as a file or asset.
		if (IAndroidPlatformFile::GetPlatformPhysical().IsAsset(*MoviePath))
		{
			if (JavaMediaPlayer->SetDataSource(
				IAndroidPlatformFile::GetPlatformPhysical().GetAssetManager(),
				FileRootPath, FileOffset, FileSize))
			{
				MediaState = EMediaState::Initialized;
			}
		}
		else
		{
			if (JavaMediaPlayer->SetDataSource(FileRootPath, FileOffset, FileSize))
			{
				MediaState = EMediaState::Initialized;
			}
		}
	}
	if (MediaState == EMediaState::Initialized)
	{
		MediaUrl = Url;
		JavaMediaPlayer->Prepare();
		MediaState = EMediaState::Prepared;
	}
	if (MediaState == EMediaState::Prepared)
	{
		// Use the extension as a rough guess as to what tracks
		// to use.
		FString Extension = FPaths::GetExtension(MediaUrl);
		if (Extension.Equals(TEXT("3gpp"), ESearchCase::IgnoreCase) ||
			Extension.Equals(TEXT("mp4"), ESearchCase::IgnoreCase))
		{
			// For video we add video track and disable audio
			JavaMediaPlayer->SetAudioEnabled(false);
//			AudioTracks.Add(MakeShareable(new AudioTrack(*this, AudioTracks.Num())));
			VideoTracks.Add(MakeShareable(new VideoTrack(*this, VideoTracks.Num())));
		}
		else if (Extension.Equals(TEXT("aac"), ESearchCase::IgnoreCase))
		{
			AudioTracks.Add(MakeShareable(new AudioTrack(*this, AudioTracks.Num())));
		}

		TracksChangedEvent.Broadcast();
	}
	if (MediaState == EMediaState::Prepared)
	{
		OpenedEvent.Broadcast(MediaUrl);
	}
	return MediaState == EMediaState::Prepared;
}
Exemplo n.º 16
0
bool NUTNet::CreateFakePlayer(UWorld* InWorld, UNetDriver*& InNetDriver, FString ServerIP, FNetworkNotify* InNotify/*=NULL*/,
								bool bSkipJoin/*=false*/, FUniqueNetIdRepl* InNetID/*=NULL*/, bool bBeaconConnect/*=false*/,
								FString InBeaconType/*=TEXT("")*/)
{
	bool bSuccess = false;

	if (InNetDriver == NULL)
	{
		InNetDriver = (InWorld != NULL ? NUTNet::CreateUnitTestNetDriver(InWorld) : NULL);
	}

	if (InNetDriver != NULL)
	{
		if (InNotify == NULL)
		{
			FNetworkNotifyHook* NotifyHook = new FNetworkNotifyHook();
			InNotify = NotifyHook;

			auto DefaultRejectChan = [](UChannel* Channel)
				{
					UE_LOG(LogUnitTest, Log, TEXT("UnitTestNetDriver: NotifyAcceptingChannel: %s"), *Channel->Describe());

					return false;
				};

			NotifyHook->NotifyAcceptingChannelDelegate.BindLambda(DefaultRejectChan);
		}

		FURL DefaultURL;
		FURL TravelURL(&DefaultURL, *ServerIP, TRAVEL_Absolute);
		FString ConnectionError;

		if (InNetDriver->InitConnect(InNotify, TravelURL, ConnectionError))
		{
			UNetConnection* TargetConn = InNetDriver->ServerConnection;

			UE_LOG(LogUnitTest, Log, TEXT("Successfully kicked off connect to IP '%s'"), *ServerIP);


			int ControlBunchSequence = 0;

			FOutBunch* ControlChanBunch = NUTNet::CreateChannelBunch(ControlBunchSequence, TargetConn, CHTYPE_Control, 0);

			// Need to send 'NMT_Hello' to start off the connection (the challenge is not replied to)
			uint8 IsLittleEndian = uint8(PLATFORM_LITTLE_ENDIAN);

			// We need to construct the NMT_Hello packet manually, for the initial connection
			uint8 MessageType = NMT_Hello;

			*ControlChanBunch << MessageType;
			*ControlChanBunch << IsLittleEndian;


#if TARGET_UE4_CL >= CL_FNETWORKVERSION
			// Starting with 4.8.0, the network protocol has changed slightly
			// @todo JohnB: Refactor this, to toggle at compile time only, based on CL (might require more accurate UT integrate CLs)
			FString VersionStr = GEngineVersion.ToString(EVersionComponent::Minor);
			int32 VersionDelim = VersionStr.Find(TEXT("."));
			int32 MajorVersion = FCString::Atoi(*VersionStr.Left(VersionDelim));
			int32 MinorVersion = FCString::Atoi(*VersionStr.Right(VersionDelim));

			bool bOldProtocol = (MajorVersion <= 4 && MinorVersion <= 7) &&
				/** Exception for UT (treat 4.7 as having the new protocol) */
				(FString(FApp::GetGameName()) != TEXT("UnrealTournament") || (MajorVersion <= 4 && MinorVersion <= 6));

			if (bOldProtocol)
#endif
			{
				*ControlChanBunch << GEngineMinNetVersion;
				*ControlChanBunch << GEngineNetVersion;
				*ControlChanBunch << (FGuid&)GetDefault<UGeneralProjectSettings>()->ProjectID;
			}
#if TARGET_UE4_CL >= CL_FNETWORKVERSION
			else
			{
				uint32 LocalNetworkVersion = FNetworkVersion::GetLocalNetworkVersion();
				*ControlChanBunch << LocalNetworkVersion;
			}
#endif


			if (bBeaconConnect)
			{
				if (!bSkipJoin)
				{
					MessageType = NMT_BeaconJoin;
					*ControlChanBunch << MessageType;
					*ControlChanBunch << InBeaconType;

					// Also immediately ack the beacon GUID setup; we're just going to let the server setup the client beacon,
					// through the actor channel
					MessageType = NMT_BeaconNetGUIDAck;
					*ControlChanBunch << MessageType;
					*ControlChanBunch << InBeaconType;
				}
			}
			else
			{
				// Then send NMT_Login
				TSharedPtr<FUniqueNetId> DudPtr = MakeShareable(new FUniqueNetIdString(TEXT("Dud")));
				FUniqueNetIdRepl PlayerUID(DudPtr);
				FString BlankStr = TEXT("");
				FString ConnectURL = UUnitTest::UnitEnv->GetDefaultClientConnectURL();

				if (InNetID != NULL)
				{
					PlayerUID = *InNetID;
				}

				MessageType = NMT_Login;
				*ControlChanBunch << MessageType;
				*ControlChanBunch << BlankStr;
				*ControlChanBunch << ConnectURL;
				*ControlChanBunch << PlayerUID;


				// Now send NMT_Join, to trigger a fake player, which should then trigger replication of basic actor channels
				if (!bSkipJoin)
				{
					MessageType = NMT_Join;
					*ControlChanBunch << MessageType;
				}
			}


			// Big hack: Store OutRec value on the unit test control channel, to enable 'retry-send' code
			TargetConn->Channels[0]->OutRec = ControlChanBunch;

			TargetConn->SendRawBunch(*ControlChanBunch, true);


			bSuccess = true;

		}
		else
		{
			UE_LOG(LogUnitTest, Log, TEXT("Failed to kickoff connect to IP '%s', error: %s"), *ServerIP, *ConnectionError);
		}
	}
	else if (InNetDriver == NULL)
	{
		UE_LOG(LogUnitTest, Log, TEXT("Failed to create an instance of the unit test net driver"));
	}
	else
	{
		UE_LOG(LogUnitTest, Log, TEXT("Failed to get a reference to WorldContext"));
	}

	return bSuccess;
}
	virtual bool SupportedByExtensionsString( const FString& ExtensionsString, const int GLESVersion ) const override
	{
		return ExtensionsString.Contains(TEXT("GL_KHR_texture_compression_astc_ldr"));
	}
Exemplo n.º 18
0
bool P_UndoPlayerMorph (player_t *activator, player_t *player, int unmorphflag, bool force)
{
	AWeapon *beastweap;
	APlayerPawn *mo;
	APlayerPawn *pmo;

	pmo = player->mo;
	// [MH]
	// Checks pmo as well; the PowerMorph destroyer will
	// try to unmorph the player; if the destroyer runs
	// because the level or game is ended while morphed,
	// by the time it gets executed the morphed player
	// pawn instance may have already been destroyed.
	if (pmo == nullptr || pmo->alternative == nullptr)
	{
		return false;
	}

	bool DeliberateUnmorphIsOkay = !!(MORPH_STANDARDUNDOING & unmorphflag);

    if ((pmo->flags2 & MF2_INVULNERABLE) // If the player is invulnerable
        && ((player != activator)       // and either did not decide to unmorph,
        || (!((player->MorphStyle & MORPH_WHENINVULNERABLE)  // or the morph style does not allow it
        || (DeliberateUnmorphIsOkay))))) // (but standard morph styles always allow it),
	{ // Then the player is immune to the unmorph.
		return false;
	}

	mo = barrier_cast<APlayerPawn *>(pmo->alternative);
	mo->SetOrigin (pmo->Pos(), false);
	mo->flags |= MF_SOLID;
	pmo->flags &= ~MF_SOLID;
	if (!force && !P_TestMobjLocation (mo))
	{ // Didn't fit
		mo->flags &= ~MF_SOLID;
		pmo->flags |= MF_SOLID;
		player->morphTics = 2*TICRATE;
		return false;
	}
	// No longer using tracer as morph storage. That is what 'alternative' is for. 
	// If the tracer has changed on the morph, change the original too.
	mo->target = pmo->target;
	mo->tracer = pmo->tracer;
	pmo->player = nullptr;

	// Remove the morph power if the morph is being undone prematurely.
	for (AInventory *item = pmo->Inventory, *next = nullptr; item != nullptr; item = next)
	{
		next = item->Inventory;
		if (item->IsKindOf(RUNTIME_CLASS(APowerMorph)))
		{
			static_cast<APowerMorph *>(item)->SetNoCallUndoMorph();
			item->Destroy();
		}
	}
	EndAllPowerupEffects(pmo->Inventory);
	mo->ObtainInventory (pmo);
	DObject::StaticPointerSubstitution (pmo, mo);
	if ((pmo->tid != 0) && (player->MorphStyle & MORPH_NEWTIDBEHAVIOUR))
	{
		mo->tid = pmo->tid;
		mo->AddToHash ();
	}
	mo->Angles.Yaw = pmo->Angles.Yaw;
	mo->player = player;
	mo->reactiontime = 18;
	mo->flags = ActorFlags::FromInt (pmo->special2) & ~MF_JUSTHIT;
	mo->Vel.X = mo->Vel.Y = 0;
	player->Vel.Zero();
	mo->Vel.Z = pmo->Vel.Z;
	if (!(pmo->special2 & MF_JUSTHIT))
	{
		mo->renderflags &= ~RF_INVISIBLE;
	}
	mo->flags  = (mo->flags & ~(MF_SHADOW|MF_NOGRAVITY)) | (pmo->flags & (MF_SHADOW|MF_NOGRAVITY));
	mo->flags2 = (mo->flags2 & ~MF2_FLY) | (pmo->flags2 & MF2_FLY);
	mo->flags3 = (mo->flags3 & ~MF3_GHOST) | (pmo->flags3 & MF3_GHOST);
	mo->Score = pmo->Score;
	InitAllPowerupEffects(mo->Inventory);

	PClassActor *exit_flash = player->MorphExitFlash;
	bool correctweapon = !!(player->MorphStyle & MORPH_LOSEACTUALWEAPON);
	bool undobydeathsaves = !!(player->MorphStyle & MORPH_UNDOBYDEATHSAVES);

	player->morphTics = 0;
	player->MorphedPlayerClass = 0;
	player->MorphStyle = 0;
	player->MorphExitFlash = nullptr;
	player->viewheight = mo->ViewHeight;
	AInventory *level2 = mo->FindInventory (RUNTIME_CLASS(APowerWeaponLevel2), true);
	if (level2 != nullptr)
	{
		level2->Destroy ();
	}

	if ((player->health > 0) || undobydeathsaves)
	{
		player->health = mo->health = mo->SpawnHealth();
	}
	else // killed when morphed so stay dead
	{
		mo->health = player->health;
	}

	player->mo = mo;
	if (player->camera == pmo)
	{
		player->camera = mo;
	}

	// [MH]
	// If the player that was morphed is the one
	// taking events, reset up the face, if any;
	// this is only needed for old-skool skins
	// and for the original DOOM status bar.
	if (player == &players[consoleplayer])
	{
		FString face = pmo->GetClass()->Face;
		if (face.IsNotEmpty() && strcmp(face, "None") != 0)
		{
			// Assume root-level base skin to begin with
			size_t skinindex = 0;
			// If a custom skin was in use, then reload it
			// or else the base skin for the player class.
			if ((unsigned int)player->userinfo.GetSkin() >= PlayerClasses.Size () &&
				(size_t)player->userinfo.GetSkin() < numskins)
			{

				skinindex = player->userinfo.GetSkin();
			}
			else if (PlayerClasses.Size () > 1)
			{
				const PClass *whatami = player->mo->GetClass();
				for (unsigned int i = 0; i < PlayerClasses.Size (); ++i)
				{
					if (PlayerClasses[i].Type == whatami)
					{
						skinindex = i;
						break;
					}
				}
			}
		}
	}

	AActor *eflash = nullptr;
	if (exit_flash != nullptr)
	{
		eflash = Spawn(exit_flash, pmo->Vec3Angle(20., mo->Angles.Yaw, TELEFOGHEIGHT), ALLOW_REPLACE);
		if (eflash)	eflash->target = mo;
	}
	mo->SetupWeaponSlots();		// Use original class's weapon slots.
	beastweap = player->ReadyWeapon;
	if (player->PremorphWeapon != nullptr)
	{
		player->PremorphWeapon->PostMorphWeapon ();
	}
	else
	{
		player->ReadyWeapon = player->PendingWeapon = nullptr;
	}
	if (correctweapon)
	{ // Better "lose morphed weapon" semantics
		PClassActor *morphweapon = PClass::FindActor(pmo->MorphWeapon);
		if (morphweapon != nullptr && morphweapon->IsDescendantOf(RUNTIME_CLASS(AWeapon)))
		{
			AWeapon *OriginalMorphWeapon = static_cast<AWeapon *>(mo->FindInventory (morphweapon));
			if ((OriginalMorphWeapon != nullptr) && (OriginalMorphWeapon->GivenAsMorphWeapon))
			{ // You don't get to keep your morphed weapon.
				if (OriginalMorphWeapon->SisterWeapon != nullptr)
				{
					OriginalMorphWeapon->SisterWeapon->Destroy ();
				}
				OriginalMorphWeapon->Destroy ();
			}
		}
 	}
	else // old behaviour (not really useful now)
	{ // Assumptions made here are no longer valid
		if (beastweap != nullptr)
		{ // You don't get to keep your morphed weapon.
			if (beastweap->SisterWeapon != nullptr)
			{
				beastweap->SisterWeapon->Destroy ();
			}
			beastweap->Destroy ();
		}
	}
	mo->alternative = nullptr;
	pmo->alternative = nullptr;
	pmo->Destroy ();
	// Restore playerclass armor to its normal amount.
	AHexenArmor *hxarmor = mo->FindInventory<AHexenArmor>();
	if (hxarmor != nullptr)
	{
		hxarmor->Slots[4] = mo->GetClass()->HexenArmor[0];
	}
	return true;
}
Exemplo n.º 19
0
void gl_InitModels()
{
	int Lump, lastLump;
	FString path;
	int index;
	int i;

	FSpriteModelFrame smf;

	lastLump = 0;

	memset(&smf, 0, sizeof(smf));
	while ((Lump = Wads.FindLump("MODELDEF", &lastLump)) != -1)
	{
		FScanner sc(Lump);
		while (sc.GetString())
		{
			if (sc.Compare("model"))
			{
				sc.MustGetString();
				memset(&smf, 0, sizeof(smf));
				smf.xscale=smf.yscale=smf.zscale=1.f;

				smf.type = PClass::FindClass(sc.String);
				if (!smf.type || smf.type->Defaults == NULL) 
				{
					sc.ScriptError("MODELDEF: Unknown actor type '%s'\n", sc.String);
				}
				GetDefaultByType(smf.type)->hasmodel=true;
				sc.MustGetStringName("{");
				while (!sc.CheckString("}"))
				{
					sc.MustGetString();
					if (sc.Compare("path"))
					{
						sc.MustGetString();
						FixPathSeperator(sc.String);
						path = sc.String;
						if (path[(int)path.Len()-1]!='/') path+='/';
					}
					else if (sc.Compare("model"))
					{
						sc.MustGetNumber();
						index=sc.Number;
						if (index<0 || index>=MAX_MODELS_PER_FRAME)
						{
							sc.ScriptError("Too many models in %s", smf.type->TypeName.GetChars());
						}
						sc.MustGetString();
						FixPathSeperator(sc.String);
						smf.models[index] = FindModel(path.GetChars(), sc.String);
						if (!smf.models[index])
						{
							Printf("%s: model not found\n", sc.String);
						}
					}
					else if (sc.Compare("scale"))
					{
						sc.MustGetFloat();
						smf.xscale=sc.Float;
						sc.MustGetFloat();
						smf.yscale=sc.Float;
						sc.MustGetFloat();
						smf.zscale=sc.Float;
					}
					// [BB] Added zoffset reading.
					else if (sc.Compare("zoffset"))
					{
						sc.MustGetFloat();
						smf.zoffset=sc.Float;
					}
					// [BB] Added model flags reading.
					else if (sc.Compare("ignoretranslation"))
					{
						smf.flags |= MDL_IGNORETRANSLATION;
					}
					else if (sc.Compare("pitchfrommomentum"))
					{
						smf.flags |= MDL_PITCHFROMMOMENTUM;
					}
					else if (sc.Compare("rotating"))
					{
						smf.flags |= MDL_ROTATING;
						smf.xrotate = 0.;
						smf.yrotate = 1.;
						smf.zrotate = 0.;
						smf.rotationCenterX = 0.;
						smf.rotationCenterY = 0.;
						smf.rotationCenterZ = 0.;
						smf.rotationSpeed = 1.;
					}
					else if (sc.Compare("rotation-speed"))
					{
						sc.MustGetFloat();
						smf.rotationSpeed = sc.Float;
					}
					else if (sc.Compare("rotation-vector"))
					{
						sc.MustGetFloat();
						smf.xrotate = sc.Float;
						sc.MustGetFloat();
						smf.yrotate = sc.Float;
						sc.MustGetFloat();
						smf.zrotate = sc.Float;
					}
					else if (sc.Compare("rotation-center"))
					{
						sc.MustGetFloat();
						smf.rotationCenterX = sc.Float;
						sc.MustGetFloat();
						smf.rotationCenterY = sc.Float;
						sc.MustGetFloat();
						smf.rotationCenterZ = sc.Float;
					}
					else if (sc.Compare("interpolatedoubledframes"))
					{
						smf.flags |= MDL_INTERPOLATEDOUBLEDFRAMES;
					}
					else if (sc.Compare("nointerpolation"))
					{
						smf.flags |= MDL_NOINTERPOLATION;
					}
					else if (sc.Compare("alignangle"))
					{
						smf.flags |= MDL_ALIGNANGLE;
					}
					else if (sc.Compare("alignpitch"))
					{
						smf.flags |= MDL_ALIGNPITCH;
					}
					else if (sc.Compare("rollagainstangle"))
					{
						smf.flags |= MDL_ROLLAGAINSTANGLE;
					}
					else if (sc.Compare("skin"))
					{
						sc.MustGetNumber();
						index=sc.Number;
						if (index<0 || index>=MAX_MODELS_PER_FRAME)
						{
							sc.ScriptError("Too many models in %s", smf.type->TypeName.GetChars());
						}
						sc.MustGetString();
						FixPathSeperator(sc.String);
						if (sc.Compare(""))
						{
							smf.skins[index]=NULL;
						}
						else
						{
							smf.skins[index]=LoadSkin(path.GetChars(), sc.String);
							if (smf.skins[index] == NULL)
							{
								Printf("Skin '%s' not found in '%s'\n",
									sc.String, smf.type->TypeName.GetChars());
							}
						}
					}
					else if (sc.Compare("frameindex") || sc.Compare("frame"))
					{
						bool isframe=!!sc.Compare("frame");

						sc.MustGetString();
						smf.sprite = -1;
						for (i = 0; i < (int)sprites.Size (); ++i)
						{
							if (strncmp (sprites[i].name, sc.String, 4) == 0)
							{
								if (sprites[i].numframes==0)
								{
									//sc.ScriptError("Sprite %s has no frames", sc.String);
								}
								smf.sprite = i;
								break;
							}
						}
						if (smf.sprite==-1)
						{
							sc.ScriptError("Unknown sprite %s in model definition for %s", sc.String, smf.type->TypeName.GetChars());
						}

						sc.MustGetString();
						FString framechars = sc.String;

						sc.MustGetNumber();
						index=sc.Number;
						if (index<0 || index>=MAX_MODELS_PER_FRAME)
						{
							sc.ScriptError("Too many models in %s", smf.type->TypeName.GetChars());
						}
						if (isframe)
						{
							sc.MustGetString();
							if (smf.models[index]!=NULL) 
							{
								smf.modelframes[index] = smf.models[index]->FindFrame(sc.String);
								if (smf.modelframes[index]==-1) sc.ScriptError("Unknown frame '%s' in %s", sc.String, smf.type->TypeName.GetChars());
							}
							else smf.modelframes[index] = -1;
						}
						else
						{
							sc.MustGetNumber();
							smf.modelframes[index] = sc.Number;
						}

						for(i=0; framechars[i]>0; i++)
						{
							char map[29]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
							int c = toupper(framechars[i])-'A';

							if (c<0 || c>=29)
							{
								sc.ScriptError("Invalid frame character %c found", c+'A');
							}
							if (map[c]) continue;
							smf.frame=c;
							SpriteModelFrames.Push(smf);
							map[c]=1;
						}
					}
				}
			}
		}
	}

	// create a hash table for quick access
	SpriteModelHash = new int[SpriteModelFrames.Size ()];
	atterm(DeleteModelHash);
	memset(SpriteModelHash, 0xff, SpriteModelFrames.Size () * sizeof(int));

	for (i = 0; i < (int)SpriteModelFrames.Size (); i++)
	{
		int j = ModelFrameHash(&SpriteModelFrames[i]) % SpriteModelFrames.Size ();

		SpriteModelFrames[i].hashnext = SpriteModelHash[j];
		SpriteModelHash[j]=i;
	}
}
Exemplo n.º 20
0
FString FCulture::FICUCultureImplementation::GetName() const
{
	FString Result = ICULocale.getName();
	Result.ReplaceInline(TEXT("_"), TEXT("-"));
	return Result;
}
Exemplo n.º 21
0
bool FDesktopPlatformBase::BuildUnrealBuildTool(const FString& RootDir, FOutputDevice& Ar)
{
	Ar.Logf(TEXT("Building UnrealBuildTool in %s..."), *RootDir);

	// Check the project file exists
	FString CsProjLocation = GetUnrealBuildToolProjectFileName(RootDir);
	if(!FPaths::FileExists(CsProjLocation))
	{
		Ar.Logf(TEXT("Project file not found at %s"), *CsProjLocation);
		return false;
	}

	FString CompilerExecutableFilename;
	FString CmdLineParams;

	if (PLATFORM_WINDOWS)
	{
		// To build UBT for windows, we must assemble a batch file that first registers the environment variable necessary to run msbuild then run it
		// This can not be done in a single invocation of CMD.exe because the environment variables do not transfer between subsequent commands when using the "&" syntax
		// devenv.exe can be used to build as well but it takes several seconds to start up so it is not desirable

		// First determine the appropriate vcvars batch file to launch
		FString VCVarsBat;

#if PLATFORM_WINDOWS
	#if _MSC_VER >= 1800
		FPlatformMisc::GetVSComnTools(12, VCVarsBat);
	#else
		FPlatformMisc::GetVSComnTools(11, VCVarsBat);
	#endif
#endif // PLATFORM_WINDOWS

		VCVarsBat = FPaths::Combine(*VCVarsBat, L"../../VC/bin/x86_amd64/vcvarsx86_amd64.bat");

		// Check to make sure we found one.
		if (VCVarsBat.IsEmpty() || !FPaths::FileExists(VCVarsBat))
		{
			Ar.Logf(TEXT("Couldn't find %s; skipping."), *VCVarsBat);
			return false;
		}

		// Now make a batch file in the intermediate directory to invoke the vcvars batch then msbuild
		FString BuildBatchFile = RootDir / TEXT("Engine/Intermediate/Build/UnrealBuildTool/BuildUBT.bat");
		BuildBatchFile.ReplaceInline(TEXT("/"), TEXT("\\"));

		FString BatchFileContents;
		BatchFileContents = FString::Printf(TEXT("call \"%s\"") LINE_TERMINATOR, *VCVarsBat);
		BatchFileContents += FString::Printf(TEXT("msbuild /nologo /verbosity:quiet \"%s\" /property:Configuration=Development /property:Platform=AnyCPU"), *CsProjLocation);
		FFileHelper::SaveStringToFile(BatchFileContents, *BuildBatchFile);

		TCHAR CmdExePath[MAX_PATH];
		FPlatformMisc::GetEnvironmentVariable(TEXT("ComSpec"), CmdExePath, ARRAY_COUNT(CmdExePath));
		CompilerExecutableFilename = CmdExePath;

		CmdLineParams = FString::Printf(TEXT("/c \"%s\""), *BuildBatchFile);
	}
	else if (PLATFORM_MAC)
	{
		FString ScriptPath = FPaths::ConvertRelativePathToFull(RootDir / TEXT("Engine/Build/BatchFiles/Mac/RunXBuild.sh"));
		CompilerExecutableFilename = TEXT("/bin/sh");
		CmdLineParams = FString::Printf(TEXT("\"%s\" /property:Configuration=Development %s"), *ScriptPath, *CsProjLocation);
	}
	else if (PLATFORM_LINUX)
	{
		FString ScriptPath = FPaths::ConvertRelativePathToFull(RootDir / TEXT("Engine/Build/BatchFiles/Linux/RunXBuild.sh"));
		CompilerExecutableFilename = TEXT("/bin/bash");
		CmdLineParams = FString::Printf(TEXT("\"%s\" /property:Configuration=Development /property:TargetFrameworkVersion=v4.0 %s"), *ScriptPath, *CsProjLocation);
	}
	else
	{
		Ar.Log(TEXT("Unknown platform, unable to build UnrealBuildTool."));
		return false;
	}

	// Spawn the compiler
	Ar.Logf(TEXT("Running: %s %s"), *CompilerExecutableFilename, *CmdLineParams);
	const bool bLaunchDetached = false;
	const bool bLaunchHidden = true;
	const bool bLaunchReallyHidden = bLaunchHidden;
	FProcHandle ProcHandle = FPlatformProcess::CreateProc(*CompilerExecutableFilename, *CmdLineParams, bLaunchDetached, bLaunchHidden, bLaunchReallyHidden, NULL, 0, NULL, NULL);
	if (!ProcHandle.IsValid())
	{
		Ar.Log(TEXT("Failed to start process."));
		return false;
	}
	FPlatformProcess::WaitForProc(ProcHandle);
	FPlatformProcess::CloseProc(ProcHandle);

	// If the executable appeared where we expect it, then we were successful
	FString UnrealBuildToolExePath = GetUnrealBuildToolExecutableFilename(RootDir);
	if(!FPaths::FileExists(UnrealBuildToolExePath))
	{
		Ar.Logf(TEXT("Missing %s after build"), *UnrealBuildToolExePath);
		return false;
	}

	return true;
}
Exemplo n.º 22
0
void SFlareNewGameMenu::Construct(const FArguments& InArgs)
{
	// Data
	MenuManager = InArgs._MenuManager;
	const FFlareStyleCatalog& Theme = FFlareStyleSet::GetDefaultTheme();
	Game = MenuManager->GetPC()->GetGame();

	// Game starts
	ScenarioList.Add(MakeShareable(new FString(TEXT("Freighter"))));
	//ScenarioList.Add(MakeShareable(new FString(TEXT("Fighter"))));
	//ScenarioList.Add(MakeShareable(new FString(TEXT("Debug"))));

	// Color
	FLinearColor Color = Theme.NeutralColor;
	Color.A = Theme.DefaultAlpha;

	// Name
	FText DefaultName = LOCTEXT("CompanyName", "Player Inc");
	FString PlayerName = MenuManager->GetPC()->PlayerState->PlayerName;
	if (PlayerName.Len())
	{
		DefaultName = FText::Format(LOCTEXT("CompanyNameFormat", "{0} Corp"), FText::FromString(PlayerName));
	}

	// Build structure
	ChildSlot
	.HAlign(HAlign_Fill)
	.VAlign(VAlign_Fill)
	.Padding(FMargin(0, AFlareMenuManager::GetMainOverlayHeight(), 0, 0))
	[
		SNew(SVerticalBox)
		
		// Main form
		+ SVerticalBox::Slot()
		.AutoHeight()
		.Padding(Theme.ContentPadding)
		.HAlign(HAlign_Center)
		[
			SNew(SBox)
			.WidthOverride(Theme.ContentWidth / 2)
			.HAlign(HAlign_Fill)
			[
				SNew(SVerticalBox)
				
				// Company name
				+ SVerticalBox::Slot()
				.Padding(Theme.ContentPadding)
				.AutoHeight()
				[
					SNew(SBorder)
					.BorderImage(&Theme.BackgroundBrush)
					.Padding(Theme.ContentPadding)
					[
						SAssignNew(CompanyName, SEditableText)
						.Text(DefaultName)
						.Style(&Theme.TextInputStyle)
					]
				]

				// Color picker
				//+ SVerticalBox::Slot()
				//.Padding(Theme.ContentPadding)
				//.AutoHeight()
				//[
				//	SAssignNew(ColorBox, SFlareColorPanel)
				//	.MenuManager(MenuManager)
				//]

				// Scenario
				+ SVerticalBox::Slot()
				.AutoHeight()
				.Padding(Theme.ContentPadding)
				[
					SAssignNew(ScenarioSelector, SComboBox<TSharedPtr<FString>>)
					.OptionsSource(&ScenarioList)
					.InitiallySelectedItem(ScenarioList[0])
					.OnGenerateWidget(this, &SFlareNewGameMenu::OnGenerateComboLine)
					.OnSelectionChanged(this, &SFlareNewGameMenu::OnComboLineSelectionChanged)
					.ComboBoxStyle(&Theme.ComboBoxStyle)
					.ForegroundColor(FLinearColor::White)
					[
						SNew(STextBlock)
						.Text(this, &SFlareNewGameMenu::OnGetCurrentComboLine)
						.TextStyle(&Theme.TextFont)
					]
				]

				// Tutorial
				+ SVerticalBox::Slot()
				.AutoHeight()
				.Padding(Theme.ContentPadding)
				.HAlign(HAlign_Right)
				[
					SAssignNew(TutorialButton, SFlareButton)
					.Text(LOCTEXT("Tutorial", "Play tutorial"))
					.HelpText(LOCTEXT("TutorialInfo", "Start with a few tutorial missions"))
					.Toggle(true)
				]

				// Start
				+ SVerticalBox::Slot()
				.AutoHeight()
				.Padding(Theme.ContentPadding)
				.HAlign(HAlign_Right)
				[
					SNew(SFlareButton)
					.Text(LOCTEXT("Start", "Start the game"))
					.HelpText(LOCTEXT("StartInfo", "Confirm the creation of a new game and start playing"))
					.Icon(FFlareStyleSet::GetIcon("Load"))
					.OnClicked(this, &SFlareNewGameMenu::OnLaunch)
				]
			]
		]
	];

	TutorialButton->SetActive(true);
}
Exemplo n.º 23
0
int32 BuildPatchToolMain( const TCHAR* CommandLine )
{
	// Initialize the command line
	FCommandLine::Set(CommandLine);

	// Add log devices
	if (FParse::Param(FCommandLine::Get(), TEXT("stdout")))
	{
		GLog->AddOutputDevice(new FBuildPatchOutputDevice());
	}
	if (FPlatformMisc::IsDebuggerPresent())
	{
		GLog->AddOutputDevice(new FOutputDeviceDebug());
	}

	GLog->Logf(TEXT("BuildPatchToolMain ran with: %s"), CommandLine);

	FPlatformProcess::SetCurrentWorkingDirectoryToBaseDir();
	bool bSuccess = false;

	FString RootDirectory;
	FString CloudDirectory;
	uint32  AppID=0;
	FString AppName;
	FString BuildVersion;
	FString LaunchExe;
	FString LaunchCommand;
	FString IgnoreListFile;
	FString AttributeListFile;
	FString PrereqName;
	FString PrereqPath;
	FString PrereqArgs;
	FString ManifestsList;
	FString ManifestsFile;
	float DataAgeThreshold = 0.0f;
	FString IniFile;
	TMap<FString, FVariant> CustomFields;

	bool bCompactify = false;
	bool bPatchGeneration = true;
	bool bPreview = false;
	bool bNoPatchDelete = false;
	bool bPatchWithReuseAgeThreshold = true;

	// Collect all the info from the CommandLine
	TArray< FString > Tokens, Switches;
	FCommandLine::Parse(FCommandLine::Get(), Tokens, Switches);
	if (Switches.Num() > 0)
	{
		int32 BuildRootIdx;
		int32 CloudDirIdx;
		int32 AppIDIdx;
		int32 AppNameIdx;
		int32 BuildVersionIdx;
		int32 AppLaunchIdx;
		int32 AppArgsIdx;
		int32 FileIgnoreListIdx;
		int32 FileAttributeListIdx;
		int32 PrereqNameIdx;
		int32 PrereqPathIdx;
		int32 PrereqArgsIdx;
		int32 ManifestsListIdx;
		int32 ManifestsFileIdx;
		int32 DataAgeThresholdIdx;

		FCommandLineMatcher Matcher;
		bSuccess = true;

		Matcher.Command = TEXT("compactify");
		bCompactify = Switches.IndexOfByPredicate(Matcher) != INDEX_NONE;
		bPatchGeneration = !bCompactify;

		Matcher.Command = TEXT("preview");
		bPreview = bCompactify && Switches.IndexOfByPredicate(Matcher) != INDEX_NONE;

		Matcher.Command = TEXT("nopatchdelete");
		bNoPatchDelete = bCompactify && Switches.IndexOfByPredicate(Matcher) != INDEX_NONE;
		
		Matcher.Command = TEXT( "BuildRoot" );
		BuildRootIdx = Switches.IndexOfByPredicate(Matcher);

		Matcher.Command = TEXT( "CloudDir" );
		CloudDirIdx = Switches.IndexOfByPredicate(Matcher);

		Matcher.Command = TEXT( "AppID" );
		AppIDIdx = Switches.IndexOfByPredicate(Matcher);

		Matcher.Command = TEXT( "AppName" );
		AppNameIdx = Switches.IndexOfByPredicate(Matcher);

		Matcher.Command = TEXT( "BuildVersion" );
		BuildVersionIdx = Switches.IndexOfByPredicate(Matcher);

		Matcher.Command = TEXT( "AppLaunch" );
		AppLaunchIdx = Switches.IndexOfByPredicate(Matcher);

		Matcher.Command = TEXT( "AppArgs" );
		AppArgsIdx = Switches.IndexOfByPredicate(Matcher);

		Matcher.Command = TEXT( "FileIgnoreList" );
		FileIgnoreListIdx = Switches.IndexOfByPredicate(Matcher);

		Matcher.Command = TEXT("FileAttributeList");
		FileAttributeListIdx = Switches.IndexOfByPredicate(Matcher);

		Matcher.Command = TEXT( "PrereqName" );
		PrereqNameIdx = Switches.IndexOfByPredicate(Matcher);

		Matcher.Command = TEXT( "PrereqPath" );
		PrereqPathIdx = Switches.IndexOfByPredicate(Matcher);

		Matcher.Command = TEXT( "PrereqArgs" );
		PrereqArgsIdx = Switches.IndexOfByPredicate(Matcher);

		Matcher.Command = TEXT("ManifestsList");
		ManifestsListIdx = Switches.IndexOfByPredicate(Matcher);

		Matcher.Command = TEXT("ManifestsFile");
		ManifestsFileIdx = Switches.IndexOfByPredicate(Matcher);

		Matcher.Command = TEXT("DataAgeThreshold");
		DataAgeThresholdIdx = Switches.IndexOfByPredicate(Matcher);

		// Check required param indexes
		bSuccess = bSuccess && CloudDirIdx != INDEX_NONE;
		if (bPatchGeneration)
		{
			bSuccess = bSuccess && BuildRootIdx != INDEX_NONE;
			bSuccess = bSuccess && AppIDIdx != INDEX_NONE;
			bSuccess = bSuccess && AppNameIdx != INDEX_NONE;
			bSuccess = bSuccess && BuildVersionIdx != INDEX_NONE;
			bSuccess = bSuccess && AppLaunchIdx != INDEX_NONE;
			bSuccess = bSuccess && AppArgsIdx != INDEX_NONE;
		}

		// Get required param values
		bSuccess = bSuccess && FParse::Value( *Switches[CloudDirIdx], TEXT( "CloudDir=" ), CloudDirectory );
		if (bPatchGeneration)
		{
			bSuccess = bSuccess && FParse::Value(*Switches[BuildRootIdx], TEXT("BuildRoot="), RootDirectory);
			bSuccess = bSuccess && FParse::Value(*Switches[AppIDIdx], TEXT("AppID="), AppID);
			bSuccess = bSuccess && FParse::Value(*Switches[AppNameIdx], TEXT("AppName="), AppName);
			bSuccess = bSuccess && FParse::Value(*Switches[BuildVersionIdx], TEXT("BuildVersion="), BuildVersion);
			bSuccess = bSuccess && FParse::Value(*Switches[AppLaunchIdx], TEXT("AppLaunch="), LaunchExe);
			bSuccess = bSuccess && FParse::Value(*Switches[AppArgsIdx], TEXT("AppArgs="), LaunchCommand);
		}

		// Get optional param values
		if( FileIgnoreListIdx != INDEX_NONE )
		{
			FParse::Value( *Switches[ FileIgnoreListIdx ], TEXT( "FileIgnoreList=" ), IgnoreListFile );
		}

		if( FileAttributeListIdx != INDEX_NONE )
		{
			FParse::Value( *Switches[ FileAttributeListIdx ], TEXT( "FileAttributeList=" ), AttributeListFile );
		}

		if( PrereqNameIdx != INDEX_NONE )
		{
			FParse::Value( *Switches[ PrereqNameIdx ], TEXT( "PrereqName=" ), PrereqName );
		}

		if( PrereqPathIdx != INDEX_NONE )
		{
			FParse::Value( *Switches[ PrereqPathIdx ], TEXT( "PrereqPath=" ), PrereqPath );
		}

		if( PrereqArgsIdx != INDEX_NONE )
		{
			FParse::Value( *Switches[ PrereqArgsIdx ], TEXT( "PrereqArgs=" ), PrereqArgs );
		}

		if (ManifestsListIdx != INDEX_NONE)
		{
			bool bShouldStopOnComma = false;
			FParse::Value(*Switches[ManifestsListIdx], TEXT("ManifestsList="), ManifestsList, bShouldStopOnComma);
		}
		else if (ManifestsFileIdx != INDEX_NONE)
		{
			FParse::Value( *Switches[ ManifestsFileIdx ], TEXT( "ManifestsFile=" ), ManifestsFile);
		}

		FString CustomValue;
		FString Left;
		FString Right;
		for (const auto& Switch : Switches)
		{
			if (FParse::Value(*Switch, TEXT("custom="), CustomValue))
			{
				if (CustomValue.Split(TEXT("="), &Left, &Right))
				{
					Left.Trim();
					Left.TrimTrailing();
					Right.Trim();
					Right.TrimTrailing();
					CustomFields.Add(Left, FVariant(Right));
				}
			}
			else if (FParse::Value(*Switch, TEXT("customfloat="), CustomValue))
			{
				if (CustomValue.Split(TEXT("="), &Left, &Right))
				{
					Left.Trim();
					Left.TrimTrailing();
					Right.Trim();
					Right.TrimTrailing();
					if (!Right.IsNumeric())
					{
						GLog->Log(ELogVerbosity::Error, TEXT("An error occurred processing token -customfloat. Non Numeric character found right of ="));
						bSuccess = false;
					}
					CustomFields.Add(Left, FVariant(TCString<TCHAR>::Atod(*Right)));
				}
			}
			else if (FParse::Value(*Switch, TEXT("customint="), CustomValue))
			{
				if (CustomValue.Split(TEXT("="), &Left, &Right))
				{
					Left.Trim();
					Left.TrimTrailing();
					Right.Trim();
					Right.TrimTrailing();
					if (!Right.IsNumeric())
					{
						GLog->Log(ELogVerbosity::Error, TEXT("An error occurred processing token -customint. Non Numeric character found right of ="));
						bSuccess = false;
					}
					CustomFields.Add(Left, FVariant(TCString<TCHAR>::Atoi64(*Right)));
				}
			}
		}

		FPaths::NormalizeDirectoryName( RootDirectory );
		FPaths::NormalizeDirectoryName( CloudDirectory );

		if (bSuccess)
		{
			// Initialize the configuration system, we can only do this reliably if we have CloudDirectory (i.e. bSuccess is true)
			IniFile = CloudDirectory / TEXT("BuildPatchTool.ini");
			GConfig->InitializeConfigSystem();
		}

		if (DataAgeThresholdIdx != INDEX_NONE)
		{
			FParse::Value(*Switches[DataAgeThresholdIdx], TEXT("DataAgeThreshold="), DataAgeThreshold);
		}
		else if (bSuccess && bCompactify)
		{
			// For compactification, if we don't pass in DataAgeThreshold, and it's not in BuildPatchTool.ini,
			// then we set it to zero, to indicate that any unused chunks are valid for deletion
			if (!GConfig->GetFloat(TEXT("Compactify"), TEXT("DataAgeThreshold"), DataAgeThreshold, IniFile))
			{
				GLog->Log(ELogVerbosity::Warning, TEXT("DataAgeThreshold not supplied, so all unreferenced data is eliglble for deletion. Note that this process is NOT compatible with any concurrently running patch generaiton processes"));
				DataAgeThreshold = 0.0f;
			}
		}
		else if (bSuccess && bPatchGeneration)
		{
			// For patch generation, if we don't pass in DataAgeThreshold, and it's not specified in BuildPatchTool.ini,
			// then we set bChunkWithReuseAgeThreshold to false, which indicates that *all* patch data is valid for reuse
			if (!GConfig->GetFloat(TEXT("PatchGeneration"), TEXT("DataAgeThreshold"), DataAgeThreshold, IniFile))
			{
				GLog->Log(ELogVerbosity::Warning, TEXT("DataAgeThreshold not supplied, so all existing data is eligible for reuse. Note that this process is NOT compatible with any concurrently running compactify processes"));
				DataAgeThreshold = 0.0f;
				bPatchWithReuseAgeThreshold = false;
			}
		}
	}

	// Initialize the file manager
	IFileManager::Get().ProcessCommandLineOptions();

	// Check for argument error
	if( !bSuccess )
	{
		GLog->Log(ELogVerbosity::Error, TEXT("An error occurred processing arguments"));
		return 1;
	}

	if (bCompactify && bPreview && bNoPatchDelete)
	{
		GLog->Log(ELogVerbosity::Error, TEXT("Only one of -preview and -nopatchdelete can be specified"));
		return 5;
	}

	if (!IgnoreListFile.IsEmpty() && !FPaths::FileExists(IgnoreListFile))
	{
		GLog->Logf(ELogVerbosity::Error, TEXT("Provided file ignore list was not found %s"), *IgnoreListFile);
		return 6;
	}

	if (!AttributeListFile.IsEmpty() && !FPaths::FileExists(AttributeListFile))
	{
		GLog->Logf(ELogVerbosity::Error, TEXT("Provided file attribute list was not found %s"), *AttributeListFile);
		return 7;
	}

	// Load the BuildPatchServices Module
	TSharedPtr<IBuildPatchServicesModule> BuildPatchServicesModule = StaticCastSharedPtr<IBuildPatchServicesModule>( FModuleManager::Get().LoadModule( TEXT( "BuildPatchServices" ) ) );

	// Initialise the UObject system and process our uobject classes
	FModuleManager::Get().LoadModule(TEXT("CoreUObject"));
	FCoreDelegates::OnInit.Broadcast();
	ProcessNewlyLoadedUObjects();

	// Setup the module
	BuildPatchServicesModule->SetCloudDirectory( CloudDirectory + TEXT( "/" ) );

	if (bCompactify)
	{
		// Split out our manifests to keep arg (if any) into an array of manifest filenames
		TArray<FString> ManifestsArr;
		if (ManifestsList.Len() > 0)
		{
			ManifestsList.ParseIntoArray(&ManifestsArr, TEXT(","), true);
		}
		else if (ManifestsFile.Len() > 0)
		{
			FString ManifestsFilePath = CloudDirectory / ManifestsFile;
			FString Temp;
			if (FFileHelper::LoadFileToString(Temp, *ManifestsFilePath))
			{
				Temp.ReplaceInline(TEXT("\r"), TEXT("\n"));
				Temp.ParseIntoArray(&ManifestsArr, TEXT("\n"), true);
			}
			else
			{
				GLog->Log(ELogVerbosity::Error, TEXT("Could not open specified manifests to keep file"));
				BuildPatchServicesModule.Reset();
				FCoreDelegates::OnExit.Broadcast();
				return 2;
			}
		}

		// Determine our mode of operation
		ECompactifyMode::Type CompactifyMode = ECompactifyMode::Full;
		if (bPreview)
		{
			CompactifyMode = ECompactifyMode::Preview;
		}
		else if (bNoPatchDelete)
		{
			CompactifyMode = ECompactifyMode::NoPatchDelete;
		}

		// Run the compactify routine
		bSuccess = BuildPatchServicesModule->CompactifyCloudDirectory(ManifestsArr, DataAgeThreshold, CompactifyMode);
	}
	else if (bPatchGeneration)
	{
		FBuildPatchSettings Settings;
		Settings.RootDirectory = RootDirectory + TEXT("/");
		Settings.AppID = AppID;
		Settings.AppName = AppName;
		Settings.BuildVersion = BuildVersion;
		Settings.LaunchExe = LaunchExe;
		Settings.LaunchCommand = LaunchCommand;
		Settings.IgnoreListFile = IgnoreListFile;
		Settings.AttributeListFile = AttributeListFile;
		Settings.PrereqName = PrereqName;
		Settings.PrereqPath = PrereqPath;
		Settings.PrereqArgs = PrereqArgs;
		Settings.DataAgeThreshold = DataAgeThreshold;
		Settings.bShouldHonorReuseThreshold = bPatchWithReuseAgeThreshold;
		Settings.CustomFields = CustomFields;

		// Run the build generation
		if (FParse::Param(FCommandLine::Get(), TEXT("nochunks")))
		{
			bSuccess = BuildPatchServicesModule->GenerateFilesManifestFromDirectory(Settings);
		}
		else
		{
			bSuccess = BuildPatchServicesModule->GenerateChunksManifestFromDirectory(Settings);
		}
	}
	else
	{
		GLog->Log(ELogVerbosity::Error, TEXT("Unknown tool mode"));
		BuildPatchServicesModule.Reset();
		FCoreDelegates::OnExit.Broadcast();
		return 3;
	}

	// Release the module ptr
	BuildPatchServicesModule.Reset();

	// Check for processing error
	if (!bSuccess)
	{
		GLog->Log(ELogVerbosity::Error, TEXT("A fatal error occurred executing BuildPatchTool.exe"));
		FCoreDelegates::OnExit.Broadcast();
		return 4;
	}

	FCoreDelegates::OnExit.Broadcast();

	GLog->Log(TEXT("BuildPatchToolMain completed successfuly"));
	return 0;
}
bool FDefaultValueHelper::StringFromCppString(const FString& Source, const FString& TypeName, FString& OutForm)
{
	int32 Pos = 0, PendingParentheses = 0;

	if( !Trim(Pos, Source) )
	{
		return false;
	}

	// remove "TypeName ( "
	if (Source.Find(TypeName, ESearchCase::CaseSensitive) == Pos)
	{
		Pos += TypeName.Len();
		if( !Trim(Pos, Source) )
		{
			return false;
		}

		if (Source.Find(FString("::"), ESearchCase::CaseSensitive) == Pos)
		{
			Pos += 2;

			if (!Trim(Pos, Source))
			{
				return false;
			}

			const FString AllowedFunctionName(TEXT("FromString"));
			if (Source.Find(AllowedFunctionName, ESearchCase::CaseSensitive, ESearchDir::FromStart, Pos) == Pos)
			{
				Pos += AllowedFunctionName.Len();
			}
			else
			{
				return false;
			}

			if (!Trim(Pos, Source))
			{
				return false;
			}
		}

		if( TS(TEXT("(")) != Source[Pos++] )
		{
			return false;
		}
		PendingParentheses++;
		if( !Trim(Pos, Source) )
		{
			return false;
		}		
	}

	// remove "TEXT ( "
	const TCHAR* TextStr = TEXT("TEXT");
	if (Source.Find(TextStr, ESearchCase::CaseSensitive) == Pos)
	{
		Pos += FCString::Strlen(TextStr);
		if( !Trim(Pos, Source) )
		{
			return false;
		}
		if( TS(TEXT("(")) != Source[Pos++] )
		{
			return false;
		}
		PendingParentheses++;
		if( !Trim(Pos, Source) )
		{
			return false;
		}
	}

	// ensure the beginning of actual string is found
	if( TS(TEXT("\"")) != Source[Pos++] )
	{
		return false;
	}
	const int32 StartPos = Pos;
	int32 EndPos = -1;

	// find end of the actual string
	for(; Pos < Source.Len(); ++Pos)
	{
		if( ( TS(TEXT("\"")) == Source[Pos] ) && ( TS(TEXT("\\")) != Source[Pos-1] ) )
		{
			EndPos = Pos;
			Pos++;
			break;
		}
	}

	for(; Pos < Source.Len(); ++Pos)
	{
		if( TS(TEXT(")")) == Source[Pos] ) 
		{
			PendingParentheses--;
		}
		else if(!IsWhitespace(Source[Pos]))
		{
			return false;
		}
	}

	if(EndPos < 0 || 0 != PendingParentheses)
	{
		return false;
	}

	OutForm = Source.Mid(StartPos, EndPos - StartPos);
	return true;
}
Exemplo n.º 25
0
void FSceneView::ConfigureBufferVisualizationSettings()
{
	bool bBufferDumpingRequired = (FScreenshotRequest::IsScreenshotRequested() || GIsHighResScreenshot || GIsDumpingMovie);
	bool bVisualizationRequired = Family->EngineShowFlags.VisualizeBuffer;
	
	if (bVisualizationRequired || bBufferDumpingRequired)
	{
		FinalPostProcessSettings.bBufferVisualizationDumpRequired = bBufferDumpingRequired;
		FinalPostProcessSettings.BufferVisualizationOverviewMaterials.Empty();

		if (bBufferDumpingRequired)
		{
			FinalPostProcessSettings.BufferVisualizationDumpBaseFilename = FPaths::GetBaseFilename(FScreenshotRequest::GetFilename(), false);
		}

		// Get the list of requested buffers from the console
		static IConsoleVariable* CVar = IConsoleManager::Get().FindConsoleVariable(TEXT("r.BufferVisualizationOverviewTargets"));
		FString SelectedMaterialNames = CVar->GetString();

		FBufferVisualizationData& BufferVisualizationData = GetBufferVisualizationData();

		if (BufferVisualizationData.IsDifferentToCurrentOverviewMaterialNames(SelectedMaterialNames))
		{
			FString Left, Right;

			// Update our record of the list of materials we've been asked to display
			BufferVisualizationData.SetCurrentOverviewMaterialNames(SelectedMaterialNames);
			BufferVisualizationData.GetOverviewMaterials().Empty();

			// Note - This will re-parse the list of names from the console variable every frame. It could be cached and only updated when
			// the variable value changes if this turns out to be a performance issue.
		
			// Extract each material name from the comma separated string
			while (SelectedMaterialNames.Len())
			{
				// Detect last entry in the list
				if (!SelectedMaterialNames.Split(TEXT(","), &Left, &Right))
				{
					Left = SelectedMaterialNames;
					Right = FString();
				}

				// Lookup this material from the list that was parsed out of the global ini file
				Left = Left.Trim();
				UMaterial* Material = BufferVisualizationData.GetMaterial(*Left);

				if (Material == NULL && Left.Len() > 0)
				{
					UE_LOG(LogBufferVisualization, Warning, TEXT("Unknown material '%s'"), *Left);
				}

				// Add this material into the material list in the post processing settings so that the render thread
				// can pick them up and draw them into the on-screen tiles
				BufferVisualizationData.GetOverviewMaterials().Add(Material);
				
				SelectedMaterialNames = Right;
			}
		}

		// Copy current material list into settings material list
		for (TArray<UMaterial*>::TConstIterator It = BufferVisualizationData.GetOverviewMaterials().CreateConstIterator(); It; ++It)
		{
			FinalPostProcessSettings.BufferVisualizationOverviewMaterials.Add(*It);
		}
	}
}
bool FDefaultValueHelper::Trim(int32& Pos, const FString& Source)
{
	for(; Pos < Source.Len() && IsWhitespace(Source[Pos]); ++Pos) { }
	return (Pos < Source.Len());
}
bool UGatherTextFromSourceCommandlet::ParseSourceText(const FString& Text, const TArray<UGatherTextFromSourceCommandlet::FParsableDescriptor*>& Parsables, FSourceFileParseContext& ParseCtxt)
{
	// Create array of ints, one for each parsable we're looking for.
	TArray<int32> ParsableMatchCounters;
	ParsableMatchCounters.AddZeroed(Parsables.Num());

	// Cache array of tokens
	TArray<FString> ParsableTokens;
	for (int32 ParIdx=0; ParIdx<Parsables.Num(); ParIdx++)
	{
		ParsableTokens.Add(Parsables[ParIdx]->GetToken());
	}

	// Split the file into lines of 
	TArray<FString> TextLines;
	Text.ParseIntoArray(&TextLines, LINE_TERMINATOR, false);

	// Move through the text lines looking for the tokens that denote the items in the Parsables list
	for (int32 LineIdx = 0; LineIdx < TextLines.Num(); LineIdx++)
	{
		const FString& Line = TextLines[LineIdx].TrimTrailing();
		if( Line.IsEmpty() )
			continue;

		// Use these pending vars to defer parsing a token hit until longer tokens can't hit too
		int32 PendingParseIdx = -1;
		const TCHAR* ParsePoint = NULL;
		ParsableMatchCounters.Empty(Parsables.Num());
		ParsableMatchCounters.AddZeroed(Parsables.Num());
		ParseCtxt.LineNumber = LineIdx + 1;
		ParseCtxt.LineText = Line;
		ParseCtxt.EndParsingCurrentLine = false;

		const TCHAR* Cursor = *Line;
		bool EndOfLine = false;
		while (!EndOfLine && !ParseCtxt.EndParsingCurrentLine)
		{
			// Check if we're starting comments. Begins *at* "//" or "/*".
			if(!ParseCtxt.WithinLineComment && !ParseCtxt.WithinBlockComment)
			{
				const TCHAR* ForwardCursor = Cursor;
				if(*ForwardCursor == TEXT('/'))
				{
					++ForwardCursor;
					switch(*ForwardCursor)
					{
					case TEXT('/'):
						{
							ParseCtxt.WithinLineComment = true;
						}
						break;
					case TEXT('*'):
						{
							ParseCtxt.WithinBlockComment = true;
						}
						break;
					}
				}
			}

			// Check if we're ending comments. Ends *after* "*/".
			if(ParseCtxt.WithinBlockComment)
			{
				const TCHAR* ReverseCursor = Cursor;
				if(*ReverseCursor == TEXT('/') && ReverseCursor >= *Line)
				{
					--ReverseCursor;
					if(*ReverseCursor == TEXT('*')  && ReverseCursor >= *Line)
					{
						ParseCtxt.WithinBlockComment = false;
					}
				}
			}

			for (int32 ParIdx=0; ParIdx<Parsables.Num(); ParIdx++)
			{
				FString& Token = ParsableTokens[ParIdx];

				if (*Cursor == Token[ParsableMatchCounters[ParIdx]])
				{
					// Char at cursor matches the next char in the parsable's identifying token
					if (Token.Len() == ++(ParsableMatchCounters[ParIdx]))
					{
						// don't immediately parse - this parsable has seen its entire token but a longer one could be about to hit too
						const TCHAR* TokenStart = Cursor + 1 - Token.Len();
						if (0 > PendingParseIdx || ParsePoint >= TokenStart)
						{
							PendingParseIdx = ParIdx;
							ParsePoint = TokenStart;
						}
					}
				}
				else
				{
					// Char at cursor doesn't match the next char in the parsable's identifying token
					// Reset the counter to start of the token
					ParsableMatchCounters[ParIdx] = 0;
				}
			}

			// Now check PendingParse and only run it if there are no better candidates
			if (0 <= PendingParseIdx)
			{
				bool MustDefer = false; // pending will be deferred if another parsable has a equal and greater number of matched chars
				if( !Parsables[PendingParseIdx]->OverridesLongerTokens() )
				{
					for (int32 ParIdx=0; ParIdx<Parsables.Num(); ParIdx++)
					{
						if (PendingParseIdx != ParIdx)
						{
							if (ParsableMatchCounters[ParIdx] >= ParsableTokens[PendingParseIdx].Len())
							{
								// a longer token is matching so defer
								MustDefer = true;
							}
						}
					}
				}

				if (!MustDefer)
				{
					// Do the parse now
					Parsables[PendingParseIdx]->TryParse(FString(ParsePoint), ParseCtxt);
					ParsableMatchCounters[PendingParseIdx] = 0;
					PendingParseIdx = -1;
					ParsePoint = NULL;
				}
			}

			EndOfLine = ('\0' == *(++Cursor)) ? true : false;
			if(EndOfLine)
			{
				ParseCtxt.WithinLineComment = false;
			}
		}
	}

	return true;
}
Exemplo n.º 28
0
bool FAutoReimportDirectoryConfig::ParseSourceDirectoryAndMountPoint(FString& SourceDirectory, FString& MountPoint, const FParseContext& InContext)
{
	SourceDirectory.ReplaceInline(TEXT("\\"), TEXT("/"));

	// Check if the source directory is actually a mount point
	if (!FPackageName::GetPackageMountPoint(SourceDirectory).IsNone())
	{
		MountPoint = SourceDirectory;
		SourceDirectory = FString();
	}

	if (!SourceDirectory.IsEmpty() && !MountPoint.IsEmpty())
	{
		// We have both a source directory and a mount point. Verify that the source dir exists, and that the mount point is valid.
		if (!IFileManager::Get().DirectoryExists(*SourceDirectory))
		{
			UE_CLOG(InContext.bEnableLogging, LogAutoReimportManager, Warning, TEXT("Unable to watch directory %s as it doesn't exist."), *SourceDirectory);
			return false;
		}

		if (FPackageName::GetPackageMountPoint(MountPoint).IsNone())
		{
			UE_CLOG(InContext.bEnableLogging, LogAutoReimportManager, Warning, TEXT("Unable to setup directory %s to map to %s, as it's not a valid mounted path. Continuing without mounted path (auto reimports will still work, but auto add won't)."), *SourceDirectory, *MountPoint);
		}
	}
	else if(!MountPoint.IsEmpty())
	{
		// We have just a mount point - validate it, and find its source directory
		if (FPackageName::GetPackageMountPoint(MountPoint).IsNone())
		{
			UE_CLOG(InContext.bEnableLogging, LogAutoReimportManager, Warning, TEXT("Unable to setup directory monitor for %s, as it's not a valid mounted path."), *MountPoint);
			return false;
		}

		SourceDirectory = FPackageName::LongPackageNameToFilename(MountPoint);
	}
	else if(!SourceDirectory.IsEmpty())
	{
		// We have just a source directory - verify whether it's a mounted path, and set up the mount point if so
		if (!IFileManager::Get().DirectoryExists(*SourceDirectory))
		{
			UE_CLOG(InContext.bEnableLogging, LogAutoReimportManager, Warning, TEXT("Unable to watch directory %s as it doesn't exist."), *SourceDirectory);
			return false;
		}

		// Set the mounted path if necessary
		auto* Pair = InContext.MountedPaths.FindByPredicate([&](const TPair<FString, FString>& InPair){
			return SourceDirectory.StartsWith(InPair.Key);
		});

		if (Pair)
		{
			MountPoint = Pair->Value / SourceDirectory.RightChop(Pair->Key.Len());
			MountPoint.ReplaceInline(TEXT("\\"), TEXT("/"));
		}
	}
	else
	{
		// Don't have any valid settings
		return false;
	}

	return true;
}
void UGatherTextFromSourceCommandlet::FCommandMacroDescriptor::TryParse(const FString& Text, FSourceFileParseContext& Context) const
{
	// Attempt to parse something of the format
	// UI_COMMAND(LocKey, DefaultLangString, DefaultLangTooltipString, <IgnoredParam>, <IgnoredParam>)

	if (!Context.ExcludedRegion && (Context.Filename.EndsWith(TEXT(".inl")) || (!Context.WithinBlockComment && !Context.WithinLineComment)) )
	{
		TArray<FString> Arguments;
		if (ParseArgsFromMacro(Text, Arguments, Context))
		{
			if (Arguments.Num() != 5)
			{
				UE_LOG(LogGatherTextFromSourceCommandlet, Warning, TEXT("Too many arguments in command %s macro in %s(%d):%s"), *GetToken(), *Context.Filename, Context.LineNumber, *MungeLogOutput(Context.LineText));
			}
			else
			{
				FString Identifier = Arguments[0].Trim();
				FString Namespace = TEXT("UICommands");
				FString SourceLocation = FString( Context.Filename + TEXT(" - line ") + FString::FromInt(Context.LineNumber) );
				FString SourceText = Arguments[1].Trim();

				if ( Identifier.IsEmpty() )
				{
					//The command doesn't have an identifier so we can't gather it
					UE_LOG(LogGatherTextFromSourceCommandlet, Warning, TEXT("UICOMMAND macro doesn't have unique identifier. %s"), *SourceLocation );
					return;
				}

				// parse DefaultLangString argument - this arg will be in quotes without TEXT macro
				bool HasQuotes;
				FString MacroDesc = FString::Printf(TEXT("\"FriendlyName\" argument in %s macro %s(%d):%s"), *GetToken(), *Context.Filename, Context.LineNumber, *Context.LineText);
				if ( PrepareArgument(SourceText, true, MacroDesc, HasQuotes) )
				{
					if ( HasQuotes && !Identifier.IsEmpty() && !SourceText.IsEmpty() )
					{
						// First create the command entry
						FContext CommandContext;
						CommandContext.Key = Identifier;
						CommandContext.SourceLocation = SourceLocation;

						Context.AddManifestText( GetToken(), Namespace, SourceText, CommandContext );

						// parse DefaultLangTooltipString argument - this arg will be in quotes without TEXT macro
						FString TooltipSourceText = Arguments[2].Trim();
						MacroDesc = FString::Printf(TEXT("\"InDescription\" argument in %s macro %s(%d):%s"), *GetToken(), *Context.Filename, Context.LineNumber, *Context.LineText);
						if (PrepareArgument(TooltipSourceText, true, MacroDesc, HasQuotes))
						{
							if (HasQuotes && !TooltipSourceText.IsEmpty())
							{
								// Create the tooltip entry
								FContext CommandTooltipContext;
								CommandTooltipContext.Key = Identifier + TEXT("_ToolTip");
								CommandTooltipContext.SourceLocation = SourceLocation;

								Context.AddManifestText( GetToken(), Namespace, TooltipSourceText, CommandTooltipContext );
							}
						}
					}
				}
			}
		}
	}
}
FPropertyAccess::Result SPropertyEditorAsset::GetValue( FObjectOrAssetData& OutValue ) const
{
	// Potentially accessing the value while garbage collecting or saving the package could trigger a crash.
	// so we fail to get the value when that is occurring.
	if ( GIsSavingPackage || IsGarbageCollecting() )
	{
		return FPropertyAccess::Fail;
	}

	FPropertyAccess::Result Result = FPropertyAccess::Fail;

	if( PropertyEditor.IsValid() && PropertyEditor->GetPropertyHandle()->IsValidHandle() )
	{
		UObject* Object = NULL;
		Result = PropertyEditor->GetPropertyHandle()->GetValue(Object);

		if (Object == NULL)
		{
			// Check to see if it's pointing to an unloaded object
			FString CurrentObjectPath;
			PropertyEditor->GetPropertyHandle()->GetValueAsFormattedString( CurrentObjectPath );

			if (CurrentObjectPath.Len() > 0 && CurrentObjectPath != TEXT("None"))
			{
				if( !CachedAssetData.IsValid() || CachedAssetData.ObjectPath.ToString() != CurrentObjectPath )
				{
					static FName AssetRegistryName("AssetRegistry");

					FAssetRegistryModule& AssetRegistryModule = FModuleManager::Get().LoadModuleChecked<FAssetRegistryModule>(AssetRegistryName);
					CachedAssetData = AssetRegistryModule.Get().GetAssetByObjectPath( *CurrentObjectPath );
				}

				Result = FPropertyAccess::Success;
				OutValue = FObjectOrAssetData( CachedAssetData );

				return Result;
			}
		}

#if !UE_BUILD_SHIPPING
		if (Object && !Object->IsValidLowLevel())
		{
			const UProperty* Property = PropertyEditor->GetProperty();
			UE_LOG(LogPropertyNode, Fatal, TEXT("Property \"%s\" (%s) contains invalid data."), *Property->GetName(), *Property->GetCPPType());
		}
#endif

		OutValue = FObjectOrAssetData( Object );
	}
	else
	{
		UObject* Object = NULL;
		if (PropertyHandle.IsValid())
		{
			Result = PropertyHandle->GetValue(Object);
		}

		if (Object != NULL)
		{
#if !UE_BUILD_SHIPPING
			if (!Object->IsValidLowLevel())
			{
				const UProperty* Property = PropertyEditor->GetProperty();
				UE_LOG(LogPropertyNode, Fatal, TEXT("Property \"%s\" (%s) contains invalid data."), *Property->GetName(), *Property->GetCPPType());
			}
#endif

			OutValue = FObjectOrAssetData(Object);
		}
		else
		{
			const FString CurrentObjectPath = ObjectPath.Get();
			Result = FPropertyAccess::Success;

			if (CurrentObjectPath != TEXT("None") && (!CachedAssetData.IsValid() || CachedAssetData.ObjectPath.ToString() != CurrentObjectPath))
			{
				static FName AssetRegistryName("AssetRegistry");

				FAssetRegistryModule& AssetRegistryModule = FModuleManager::Get().LoadModuleChecked<FAssetRegistryModule>(AssetRegistryName);
				CachedAssetData = AssetRegistryModule.Get().GetAssetByObjectPath(*CurrentObjectPath);

				if (PropertyHandle.IsValid())
				{
					// No property editor was specified so check if multiple property values are associated with the property handle
					TArray<FString> ObjectValues;
					PropertyHandle->GetPerObjectValues(ObjectValues);

					if (ObjectValues.Num() > 1)
					{
						for (int32 ObjectIndex = 1; ObjectIndex < ObjectValues.Num() && Result == FPropertyAccess::Success; ++ObjectIndex)
						{
							if (ObjectValues[ObjectIndex] != ObjectValues[0])
							{
								Result = FPropertyAccess::MultipleValues;
							}
						}
					}
				}
			}
			else if (CurrentObjectPath == TEXT("None"))
			{
				CachedAssetData = FAssetData();
			}

			OutValue = FObjectOrAssetData(CachedAssetData);
		}
	}

	return Result;
}