Files
UnrealEngineUWP/Engine/Source/Programs/AutomationTool/OneSkyLocalization/OneSkyLocalizationProvider.cs
Andrew Grant f25badee7f Copying //UE4/Orion-Staging to //UE4/Main (Origin: //Orion/Dev-General @2826496)
#lockdown Nick.Penwarden

==========================
MAJOR FEATURES + CHANGES
==========================

Change 2826201 on 2016/01/13 by Zabir.Hoque

	Add more verbose logging to try to understand #OR-11297

	#lockdown Andrew.Grant
	#CodeReview Marcus.Wassmer
	#RB none
	#TESTS compiled Win64 debug editor, ran agora_p

Change 2826170 on 2016/01/13 by Marcus.Wassmer

	Flush unloaded resource properly in LoadMap
	#codereview Gil.Gribb
	#rb none
	#test cycling game.  memory is freed properly now.
	#lockdown Andrew.Grant

Change 2826135 on 2016/01/12 by Michael.Noland

	Orion: Improve login screen on PC to reduce the potential impact of framerate on data center ping calculation
	- Disabled async streaming for the duration of the QOS ping measurement to avoid hitches
	- Added a circular throbber in the top left corner of the login screen indicating that something is async streaming (as a diagnostic tool for users affected by the datacenter ping, can be removed in the future)
	- Added logging of the current average frame time when the datacenter ping is finalized
	- Added a 'Pick Ideal Settings' button to the login screen (note: on the actual screen, not the login widget, so it will not appear on PS4)
	#jira OR-12453
	#rb paul.moore
	#tests Ran a QOS server and client and verified that the new logging is occurring, tried out the new benchmark button, etc...

	Merging CL# 2826128 using //Orion/Main_to_//Orion/Dev-General

Change 2826131 on 2016/01/12 by Michael.Noland

	#UE4 - added print out of MS/FPS during Qos ping evaluation
	#rb michael.noland
	#tests loaded up through login screen to see output

	Merging CL# 2825678 using //Orion/Main_to_//Orion/Dev-General

Change 2826128 on 2016/01/12 by Michael.Noland

	Orion: Improve login screen on PC to reduce the potential impact of framerate on data center ping calculation
	- Disabled async streaming for the duration of the QOS ping measurement to avoid hitches
	- Added a circular throbber in the top left corner of the login screen indicating that something is async streaming (as a diagnostic tool for users affected by the datacenter ping, can be removed in the future)
	- Added logging of the current average frame time when the datacenter ping is finalized
	- Added a 'Pick Ideal Settings' button to the login screen (note: on the actual screen, not the login widget, so it will not appear on PS4)
	#jira OR-12453
	#rb paul.moore
	#tests Ran a QOS server and client and verified that the new logging is occurring, tried out the new benchmark button, etc...

	Merging CL# 2826116 using //Orion/Release-Next->//Orion/Main

Change 2826116 on 2016/01/12 by Michael.Noland

	Orion: Improve login screen on PC to reduce the potential impact of framerate on data center ping calculation
	- Disabled async streaming for the duration of the QOS ping measurement to avoid hitches
	- Added a circular throbber in the top left corner of the login screen indicating that something is async streaming (as a diagnostic tool for users affected by the datacenter ping, can be removed in the future)
	- Added logging of the current average frame time when the datacenter ping is finalized
	- Added a 'Pick Ideal Settings' button to the login screen (note: on the actual screen, not the login widget, so it will not appear on PS4)
	#jira OR-12453
	#rb paul.moore
	#tests Ran a QOS server and client and verified that the new logging is occurring, tried out the new benchmark button, etc...
	#lockdown andrew.grant
	#codereview josh.markiewicz

Change 2825772 on 2016/01/12 by Dmitry.Rekman

	Linux signal handling improvements.

	- Switch crash handlers to use "crash malloc" (preallocated memory) on crash.
	- Remove unnecessary memory allocations from graceful termination handler.

	#rb none
	#tests Run the Linux server and crashed it a few times.
	#codereview David.Vossel, Michael.Trepka

Change 2825768 on 2016/01/12 by Josh.Markiewicz

	#UE4 - added print out of MS/FPS during Qos ping evaluation
	#rb michael.noland
	#tests loaded up through login screen to see output

Change 2825703 on 2016/01/12 by Brian.Karis

	Switched on new motion blur. Set temporal AA sharpness to 1.

	#rb none
	#TESTS editor

Change 2825689 on 2016/01/12 by Lina.Halper

	Fix for get animation notify crash

	https://jira.ol.epicgames.net/browse/OR-12248
	https://jira.ol.epicgames.net/browse/OR-12348

	- Also fixed the crash in preview of persona due to blend sample cache contains previous animation data
	- Also fixed blend space player to reinitialize cache data
	- The main issue is marker doesn't clamp the length, causing notifies ensure to trigger.

	#rb : Laurent.Delayen
	#tests: 10 Sparrows bot match for long time
	#code review: Martin.Wilson
	#lockdown: Andrew.Grant

Change 2825680 on 2016/01/12 by Martin.Mittring

	fixed all cases with r.Tonemapper.ScreenPercentage, ScreenPercentage, Fringe, Vignette, ViewRect, flickering with transluceny (View members have been modified while other thread was reading)
	#rb:Olaf.Piesche, David.Hill
	#test: PC, many cases

Change 2825579 on 2016/01/12 by Chris.Bunner

	Force shadow shape bone indices on the required update list.
	#rb Lina.Halper, Rolando.Caloca
	#tests Editor
	#codereview Daniel.Wright
	#jira OR-12339

Change 2825443 on 2016/01/12 by Martin.Mittring
2016-01-14 08:11:47 -05:00

273 lines
9.2 KiB
C#

// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using AutomationTool;
using UnrealBuildTool;
using OneSky;
using EpicGames.Localization;
using EpicGames.OneSkyLocalization.Config;
namespace EpicGames.OneSkyLocalization
{
[Help("OneSkyConfigName", "Name of the config data to use (see OneSkyConfigHelper).")]
[Help("OneSkyProjectGroupName", "Name of the project group in OneSky.")]
public class OneSkyLocalizationProvider : LocalizationProvider
{
public OneSkyLocalizationProvider(LocalizationProviderArgs InArgs)
: base(InArgs)
{
var OneSkyConfigName = CommandUtils.ParseParamValue("OneSkyConfigName");
if (OneSkyConfigName == null)
{
throw new AutomationException("Missing required command line argument: 'OneSkyConfigName'");
}
var OneSkyProjectGroupName = CommandUtils.ParseParamValue("OneSkyProjectGroupName");
if (OneSkyProjectGroupName == null)
{
throw new AutomationException("Missing required command line argument: 'OneSkyProjectGroupName'");
}
OneSkyConfigData OneSkyConfig = OneSkyConfigHelper.Find(OneSkyConfigName);
OneSkyService = new OneSkyService(OneSkyConfig.ApiKey, OneSkyConfig.ApiSecret);
OneSkyProjectGroup = GetOneSkyProjectGroup(OneSkyProjectGroupName);
}
public static string StaticGetLocalizationProviderId()
{
return "OneSky";
}
public override string GetLocalizationProviderId()
{
return StaticGetLocalizationProviderId();
}
public override void DownloadProjectFromLocalizationProvider(string ProjectName, ProjectImportExportInfo ProjectImportInfo)
{
var OneSkyFileName = GetOneSkyFilename(ProjectImportInfo.PortableObjectName);
var OneSkyProject = GetOneSkyProject(ProjectName);
var OneSkyFile = OneSkyProject.UploadedFiles.FirstOrDefault(f => f.Filename == OneSkyFileName);
// Create changelist for backed up POs from OneSky.
int OneSkyDownloadedPOChangeList = 0;
if (CommandUtils.P4Enabled)
{
OneSkyDownloadedPOChangeList = CommandUtils.P4.CreateChange(CommandUtils.P4Env.Client, "OneSky downloaded PO backup.");
}
//Export
if (OneSkyFile != null)
{
var CulturesToExport = new List<string>();
foreach (var OneSkyCulture in OneSkyProject.EnabledCultures)
{
// Only export the OneSky cultures that we care about for this project
if (ProjectImportInfo.CulturesToGenerate.Contains(OneSkyCulture))
{
CulturesToExport.Add(OneSkyCulture);
}
}
ExportOneSkyFileToDirectory(OneSkyFile, new DirectoryInfo(CommandUtils.CombinePaths(RootWorkingDirectory, ProjectImportInfo.DestinationPath)), ProjectImportInfo.PortableObjectName, CulturesToExport, ProjectImportInfo.bUseCultureDirectory, OneSkyDownloadedPOChangeList);
}
// Submit changelist for backed up POs from OneSky.
if (CommandUtils.P4Enabled)
{
int SubmittedChangeList;
CommandUtils.P4.Submit(OneSkyDownloadedPOChangeList, out SubmittedChangeList);
}
}
private void ExportOneSkyFileToDirectory(UploadedFile OneSkyFile, DirectoryInfo DestinationDirectory, string DestinationFilename, IEnumerable<string> Cultures, bool bUseCultureDirectory, int OneSkyDownloadedPOChangeList)
{
foreach (var Culture in Cultures)
{
var CultureDirectory = (bUseCultureDirectory) ? new DirectoryInfo(Path.Combine(DestinationDirectory.FullName, Culture)) : DestinationDirectory;
if (!CultureDirectory.Exists)
{
CultureDirectory.Create();
}
using (var MemoryStream = new MemoryStream())
{
var ExportTranslationState = OneSkyFile.ExportTranslation(Culture, MemoryStream).Result;
if (ExportTranslationState == UploadedFile.ExportTranslationState.Success)
{
var ExportFile = new FileInfo(Path.Combine(CultureDirectory.FullName, DestinationFilename));
// Write out the updated PO file so that the gather commandlet will import the new data from it
{
var ExportFileWasReadOnly = false;
if (ExportFile.Exists)
{
// We're going to clobber the existing PO file, so make sure it's writable (it may be read-only if in Perforce)
ExportFileWasReadOnly = ExportFile.IsReadOnly;
ExportFile.IsReadOnly = false;
}
MemoryStream.Position = 0;
using (Stream FileStream = ExportFile.OpenWrite())
{
MemoryStream.CopyTo(FileStream);
Console.WriteLine("[SUCCESS] Exporting: '{0}' as '{1}' ({2})", OneSkyFile.Filename, ExportFile.FullName, Culture);
}
if (ExportFileWasReadOnly)
{
ExportFile.IsReadOnly = true;
}
}
// Also update the back-up copy so we can diff against what we got from OneSky, and what the gather commandlet produced
{
var ExportFileCopy = new FileInfo(Path.Combine(ExportFile.DirectoryName, String.Format("{0}_FromOneSky{1}", Path.GetFileNameWithoutExtension(ExportFile.Name), ExportFile.Extension)));
var ExportFileCopyWasReadOnly = false;
if (ExportFileCopy.Exists)
{
// We're going to clobber the existing PO file, so make sure it's writable (it may be read-only if in Perforce)
ExportFileCopyWasReadOnly = ExportFileCopy.IsReadOnly;
ExportFileCopy.IsReadOnly = false;
}
ExportFile.CopyTo(ExportFileCopy.FullName, true);
if (ExportFileCopyWasReadOnly)
{
ExportFileCopy.IsReadOnly = true;
}
// Add/check out backed up POs from OneSky.
if (CommandUtils.P4Enabled)
{
UE4Build.AddBuildProductsToChangelist(OneSkyDownloadedPOChangeList, new List<string>() { ExportFileCopy.FullName });
}
}
}
else if (ExportTranslationState == UploadedFile.ExportTranslationState.NoContent)
{
Console.WriteLine("[WARNING] Exporting: '{0}' ({1}) has no translations!", OneSkyFile.Filename, Culture);
}
else
{
Console.WriteLine("[FAILED] Exporting: '{0}' ({1})", OneSkyFile.Filename, Culture);
}
}
}
}
public override void UploadProjectToLocalizationProvider(string ProjectName, ProjectImportExportInfo ProjectExportInfo)
{
var OneSkyProject = GetOneSkyProject(ProjectName);
Func<string, FileInfo> GetPathForCulture = (string Culture) =>
{
if (ProjectExportInfo.bUseCultureDirectory)
{
return new FileInfo(Path.Combine(RootWorkingDirectory, ProjectExportInfo.DestinationPath, Culture, ProjectExportInfo.PortableObjectName));
}
else
{
return new FileInfo(Path.Combine(RootWorkingDirectory, ProjectExportInfo.DestinationPath, ProjectExportInfo.PortableObjectName));
}
};
// Upload the .po file for the native culture first
UploadFileToOneSky(OneSkyProject, GetPathForCulture(ProjectExportInfo.NativeCulture), ProjectExportInfo.NativeCulture);
if (bUploadAllCultures)
{
// Upload the remaining .po files for the other cultures
foreach (var Culture in ProjectExportInfo.CulturesToGenerate)
{
// Skip native culture as we uploaded it above
if (Culture != ProjectExportInfo.NativeCulture)
{
UploadFileToOneSky(OneSkyProject, GetPathForCulture(Culture), Culture);
}
}
}
}
private void UploadFileToOneSky(OneSky.Project OneSkyProject, FileInfo FileToUpload, string Culture)
{
using (var FileStream = FileToUpload.OpenRead())
{
// Read the BOM
var UTF8BOM = new byte[3];
FileStream.Read(UTF8BOM, 0, 3);
// We want to ignore the utf8 BOM
if (UTF8BOM[0] != 0xef || UTF8BOM[1] != 0xbb || UTF8BOM[2] != 0xbf)
{
FileStream.Position = 0;
}
var OneSkyFileName = GetOneSkyFilename(Path.GetFileName(FileToUpload.FullName));
Console.WriteLine("Uploading: '{0}' as '{1}' ({2})", FileToUpload.FullName, OneSkyFileName, Culture);
var UploadedFile = OneSkyProject.Upload(OneSkyFileName, FileStream, Culture).Result;
if (UploadedFile == null)
{
Console.WriteLine("[FAILED] Uploading: '{0}' ({1})", FileToUpload.FullName, Culture);
}
else
{
Console.WriteLine("[SUCCESS] Uploading: '{0}' ({1})", FileToUpload.FullName, Culture);
}
}
}
private ProjectGroup GetOneSkyProjectGroup(string ProjectGroupName)
{
var OneSkyProjectGroup = OneSkyService.ProjectGroups.FirstOrDefault(g => g.Name == ProjectGroupName);
if (OneSkyProjectGroup == null)
{
OneSkyProjectGroup = new ProjectGroup(ProjectGroupName, "en");
OneSkyService.ProjectGroups.Add(OneSkyProjectGroup);
}
return OneSkyProjectGroup;
}
private OneSky.Project GetOneSkyProject(string ProjectName, string ProjectDescription = "")
{
OneSky.Project OneSkyProject = OneSkyProjectGroup.Projects.FirstOrDefault(p => p.Name == ProjectName);
if (OneSkyProject == null)
{
ProjectType projectType = OneSkyService.ProjectTypes.First(pt => pt.Code == "website");
OneSkyProject = new OneSky.Project(ProjectName, ProjectDescription, projectType);
OneSkyProjectGroup.Projects.Add(OneSkyProject);
}
return OneSkyProject;
}
private string GetOneSkyFilename(string BaseFilename)
{
var OneSkyFileName = BaseFilename;
if (!String.IsNullOrEmpty(LocalizationBranchName))
{
// Apply the branch suffix. OneSky will take care of merging the files from different branches together.
var OneSkyFileNameWithSuffix = Path.GetFileNameWithoutExtension(OneSkyFileName) + "_" + LocalizationBranchName + Path.GetExtension(OneSkyFileName);
OneSkyFileName = OneSkyFileNameWithSuffix;
}
return OneSkyFileName;
}
private OneSkyService OneSkyService;
private ProjectGroup OneSkyProjectGroup;
}
}