Ejemplo n.º 1
0
static void main_AttemptConnection( )
{
	char	szBuffer[128];

	// Update the GUI.
	time( &g_tLastSentCommand );
	main_SetState( STATE_CONNECTING );
	sprintf( szBuffer, "Connecting to %s...", NETWORK_AddressToString( g_ServerAddress ));
	main_UpdateStatusbar( szBuffer );
	main_UpdateTrayTooltip( szBuffer );
	GetDlgItemText( g_hDlg, IDC_SERVERIP, szBuffer, 128 );

	// Save this server to our config file.
	g_Config.SetSection( "Settings", true );
	g_Config.SetValueForKey( "LastServer", szBuffer );
	g_Config.WriteConfigFile( );

	// Start listening for packets.
	if ( g_hThread == NULL )
	{
		g_hThread = CreateThread( NULL, 0, main_Loop, 0, 0, 0 );
		NETWORK_InitBuffer( &g_MessageBuffer, 8192, BUFFERTYPE_WRITE );
	}

	NETWORK_ClearBuffer( &g_MessageBuffer );
	NETWORK_WriteByte( &g_MessageBuffer.ByteStream, CLRC_BEGINCONNECTION );
	NETWORK_WriteByte( &g_MessageBuffer.ByteStream, PROTOCOL_VERSION );
	NETWORK_LaunchPacket( &g_MessageBuffer, g_ServerAddress );	
}
Ejemplo n.º 2
0
bool FGenericPlatformMisc::GetStoredValue(const FString& InStoreId, const FString& InSectionName, const FString& InKeyName, FString& OutValue)
{
	check(!InStoreId.IsEmpty());
	check(!InSectionName.IsEmpty());
	check(!InKeyName.IsEmpty());

	// This assumes that FPlatformProcess::ApplicationSettingsDir() returns a user-specific directory; it doesn't on Windows, but Windows overrides this behavior to use the registry
	const FString ConfigPath = FString(FPlatformProcess::ApplicationSettingsDir()) / InStoreId / FString(TEXT("KeyValueStore.ini"));
		
	FConfigFile ConfigFile;
	ConfigFile.Read(ConfigPath);

	const FConfigSection* const Section = ConfigFile.Find(InSectionName);
	if(Section)
	{
		const FString* const KeyValue = Section->Find(*InKeyName);
		if(KeyValue)
		{
			OutValue = *KeyValue;
			return true;
		}
	}

	return false;
}
Ejemplo n.º 3
0
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )
{
	g_hInst = hInstance;
	g_Config.ChangePathName( "settings.ini" );
	g_Config.LoadConfigFile( NULL, NULL );

	// Read the user's favorites.
	if ( g_Config.SetSection("Favorites"))
	{			
		const char *key;
		const char *value;

		while ( g_Config.NextInSection( key, value ))
		{
			FAVORITE_s fav;

			strncpy( fav.szName, key, 128 );
			fav.szName[128] = 0;
			strncpy( fav.szAddress, value, strchr( value, '/' ) - value );
			fav.szAddress[strchr( value, '/' ) - value] = 0;
			strncpy( fav.szPassword, strchr( value, '/' ) + 1, 128 );
			fav.szPassword[128] = 0;

			g_Favorites.push_back( fav );			
		}
	}

	NETWORK_Construct( 99999 );
	main_SetState( STATE_WAITING );
	DialogBox( g_hInst, MAKEINTRESOURCE( IDD_CONNECTDIALOG ), NULL, main_ConnectDialogCallback );
}
bool UOnlineHotfixManager::HotfixPakIniFile(const FString& FileName)
{
	FConfigFile* ConfigFile = GetConfigFile(FileName);
	ConfigFile->Combine(FileName);
	UE_LOG(LogHotfixManager, Log, TEXT("Hotfix merged INI (%s) found in a PAK file"), *FileName);

	FName IniFileName(*FileName, FNAME_Find);
	int32 NumObjectsReloaded = 0;
	const double StartTime = FPlatformTime::Seconds();
	// Now that we have a list of classes to update, we can iterate objects and
	// reload if they match the INI file that was changed
	for (FObjectIterator It; It; ++It)
	{
		UClass* Class = It->GetClass();
		if (Class->HasAnyClassFlags(CLASS_Config) &&
			Class->ClassConfigName == IniFileName)
		{
			// Force a reload of the config vars
			It->ReloadConfig();
			NumObjectsReloaded++;
		}
	}
	UE_LOG(LogHotfixManager, Log, TEXT("Updating config from %s took %f seconds reloading %d objects"),
		*FileName, FPlatformTime::Seconds() - StartTime, NumObjectsReloaded);
	return true;
}
Ejemplo n.º 5
0
bool CanCookForPlatformInThisProcess( const FString& PlatformName )
{
	////////////////////////////////////////
	// hack remove this hack when we properly support changing the mobileHDR setting 
	// check if our mobile hdr setting in memory is different from the one which is saved in the config file
	
	
	FConfigFile PlatformEngineIni;
	GConfig->LoadLocalIniFile(PlatformEngineIni, TEXT("Engine"), true, *PlatformName );

	FString IniValueString;
	bool ConfigSetting = false;
	if ( PlatformEngineIni.GetString( TEXT("/Script/Engine.RendererSettings"), TEXT("r.MobileHDR"), IniValueString ) == false )
	{
		// must always match the RSetting setting because we don't have a config setting
		return true; 
	}
	ConfigSetting = IniValueString.ToBool();

	// this was stolen from void IsMobileHDR()
	static auto* MobileHDRCvar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.MobileHDR"));
	const bool CurrentRSetting = MobileHDRCvar->GetValueOnAnyThread() == 1;

	if ( CurrentRSetting != ConfigSetting )
	{
		UE_LOG(LogUnrealEdEngine, Warning, TEXT("Unable to use cook in editor because r.MobileHDR from Engine ini doesn't match console value r.MobileHDR"));
		return false;
	}
	////////////////////////////////////////
	return true;
}
Ejemplo n.º 6
0
void FConfigManifest::MigrateConfigSection(FConfigFile& ConfigFile, const TCHAR* OldSectionName, const TCHAR* NewSectionName)
{
	const FConfigSection* OldSection = ConfigFile.Find(OldSectionName);
	if (OldSection)
	{
		FConfigSection* NewSection = ConfigFile.Find(NewSectionName);
		if (NewSection)
		{
			for (auto& Setting : *OldSection)
			{
				if (!NewSection->Contains(Setting.Key))
				{
					NewSection->Add(Setting.Key, Setting.Value);
				}
			}
		}
		else
		{
			// Add the new section and remove the old
			FConfigSection SectionCopy = *OldSection;
			ConfigFile.Add(NewSectionName, MoveTemp(SectionCopy));
			ConfigFile.Remove(OldSectionName);
		}
		ConfigFile.Dirty = true;
	}
}
Ejemplo n.º 7
0
/** Combine 2 config files together, putting the result in a third */
void CombineConfig(const TCHAR* Base, const TCHAR* Other, const TCHAR* Output)
{
	FConfigFile Config;

	Config.Read(Base);
	Config.Combine(Other);

	Config.Write(Output, false /*bDoRemoteWrite*/);
}
Ejemplo n.º 8
0
void FDesktopPlatformLinux::EnumerateEngineInstallations(TMap<FString, FString> &OutInstallations)
{
	EnumerateLauncherEngineInstallations(OutInstallations);

	FString UProjectPath = FString(FPlatformProcess::ApplicationSettingsDir()) / "Unreal.uproject";
	FArchive* File = IFileManager::Get().CreateFileWriter(*UProjectPath, FILEWRITE_EvenIfReadOnly);
	if (File)
	{
		File->Close();
		delete File;
	}
	else
	{
	    SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Unable to write to Settings Directory", TCHAR_TO_UTF8(*UProjectPath), NULL);
	}

	FConfigFile ConfigFile;
	FString ConfigPath = FString(FPlatformProcess::ApplicationSettingsDir()) / FString(TEXT("UnrealEngine")) / FString(TEXT("Install.ini"));
	ConfigFile.Read(ConfigPath);

	FConfigSection &Section = ConfigFile.FindOrAdd(TEXT("Installations"));

	// @todo: currently we can enumerate only this installation
	FString EngineDir = FPaths::EngineDir();

	FString EngineId;
	const FName* Key = Section.FindKey(EngineDir);
	if (Key)
	{
		EngineId = Key->ToString();
	}
	else
	{
		if (!OutInstallations.FindKey(EngineDir))
		{
			EngineId = FGuid::NewGuid().ToString(EGuidFormats::DigitsWithHyphens);
			Section.AddUnique(*EngineId, EngineDir);
			ConfigFile.Dirty = true;
		}
	}
	if (!EngineId.IsEmpty() && !OutInstallations.Find(EngineId))
	{
		OutInstallations.Add(EngineId, EngineDir);
	}

	ConfigFile.Write(ConfigPath);

	IFileManager::Get().Delete(*UProjectPath);
}
void FCrashReportClientConfig::SetProjectConfigOverrides(const FConfigFile& InConfigFile)
{
    const FConfigSection* Section = InConfigFile.Find(FGenericCrashContext::ConfigSectionName);

    // Default to false (show the option) when config is missing.
    bHideLogFilesOption = false;

    // Default to true (Allow the user to close without sending) when config is missing.
    bIsAllowedToCloseWithoutSending = true;

    // Try to read values from override config file
    if (Section != nullptr)
    {
        const FConfigValue* HideLogFilesOptionValue = Section->Find(TEXT("bHideLogFilesOption"));
        if (HideLogFilesOptionValue != nullptr)
        {
            bHideLogFilesOption = FCString::ToBool(*HideLogFilesOptionValue->GetValue());
        }

        const FConfigValue* IsAllowedToCloseWithoutSendingValue = Section->Find(TEXT("bIsAllowedToCloseWithoutSending"));
        if (IsAllowedToCloseWithoutSendingValue != nullptr)
        {
            bIsAllowedToCloseWithoutSending = FCString::ToBool(*IsAllowedToCloseWithoutSendingValue->GetValue());
        }
    }
}
Ejemplo n.º 10
0
void FConfigManifest::MigrateEditorUserSettings()
{
	const FString EditorUserSettingsFilename = ProjectSpecificIniPath(TEXT("EditorUserSettings.ini"));
	if (!FPaths::FileExists(EditorUserSettingsFilename))
	{
		return;
	}

	// Handle upgrading editor user settings to the new path
	FConfigFile OldIni;
	OldIni.NoSave = true;
	OldIni.Read(EditorUserSettingsFilename);
	
	if (OldIni.Num() != 0)
	{
		// Rename the config section
		MigrateConfigSection(OldIni, TEXT("/Script/UnrealEd.EditorUserSettings"), TEXT("/Script/UnrealEd.EditorPerProjectUserSettings"));

		const FString EditorPerProjectUserSettingsFilename = ProjectSpecificIniPath(TEXT("EditorPerProjectUserSettings.ini"));

		FConfigFile NewIni;
		NewIni.Read(EditorPerProjectUserSettingsFilename);
		NewIni.AddMissingProperties(OldIni);
		if (!NewIni.Write(EditorPerProjectUserSettingsFilename, false))
		{
			return;
		}
	}

	IFileManager::Get().Move(*(EditorUserSettingsFilename + TEXT(".bak")), *EditorUserSettingsFilename);
}
Ejemplo n.º 11
0
bool FDesktopPlatformLinux::RegisterEngineInstallation(const FString &RootDir, FString &OutIdentifier)
{
	bool bRes = false;
	if (IsValidRootDirectory(RootDir))
	{
		FConfigFile ConfigFile;
		FString ConfigPath = FString(FPlatformProcess::ApplicationSettingsDir()) / FString(TEXT("UnrealEngine")) / FString(TEXT("Install.ini"));
		ConfigFile.Read(ConfigPath);

		FConfigSection &Section = ConfigFile.FindOrAdd(TEXT("Installations"));
		OutIdentifier = FGuid::NewGuid().ToString(EGuidFormats::DigitsWithHyphens);
		Section.AddUnique(*OutIdentifier, RootDir);

		ConfigFile.Dirty = true;
		ConfigFile.Write(ConfigPath);
	}
	return bRes;
}
Ejemplo n.º 12
0
bool FGenericPlatformMisc::SetStoredValue(const FString& InStoreId, const FString& InSectionName, const FString& InKeyName, const FString& InValue)
{
	check(!InStoreId.IsEmpty());
	check(!InSectionName.IsEmpty());
	check(!InKeyName.IsEmpty());

	// This assumes that FPlatformProcess::ApplicationSettingsDir() returns a user-specific directory; it doesn't on Windows, but Windows overrides this behavior to use the registry
	const FString ConfigPath = FString(FPlatformProcess::ApplicationSettingsDir()) / InStoreId / FString(TEXT("KeyValueStore.ini"));
		
	FConfigFile ConfigFile;
	ConfigFile.Read(ConfigPath);

	FConfigSection& Section = ConfigFile.FindOrAdd(InSectionName);

	FString& KeyValue = Section.FindOrAdd(*InKeyName);
	KeyValue = InValue;

	ConfigFile.Dirty = true;
	return ConfigFile.Write(ConfigPath);
}
Ejemplo n.º 13
0
void FConfigManifest::UpgradeFromPreviousVersions()
{
	// First off, load the manifest config if it exists
	FConfigFile Manifest;

	const FString ManifestFilename = ProjectAgnosticIniPath(TEXT("Manifest.ini"));

	if (!FPaths::FileExists(ManifestFilename) && IsDirectoryEmpty(*FPaths::GetPath(ManifestFilename)))
	{
		// Copy files from previous versions of the engine, if possible
		MigratePreviousEngineInis();
	}

	const EConfigManifestVersion LatestVersion = (EConfigManifestVersion)((int32)EConfigManifestVersion::NumOfVersions - 1);
	EConfigManifestVersion CurrentVersion = EConfigManifestVersion::Initial;

	if (FPaths::FileExists(ManifestFilename))
	{
		// Load the manifest from the file
		Manifest.Read(*ManifestFilename);

		int64 Version = 0;
		if (Manifest.GetInt64(TEXT("Manifest"), TEXT("Version"), Version) && Version < (int64)EConfigManifestVersion::NumOfVersions)
		{
			CurrentVersion = (EConfigManifestVersion)Version;
		}
	}

	if (CurrentVersion == LatestVersion)
	{
		return;
	}

	CurrentVersion = UpgradeFromVersion(CurrentVersion);

	// Set the version in the manifest, and write it out
	Manifest.SetInt64(TEXT("Manifest"), TEXT("Version"), (int64)CurrentVersion);
	Manifest.Write(ManifestFilename);
}
Ejemplo n.º 14
0
EConfigManifestVersion FConfigManifest::UpgradeFromVersion(EConfigManifestVersion FromVersion)
{
	// Perform upgrades sequentially...

	if (FromVersion < EConfigManifestVersion::RenameEditorAgnosticSettings)
	{
		// First off, rename the Editor game agnostic ini config to EditorSettings
		auto Path = ProjectAgnosticIniPath(TEXT("EditorSettings.ini"));
		RenameIni(*ProjectAgnosticIniPath(TEXT("EditorGameAgnostic.ini")), *Path);

		FConfigFile EditorSettings;
		EditorSettings.Read(Path);
		MigrateConfigSection(EditorSettings, TEXT("/Script/UnrealEd.EditorGameAgnosticSettings"), TEXT("/Script/UnrealEd.EditorSettings"));
		EditorSettings.Write(Path, false /*bDoRemoteWrite*/);

		FromVersion = EConfigManifestVersion::RenameEditorAgnosticSettings;
	}

	if (FromVersion < EConfigManifestVersion::MigrateProjectSpecificInisToAgnostic)
	{
		if (!FApp::HasGameName())
		{
			// We can't upgrade game settings if there is no game.
			return FromVersion;
		}

		// The initial versioning made the following changes:

		// 1. Move EditorLayout.ini from Game/Saved/Config to Engine/Saved/Config, thus making it project-agnostic
		// 2. Move EditorKeyBindings.ini from Game/Saved/Config to Engine/Saved/Config, thus making it project-agnostic

		MigrateToAgnosticIni(TEXT("EditorLayout.ini"));
		MigrateToAgnosticIni(TEXT("EditorKeyBindings.ini"));
		
		FromVersion = EConfigManifestVersion::MigrateProjectSpecificInisToAgnostic;
	}

	return FromVersion;
}
bool FPluginManager::ConfigureEnabledPlugins()
{
	if(!bHaveConfiguredEnabledPlugins)
	{
		// Don't need to run this again
		bHaveConfiguredEnabledPlugins = true;

		// If a current project is set, check that we know about any plugin that's explicitly enabled
		const FProjectDescriptor *Project = IProjectManager::Get().GetCurrentProject();
		const bool bHasProjectFile = Project != nullptr;

		// Get all the enabled plugin names
		TArray< FString > EnabledPluginNames;
#if IS_PROGRAM
		// Programs can also define the list of enabled plugins in ini
		GConfig->GetArray(TEXT("Plugins"), TEXT("ProgramEnabledPlugins"), EnabledPluginNames, GEngineIni);
#endif
#if !IS_PROGRAM || HACK_HEADER_GENERATOR
		if (!FParse::Param(FCommandLine::Get(), TEXT("NoEnginePlugins")))
		{
			FProjectManager::Get().GetEnabledPlugins(EnabledPluginNames);
		}
#endif

		// Build a set from the array
		TSet< FString > AllEnabledPlugins;
		AllEnabledPlugins.Append(MoveTemp(EnabledPluginNames));

		// Enable all the plugins by name
		for (const TSharedRef< FPlugin > Plugin : AllPlugins)
		{
			if (AllEnabledPlugins.Contains(Plugin->Name))
			{
				Plugin->bEnabled = (!IS_PROGRAM || !bHasProjectFile) || IsPluginSupportedByCurrentTarget(Plugin);
				if (!Plugin->bEnabled)
				{
					AllEnabledPlugins.Remove(Plugin->Name);
				}
			}
		}

		if (bHasProjectFile)
		{
			// Take a copy of the Project's plugins as we may remove some
			TArray<FPluginReferenceDescriptor> PluginsCopy = Project->Plugins;
			for(const FPluginReferenceDescriptor& Plugin: PluginsCopy)
			{
				if ((Plugin.bEnabled && !FindPluginInstance(Plugin.Name).IsValid()) &&
					 (!IS_PROGRAM || AllEnabledPlugins.Contains(Plugin.Name))) // skip if this is a program and the plugin is not enabled
				{
					FText Caption(LOCTEXT("PluginMissingCaption", "Plugin missing"));
					if(Plugin.MarketplaceURL.Len() > 0)
					{
						if(FMessageDialog::Open(EAppMsgType::YesNo, FText::Format(LOCTEXT("PluginMissingError", "This project requires the {0} plugin.\n\nWould you like to download it from the the Marketplace?"), FText::FromString(Plugin.Name)), &Caption) == EAppReturnType::Yes)
						{
							FString Error;
							FPlatformProcess::LaunchURL(*Plugin.MarketplaceURL, nullptr, &Error);
							if(Error.Len() > 0) FMessageDialog::Open(EAppMsgType::Ok, FText::FromString(Error));
							return false;
						}
					}
					else
					{
						FString Description = (Plugin.Description.Len() > 0) ? FString::Printf(TEXT("\n\n%s"), *Plugin.Description) : FString();
						FMessageDialog::Open(EAppMsgType::Ok, FText::Format(LOCTEXT("PluginRequiredError", "This project requires the {0} plugin. {1}"), FText::FromString(Plugin.Name), FText::FromString(Description)), &Caption);
						
						if (FMessageDialog::Open(EAppMsgType::YesNo, FText::Format(LOCTEXT("PluginMissingDisable", "Would you like to disable {0}? You will no longer be able to open any assets created using it."), FText::FromString(Plugin.Name)), &Caption) == EAppReturnType::No)
						{
							return false;
						}

						FText FailReason;
						if (!IProjectManager::Get().SetPluginEnabled(*Plugin.Name, false, FailReason))
						{
							FMessageDialog::Open(EAppMsgType::Ok, FailReason);
						}
					}
				}
			}
		}

		// If we made it here, we have all the required plugins
		bHaveAllRequiredPlugins = true;

		for(const TSharedRef<FPlugin>& Plugin: AllPlugins)
		{
			if (Plugin->bEnabled)
			{
				// Add the plugin binaries directory
				const FString PluginBinariesPath = FPaths::Combine(*FPaths::GetPath(Plugin->FileName), TEXT("Binaries"), FPlatformProcess::GetBinariesSubdirectory());
				FModuleManager::Get().AddBinariesDirectory(*PluginBinariesPath, Plugin->LoadedFrom == EPluginLoadedFrom::GameProject);

#if !IS_MONOLITHIC
				// Only check this when in a non-monolithic build where modules could be in separate binaries
				if (Project != NULL && Project->Modules.Num() == 0)
				{
					// Content only project - check whether any plugins are incompatible and offer to disable instead of trying to build them later
					TArray<FString> IncompatibleFiles;
					if (!FModuleDescriptor::CheckModuleCompatibility(Plugin->Descriptor.Modules, Plugin->LoadedFrom == EPluginLoadedFrom::GameProject, IncompatibleFiles))
					{
						// Ask whether to disable plugin if incompatible
						FText Caption(LOCTEXT("IncompatiblePluginCaption", "Plugin missing or incompatible"));
						if (FMessageDialog::Open(EAppMsgType::YesNo, FText::Format(LOCTEXT("IncompatiblePluginText", "Missing or incompatible modules in {0} plugin - would you like to disable it? You will no longer be able to open any assets created using it."), FText::FromString(Plugin->Name)), &Caption) == EAppReturnType::No)
						{
							return false;
						}

						FText FailReason;
						if (!IProjectManager::Get().SetPluginEnabled(*Plugin->Name, false, FailReason))
						{
							FMessageDialog::Open(EAppMsgType::Ok, FailReason);
						}
					}
				}
#endif //!IS_MONOLITHIC

			// Build the list of content folders
				if (Plugin->Descriptor.bCanContainContent)
				{
					if (auto EngineConfigFile = GConfig->Find(GEngineIni, false))
					{
						if (auto CoreSystemSection = EngineConfigFile->Find(TEXT("Core.System")))
						{
							CoreSystemSection->AddUnique("Paths", Plugin->GetContentDir());
						}
					}
				}

				// Load Default<PluginName>.ini config file if it exists
				FString PluginConfigDir = FPaths::GetPath(Plugin->FileName) / TEXT("Config/");
				FConfigFile PluginConfig;
				FConfigCacheIni::LoadExternalIniFile(PluginConfig, *Plugin->Name, *FPaths::EngineConfigDir(), *PluginConfigDir, true);
				if (PluginConfig.Num() > 0)
				{
					FString PlaformName = FPlatformProperties::PlatformName();
					FString PluginConfigFilename = FString::Printf(TEXT("%s%s/%s.ini"), *FPaths::GeneratedConfigDir(), *PlaformName, *Plugin->Name);
					FConfigFile& NewConfigFile = GConfig->Add(PluginConfigFilename, FConfigFile());
					NewConfigFile.AddMissingProperties(PluginConfig);
					NewConfigFile.Write(PluginConfigFilename);
				}
			}
		}
		
		// Mount all the plugin content folders and pak files
		TArray<FString>	FoundPaks;
		FPakFileSearchVisitor PakVisitor(FoundPaks);
		IPlatformFile& PlatformFile = FPlatformFileManager::Get().GetPlatformFile();
		for(TSharedRef<IPlugin> Plugin: GetEnabledPlugins())
		{
			if (Plugin->CanContainContent() && ensure(RegisterMountPointDelegate.IsBound()))
			{
				FString ContentDir = Plugin->GetContentDir();
				RegisterMountPointDelegate.Execute(Plugin->GetMountedAssetPath(), ContentDir);

				// Pak files are loaded from <PluginName>/Content/Paks/<PlatformName>
				if (FPlatformProperties::RequiresCookedData())
				{
					FoundPaks.Reset();
					PlatformFile.IterateDirectoryRecursively(*(ContentDir / TEXT("Paks") / FPlatformProperties::PlatformName()), PakVisitor);
					for (const auto& PakPath : FoundPaks)
					{
						if (FCoreDelegates::OnMountPak.IsBound())
						{
							FCoreDelegates::OnMountPak.Execute(PakPath, 0);
						}
					}
				}
			}
		}
	}
	return bHaveAllRequiredPlugins;
}
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;
}
Ejemplo n.º 17
0
void FTextureLODSettings::ReadEntry( int32 GroupId, const TCHAR* GroupName, const FConfigFile& IniFile, const TCHAR* IniSection )
{
	// Look for string in filename/ section.
	FString Entry;
	if (IniFile.GetString(IniSection, GroupName, Entry))
	{
		// Trim whitespace at the beginning.
		Entry = Entry.Trim();
		// Remove brackets.
		Entry = Entry.Replace( TEXT("("), TEXT("") );
		Entry = Entry.Replace( TEXT(")"), TEXT("") );
		
		// Parse minimum LOD mip count.
		int32	MinLODSize = 0;
		if( FParse::Value( *Entry, TEXT("MinLODSize="), MinLODSize ) )
		{
			TextureLODGroups[GroupId].MinLODMipCount = FMath::CeilLogTwo( MinLODSize );
		}

		// Parse maximum LOD mip count.
		int32 MaxLODSize = 0;
		if( FParse::Value( *Entry, TEXT("MaxLODSize="), MaxLODSize ) )
		{
			TextureLODGroups[GroupId].MaxLODMipCount = FMath::CeilLogTwo( MaxLODSize );
		}

		// Parse LOD bias.
		int32 LODBias = 0;
		if( FParse::Value( *Entry, TEXT("LODBias="), LODBias ) )
		{
			TextureLODGroups[GroupId].LODBias = LODBias;
		}

		// Parse min/map/mip filter names.
		FName MinMagFilter = NAME_Aniso;
		FParse::Value( *Entry, TEXT("MinMagFilter="), MinMagFilter );
		FName MipFilter = NAME_Point;
		FParse::Value( *Entry, TEXT("MipFilter="), MipFilter );

		{
			FString MipGenSettings;
			FParse::Value( *Entry, TEXT("MipGenSettings="), MipGenSettings );
			TextureLODGroups[GroupId].MipGenSettings = UTexture::GetMipGenSettingsFromString(*MipGenSettings, true);
		}

		// Convert into single filter enum. The code is layed out such that invalid input will 
		// map to the default state of highest quality filtering.

		// Linear filtering
		if( MinMagFilter == NAME_Linear )
		{
			if( MipFilter == NAME_Point )
			{
				TextureLODGroups[GroupId].Filter = SF_Bilinear;
			}
			else
			{
				TextureLODGroups[GroupId].Filter = SF_Trilinear;
			}
		}
		// Point. Don't even care about mip filter.
		else if( MinMagFilter == NAME_Point )
		{
			TextureLODGroups[GroupId].Filter = SF_Point;
		}
		// Aniso or unknown.
		else
		{
			if( MipFilter == NAME_Point )
			{
				TextureLODGroups[GroupId].Filter = SF_AnisotropicPoint;
			}
			else
			{
				TextureLODGroups[GroupId].Filter = SF_AnisotropicLinear;
			}
		}

		// Parse NumStreamedMips
		int32 NumStreamedMips = -1;
		if( FParse::Value( *Entry, TEXT("NumStreamedMips="), NumStreamedMips ) )
		{
			TextureLODGroups[GroupId].NumStreamedMips = NumStreamedMips;
		}
	}
}
Ejemplo n.º 18
0
BOOL CALLBACK main_ConnectDialogCallback( HWND hDlg, UINT Message, WPARAM wParam, LPARAM lParam )
{
	char	szBuffer[128];

	switch ( Message )
	{
	case WM_CTLCOLORSTATIC:

		switch ( GetDlgCtrlID( (HWND) lParam ))
		{
		// Paint these two labels white.
		case IDC_INTROTEXT:
		case IDC_DESCTEXT:

			return (LRESULT) g_hWhiteBrush;
		// Ignore everything else.
		default:

			return NULL;
		}
		break;
	case WM_PAINT:
		{
			// Paint the top of the form white.
			PAINTSTRUCT Ps;
			RECT r;
			r.left = 0;
			r.top = 3;
			r.bottom = 55;
			r.right = 400;
			main_PaintRectangle( BeginPaint(hDlg, &Ps), &r, RGB(255, 255, 255));
		}
		break;
	case WM_INITDIALOG:

		{
			g_hDlg = hDlg;

			// Load the icon.
			SendMessage( hDlg, WM_SETICON, (WPARAM)ICON_SMALL, (LPARAM) (HICON) LoadImage( g_hInst,	MAKEINTRESOURCE( AAA_MAIN_ICON ), IMAGE_ICON, 16, 16, LR_SHARED ));
			SendMessage( hDlg, WM_SETICON, (WPARAM)ICON_BIG, (LPARAM)LoadIcon( g_hInst, MAKEINTRESOURCE( AAA_MAIN_ICON )));

			//==============================
			// Create the notification icon.
			//==============================

			ZeroMemory( &g_NotifyIconData, sizeof( g_NotifyIconData ));
			g_NotifyIconData.cbSize = sizeof( g_NotifyIconData );
			g_NotifyIconData.hWnd = hDlg;
			g_NotifyIconData.uID = 0;
			g_NotifyIconData.uFlags = NIF_ICON|NIF_MESSAGE|NIF_TIP;
			g_NotifyIconData.uCallbackMessage = UWM_TRAY_TRAYID;
			g_NotifyIconData.hIcon =  (HICON) LoadImage( g_hInst,	MAKEINTRESOURCE( AAA_MAIN_ICON ), IMAGE_ICON, 16, 16, LR_SHARED );			
			lstrcpy( g_NotifyIconData.szTip, g_szTooltip );
			Shell_NotifyIcon( NIM_ADD, &g_NotifyIconData );

			//==================
			// Create the menus.
			//==================
		
			// Create the favorites menu.
			g_hFavoritesMenu = CreatePopupMenu( );
			int iIndex = 1;
			for( std::vector<FAVORITE_s>::iterator i = g_Favorites.begin(); i != g_Favorites.end(); ++i )			
				AppendMenu( g_hFavoritesMenu, MF_STRING, IDR_DYNAMIC_MENU + iIndex++, (LPCTSTR)(&(*i->szName)) );

			// Create the tray menu.
			g_hTrayMenu = CreatePopupMenu( );
			AppendMenu( g_hTrayMenu, MF_STRING, IDR_TOGGLE, "Show/Hide" );
			AppendMenu( g_hTrayMenu, MF_STRING|MF_POPUP, (UINT)g_hFavoritesMenu, "Favorites");
			AppendMenu( g_hTrayMenu, MF_SEPARATOR, 0, 0 );
			AppendMenu( g_hTrayMenu, MF_STRING, IDR_EXIT, "Exit" );

			// Create the file menu.
			HMENU hFileMenu = CreatePopupMenu( );
			AppendMenu( hFileMenu, MF_STRING, IDR_EXIT, "Exit" );

			// Create the file menu.
			HMENU hHelpMenu = CreatePopupMenu( );
			AppendMenu( hHelpMenu, MF_STRING, IDR_ABOUT, "About..." );

			// Create the main menu.
			g_hMainMenu = CreateMenu( );
			AppendMenu( g_hMainMenu, MF_STRING|MF_POPUP, (UINT)hFileMenu, "File" );
			AppendMenu( g_hMainMenu, MF_STRING|MF_POPUP, (UINT)g_hFavoritesMenu, "Favorites");
			AppendMenu( g_hMainMenu, MF_STRING|MF_POPUP, (UINT)hHelpMenu, "Help");
			AppendMenu( g_hMainMenu, MF_SEPARATOR, 0, 0 );
			SetMenu( hDlg, g_hMainMenu );

			// Set up the status bar.
			g_hDlgStatusBar = CreateStatusWindow( WS_CHILD | WS_VISIBLE, (LPCTSTR)NULL, hDlg, IDC_STATIC );

			// Set up the top, white section.
			SendMessage( GetDlgItem( g_hDlg, IDC_INTROTEXT ), WM_SETFONT, (WPARAM) CreateFont( 13, 0, 0, 0, 600, 0, 0, 0, 0, 0, 0, 0, 0, "Tahoma" ), (LPARAM) 1 );
			LOGBRUSH LogBrush;
			LogBrush.lbStyle = BS_SOLID;
			LogBrush.lbColor = RGB( 255, 255, 255 );
			g_hWhiteBrush = CreateBrushIndirect( &LogBrush );

			// Load the server address that was used last time.
			if ( g_Config.HaveSections( ) && g_Config.SetSection( "Settings", true ) && g_Config.GetValueForKey( "LastServer" ) )
				SetDlgItemText( hDlg, IDC_SERVERIP, g_Config.GetValueForKey( "LastServer" ) );

		}
		break;
	case WM_COMMAND:

			// Selecting a favorite from the menu?
			if ( LOWORD( wParam ) > IDR_DYNAMIC_MENU && LOWORD( wParam ) <= IDR_DYNAMIC_MENU + g_Favorites.size( ))
			{
				main_ConnectToFavorite( LOWORD( wParam ) - IDR_DYNAMIC_MENU - 1 );
				return TRUE;
			}

			switch ( LOWORD( wParam ))
			{
			// This also occurs when esc is pressed.
			case IDCANCEL:

				if ( g_State == STATE_CONNECTING )
				{
					main_SetState( STATE_WAITING );
					main_EnableConnectionButtons( TRUE );
					main_UpdateStatusbar( "Cancelled." );
				}
				else
					main_Quit( );
				break;
			// The "connect" button.
			case IDOK:	

				// Disable all the inputs.
				main_EnableConnectionButtons( FALSE );

				// Read in what the user gave us.
				GetDlgItemText( hDlg, IDC_SERVERIP, szBuffer, 128 );
				NETWORK_StringToAddress( szBuffer,  &g_ServerAddress );
				GetDlgItemText( hDlg, IDC_PASSWORD, g_szPassword, 128 );

				// If the user didn't specify a port, use the default one.
				if ( g_ServerAddress.usPort == 0 )
					NETWORK_SetAddressPort( g_ServerAddress, DEFAULT_SERVER_PORT );

				// Do some quick error checking.
				if ( !strlen( szBuffer ))
					MessageBox( hDlg, "You should probably enter a server address.", "Input error.", MB_ICONEXCLAMATION );
				else if ( strlen( g_szPassword ) < 4 )
					MessageBox( hDlg, "RCON passwords must be at least four characters long.", "Input error.", MB_ICONEXCLAMATION );
				else
				{
					main_AttemptConnection( );
					break;
				}

				// Re-enable the form so the user can try again.
				main_EnableConnectionButtons( TRUE );
				break;
			case IDR_EXIT:
				
				main_Quit( );
				break;
			case IDR_ABOUT:

				DialogBox( g_hInst, MAKEINTRESOURCE( IDD_ABOUTDIALOG ), hDlg, main_AboutDialogCallback );
				break;
			}
			break;
	case WM_SYSCOMMAND:

		// Hide the window when minimized.
		if ( wParam == SC_MINIMIZE )
			ShowWindow( hDlg, SW_HIDE );
		else
			DefWindowProc( hDlg, Message, wParam, lParam );
		break;
	case WM_CLOSE:

		main_Quit( );
		break;
	case WM_DESTROY:

		Shell_NotifyIcon( NIM_DELETE, &g_NotifyIconData );
		PostQuitMessage( 0 );
		break;
	case UWM_TRAY_TRAYID:

		return main_TrayIconClicked( hDlg, lParam );		
	default:

		return FALSE;
	}

	return TRUE;
}
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;
}
int32 UGatherTextCommandlet::Main( const FString& Params )
{
	const TCHAR* Parms = *Params;
	TArray<FString> Tokens;
	TArray<FString> Switches;
	TMap<FString, FString> ParamVals;
	UCommandlet::ParseCommandLine(*Params, Tokens, Switches, ParamVals);
	
	// find the file corresponding to this object's loc file, loading it if necessary
	FString GatherTextConfigPath;
	const FString* ParamVal = ParamVals.Find(FString(TEXT("Config")));
	if (ParamVal)
	{
		GatherTextConfigPath = *ParamVal;
	}	
	else
	{
		UE_LOG(LogGatherTextCommandlet, Error, TEXT("-Config not specified.\n%s"), *UsageText);
		return -1;
	}

	if(FPaths::IsRelative(GatherTextConfigPath))
	{
		FString ProjectBasePath;
		if (!FPaths::GameDir().IsEmpty())
		{
			ProjectBasePath = FPaths::GameDir();
		}
		else
		{
			ProjectBasePath = FPaths::EngineDir();
		}
		GatherTextConfigPath = FPaths::Combine( *ProjectBasePath, *GatherTextConfigPath );
	}

	GConfig->LoadFile(*GatherTextConfigPath);

	FConfigFile* ConfigFile = GConfig->FindConfigFile(*GatherTextConfigPath);

	if( NULL == ConfigFile )
	{
		UE_LOG(LogGatherTextCommandlet, Error, TEXT("Loading Config File \"%s\" failed."), *GatherTextConfigPath);
		return -1; 
	}

	const bool bEnableSourceControl = Switches.Contains(TEXT("EnableSCC"));
	const bool bDisableSubmit = Switches.Contains(TEXT("DisableSCCSubmit"));

	UE_LOG(LogGatherTextCommandlet, Log,TEXT("Beginning GatherText Commandlet."));

	TSharedPtr< FGatherTextSCC > CommandletSourceControlInfo = nullptr;

	if( bEnableSourceControl )
	{
		CommandletSourceControlInfo = MakeShareable( new FGatherTextSCC() );

		FText SCCErrorStr;
		if( !CommandletSourceControlInfo->IsReady( SCCErrorStr ) )
		{
			UE_LOG( LogGatherTextCommandlet, Error, TEXT("Source Control error: %s"), *SCCErrorStr.ToString() );
			return -1;
		}
	}

	// Basic helper that can be used only to gather a new manifest for writing
	TSharedRef<FLocTextHelper> CommandletGatherManifestHelper = MakeShareable(new FLocTextHelper(MakeShareable(new FLocFileSCCNotifies(CommandletSourceControlInfo))));
	CommandletGatherManifestHelper->LoadManifest(ELocTextHelperLoadFlags::Create);

	int32 NumSteps = (ConfigFile->Find("CommonSettings") != NULL) ? ConfigFile->Num() - 1 :  ConfigFile->Num();

	//Execute each step defined in the config file.
	for( int32 i=0; i<NumSteps ; ++i )
	{
		FString SectionName = FString::Printf(TEXT("GatherTextStep%d"),i);
		FConfigSection* CurrCommandletSection = ConfigFile->Find(SectionName);
		if( NULL == CurrCommandletSection )
		{
			UE_LOG(LogGatherTextCommandlet, Error, TEXT("Could not find %s"),*SectionName);
			continue;
		}

		FString CommandletClassName = GConfig->GetStr( *SectionName, TEXT("CommandletClass"), GatherTextConfigPath ) + TEXT("Commandlet");

		UClass* CommandletClass = FindObject<UClass>(ANY_PACKAGE,*CommandletClassName,false);
		if (!CommandletClass)
		{
			UE_LOG(LogGatherTextCommandlet, Error,TEXT("The commandlet name %s in section %s is invalid."), *CommandletClassName, *SectionName);
			continue;
		}

		UGatherTextCommandletBase* Commandlet = NewObject<UGatherTextCommandletBase>(GetTransientPackage(), CommandletClass);
		check(Commandlet);
		Commandlet->AddToRoot();
		Commandlet->Initialize( CommandletGatherManifestHelper, CommandletSourceControlInfo );

		// Execute the commandlet.
		double CommandletExecutionStartTime = FPlatformTime::Seconds();

		UE_LOG(LogGatherTextCommandlet, Log,TEXT("Executing %s: %s"), *SectionName, *CommandletClassName);
		
		
		FString GeneratedCmdLine = FString::Printf(TEXT("-Config=\"%s\" -Section=%s"), *GatherTextConfigPath , *SectionName);

		// Add all the command params with the exception of config
		for(auto ParamIter = ParamVals.CreateConstIterator(); ParamIter; ++ParamIter)
		{
			const FString& Key = ParamIter.Key();
			const FString& Val = ParamIter.Value();
			if(Key != TEXT("config"))
			{
				GeneratedCmdLine += FString::Printf(TEXT(" -%s=%s"), *Key , *Val);
			}	
		}

		// Add all the command switches
		for(auto SwitchIter = Switches.CreateConstIterator(); SwitchIter; ++SwitchIter)
		{
			const FString& Switch = *SwitchIter;
			GeneratedCmdLine += FString::Printf(TEXT(" -%s"), *Switch);
		}

		if( 0 != Commandlet->Main( GeneratedCmdLine ) )
		{
			UE_LOG(LogGatherTextCommandlet, Error,TEXT("%s-%s reported an error."),*SectionName, *CommandletClassName);
			if( CommandletSourceControlInfo.IsValid() )
			{
				FText SCCErrorStr;
				if( !CommandletSourceControlInfo->CleanUp( SCCErrorStr ) )
				{
					UE_LOG(LogGatherTextCommandlet, Error, TEXT("%s"), *SCCErrorStr.ToString());
				}
			}
			return -1;
		}

		UE_LOG(LogGatherTextCommandlet, Log,TEXT("Completed %s: %s"), *SectionName, *CommandletClassName);
	}

	if( CommandletSourceControlInfo.IsValid() && !bDisableSubmit )
	{
		FText SCCErrorStr;
		if( CommandletSourceControlInfo->CheckinFiles( GetChangelistDescription(GatherTextConfigPath), SCCErrorStr ) )
		{
			UE_LOG(LogGatherTextCommandlet, Log,TEXT("Submitted Localization files."));
		}
		else
		{
			UE_LOG(LogGatherTextCommandlet, Error, TEXT("%s"), *SCCErrorStr.ToString());
			if( !CommandletSourceControlInfo->CleanUp( SCCErrorStr ) )
			{
				UE_LOG(LogGatherTextCommandlet, Error, TEXT("%s"), *SCCErrorStr.ToString());
			}
			return -1;
		}
	}

	return 0;
}
void UInternationalizationConditioningCommandlet::FLocalizationFile::CompareToCounterpart( TSharedPtr<FLocalizationFile> Other )
{
	check(Other.IsValid());

	FConfigFile* OtherFile = Other->GetFile();
	check(Other.IsValid());
	check(LocFile != NULL);

	// Iterate through all sections in the loc file
	for ( FConfigFile::TIterator SectionIt(*LocFile); SectionIt; ++SectionIt )
	{
		const FString& LocSectionName = SectionIt.Key();
		FConfigSection& MySection = SectionIt.Value();

		// Skip the [Language] and [Public] sections
		if( LocSectionName == TEXT("Language") || LocSectionName == TEXT("Public") )
		{
			continue;
		}

		// Find this section in the counterpart loc file
		FConfigSection* OtherSection = OtherFile->Find(LocSectionName);
		if ( OtherSection != NULL )
		{
			// Iterate through all keys in this section
			for ( FConfigSection::TIterator It(MySection); It; ++It )
			{
				const FName Propname = It.Key();
				const FString& PropValue = It.Value();

				FString EscapedPropValue = PropValue.ReplaceQuotesWithEscapedQuotes();

				// Find this key in the counterpart loc file
				FString* OtherValue = OtherSection->Find(Propname);
				if ( OtherValue != NULL )
				{
					FString EscapedOtherValue = *OtherValue->ReplaceQuotesWithEscapedQuotes();

					// If the counterpart has the same value as we do or is empty, the value is untranslated
					if( OtherValue->IsEmpty() )
					{
						// If the entry is empty we do nothing for the time being.
					}
					else if ( PropValue == *OtherValue )
					{
						new(IdenticalProperties) FLocalizationFileEntry( Other->GetFilename(), LocSectionName, Propname.ToString(), EscapedPropValue, EscapedPropValue );
					}
					else
					{
						new(TranslatedProperties) FLocalizationFileEntry( Other->GetFilename(), LocSectionName, Propname.ToString(), EscapedPropValue, EscapedOtherValue );
					}
				}
				else
				{
					// The counterpart didn't contain this key
					new(UnmatchedProperties) FString(LocSectionName + TEXT(".") + Propname.ToString());
				}
			}
		}
		else
		{
			// The counterpart didn't contain this section
			new(UnmatchedSections) FString(FPaths::GetBaseFilename(LocFilename) + TEXT(".") + LocSectionName);
		}
	}
}